STM8L151 使用硬件SPI驱动W25Q16 Flash

SPI:有四根线的串行通信协议,允许与其他设备以半、全双工、同步、串行方式通信。

MISO:主模式输入、从模式输出线

MOSI:主模式输出、从模式输入线

CLK:时钟线

NSS:从设备选择引脚,主设备标准IO驱动,并用来区分从设备

以STM8L 驱动SPI Flash W25Q16 为例说明记录下,使用STM8L 的SPI该注意哪些地方,以及如何简单驱动W25Q16。

华邦的W25Q16 SPI Flash芯片是采用SPI接口,至于该芯片的优缺点就不说了,STM8L上有一个硬件SPI,可以很方便的来驱动W25Q16,下面就来看看该如何配置STM8L的SPI 外设。

void SPI_FLASH_Init(void)
{
	//SPI_CLOCK:PB5, SPI_MOSI: PB6, SPI_MISO: PB7
	GPIO_Init(GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast);
	GPIO_Init(GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast);
	//主机模式,配置为输入 该设置很关键
	GPIO_Init(GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT);
  	/* 初始化SPI */
	SPI_Init(SPI1, SPI_FirstBit_MSB, SPI_BaudRatePrescaler_4, SPI_Mode_Master,		 SPI_CPOL_High, SPI_CPHA_2Edge, 		SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);

	SPI_Cmd(SPI1, ENABLE);	/* 使能SPI */

	/* 配置CS管脚 */
	GPIO_Init(SPI_CS , SPI_Pin_CS, GPIO_Mode_Out_PP_High_Fast);
	GPIO_WriteBit(SPI_CS, SPI_Pin_CS, SET);		/* 拉高不使能外部SPI设备 */
}

在上面中要注意SPI 使用到的管脚PB5, PB6, PB7 的设置,在SPI主机模式中,PB5、PB6根据外围电路可以设置为外部上拉输出,也可设置为上面的内部上拉输出,而PB7则要设置为内部上拉输入或浮空输入(外加上拉电阻),这些设置完还要开启SPI外设的时钟。

下面是读取Flash 厂商ID和设备ID的函数,

uint8_t SPI_FLASH_SendByte(u8 byte)
{
  /* Loop while DR register in not emplty */
  while (SPI_GetFlagStatus(SPI1, SPI_FLAG_TXE) == RESET);
  /* Send byte through the SPI1 peripheral */
  SPI_SendData(SPI1, byte);
  /* Wait to receive a byte */
  while (SPI_GetFlagStatus(SPI1, SPI_FLAG_RXNE) == RESET);
  /* Return the byte read from the SPI bus */
  return SPI_ReceiveData(SPI1);
 }
uint16_t SPI_FLASH_ReadID(void)
{
	u16 Device_ID = 0;
	/* Select the FLASH: Chip Select low */
	SPI_FLASH_CS_LOW(); //拉低片选管脚电平,选中外设
	/* Send "RDID " instruction */
	SPI_FLASH_SendByte(0x90); //读取设备ID指令
	SPI_FLASH_SendByte(0X00);
	SPI_FLASH_SendByte(0X00);
	SPI_FLASH_SendByte(0X00);
	/* Read a byte from the FLASH */
	Device_ID = (SPI_FLASH_SendByte(Dummy_Byte)<<8);
	Device_ID |= SPI_FLASH_SendByte(Dummy_Byte);
	SPI_FLASH_CS_HIGH();//拉高片选管脚电平,
	return Device_ID;
}

在W25Q16的手册中,

函数读回来的数据应该是上面的值,再看看手册上的ID读取指令0x90

获取设备ID的指令发送顺序如上图,第一字节先发0x90,然后发两个dummy Byte(任何数值都可)和0x00,之后再读取厂商ID和设备ID,上面的函数基本实现的就是这个时序。

实测的测试结果如下,

结果与手册给的ID一致。

时间: 2024-11-03 21:50:30

STM8L151 使用硬件SPI驱动W25Q16 Flash的相关文章

linux enc28j60网卡驱动移植(硬件spi和模拟spi)

本来想移植DM9000网卡的驱动,无奈硬件出了点问题,通过杜邦线链接开发板和DM9000网卡模块,系统上电,还没加载网卡驱动就直接崩溃了,找不到原因...刚好手上有一个enc28j60的网卡模块,于是就着手移植enc28j60的驱动. 其实移植enc28j60的驱动也十分简单,网上有现成的,只需要分配一些硬件资源即可. 由于我的内核版本老到掉牙,没有自带enc28j60的驱动,只能在网上找一个: enc28j60.c http://git.ti.com/ti-linux-kernel/ti-li

Linux SPI驱动设计

1. SPI总线结构 SPI串行外设接口,是一种高速的,全双工,同步的通信总线.采用主从模式架构,支持多个slave,一般仅支持单Master SPI接口共有4根信号线,分别是: 设备选择线(SS).时钟线(SCK).串行输出数据线(MOSI).串行输入数据线(MISO). 2. 数据传输过程 主节点通过MOSI线输出数据,从节点在SIMO处从主节点读取数据.同时,也通过SMOI输出MSB(最高位), 主节点会在MISO处读取从节点的数据,整个过程将一直持续,直至交换完所有的数据. 3. 总线时

spi驱动框架全面分析,从master驱动到设备驱动

内核版本:linux2.6.32.2 硬件资源:s3c2440 参考:  韦东山SPI视频教程 内容概括: 1.I2C 驱动框架回顾 2.SPI 框架简单介绍 3.master 驱动框架 3.1 驱动侧 3.2 设备侧 4.SPI 设备驱动框架 4.1 设备册 4.2 驱动侧 5.设备驱动程序实例 1.I2C 驱动框架回顾 在前面学习 I2C 驱动程序的时候我们知道,I2C 驱动框架分为两层,一层是控制器驱动程序 i2c_adapter,它一般是由芯片厂商写好的,主要提供一个 algorithm

Linux下spi驱动开发

转载至:http://www.embedu.org/Column/Column367.htm 作者:刘洪涛,华清远见嵌入式学院讲师. 一.概述 基于子系统去开发驱动程序已经是linux内核中普遍的做法了.前面写过基于I2C子系 统的驱动开发.本文介绍另外一种常用总线SPI的开发方法.SPI子系统的开发和I2C有很多的相似性,大家可以对比学习.本主题分为两个部分叙述,第一 部分介绍基于SPI子系统开发的理论框架:第二部分以华清远见教学平台FS_S5PC100上的M25P10芯片为例(内核版本2.6

4、CC2541芯片中级教程-OSAL操作系统(简单AT指令实现+IIC软件和硬件实现驱动MPU6050)

本文根据一周CC2541笔记汇总得来—— 适合概览和知识快速索引—— 全部链接: 中级教程-OSAL操作系统\OSAL操作系统-实验01 OSAL初探 [插入]SourceInsight-工程建立方法 中级教程-OSAL操作系统(OSAL系统解基本套路) 中级教程-OSAL操作系统(进一步了解-OLED && 普通按键和5方向按键-中断!!!)这个系统驱动层和应用层不一样~ 中级教程-OSAL操作系统(ADC-光敏电阻) OSAL操作系统-实验16 串口波特率扩展 OSAL操作系统-实验1

MSM8909+Android5.1.1 SPI驱动开发(PSAM部分)

MSM8909+Android5.1.1SPI驱动开发(PSAM部分) 1.     PSAM部分的硬件设计 图1 CS   片选信号 SCK  时钟信号 MISO 主设备的数据输入.从设备的数据输出脚 MOSI 主设备的数据输出.从设备的数据输入脚 2.     PSAM部分软件设计 图2 (1)  PSAM应用 这部分只需要调用API函数即可. (2)  PSAM API API的主要工作就是给M0上电.设置SPI读写模式.设置SPI读写的每字节的位数.SPI的工作频率等. (3)  SPI

MSP430G2553 Launchpad 硬件I2C驱动

一.USCI I2C 驱动介绍 对于MSP430G2553,硬件I2C由外设USCI(Universal Serial Communication Interface)提供.USCI又分为USCI_A和USCI_B,其中USCI_A支持UART/IrDA/LIN/SPI通讯,USCI_B支持I2C/SPI通讯.MSP430G2553带有一个USCI_A和一个USCI_B,硬件I2C对应的管脚为P1.6(UCB0SCL)和P1.7(UCB0SDA). 由于Launchpad上P1.6连接到了LED

SPI驱动编写要点

题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这个框架搭建好了,作为驱动开发者的我们只需要搞清楚哪一部分是需要自己修改或重新编写就OK了. 结合Linux内核面向对象的设计思想,SPI总的设计思路大概是这样的: 第①处:内核中抽象了SPI控制器,让spi_master成为他的象征,他的实例化对象就是与硬生生的SPI控制器对应的,在Linux内核中

Linux设备驱动探究第1天----spi驱动(1)

本文允许转载,请注明出处:http://blog.csdn.net/fulinus Linux内核代码实在太大了,一个小小的模块也会让你手足无措,今天下午决心要把spi驱动好好看看. 首先分析spidev.c文件,这个文件中定义struct file_operations结构中的成员.成员有spidev_write.spidev_read和spidev_ioctl,前两者实现半双工通信,后者实现全双工通信.当然还有open和release等相关的成员,先忽略吧. spidev_write ---