查看mm32f0140的miniboard原理图,spi挂载了w25q80。
一、spi介绍
串行外设接口,serial peripheral interface。一种高速的、全双工、同步的串行通信总线。主要应用于eeprom、flash、ad转换器,还有数字信号处理器和数字信号解码器之间。
spi 支持同时发送和接收数据,采用主从工作方式。spi 通过 4 个引脚与外部器件相连,分别是:
mosi:主设备输出、从设备输入引脚。传输方向为主设备发送到从设备。
miso:主设备输入、从设备输出引脚。传输方向为从设备发送到主设备。
sck:串行时钟信号,由主设备产生并提供给从设备。
nss:片选信号,从设备选择。
下图示意主、从设备之间一对一通信时的连接情况:
主设备负责发起通信请求,从设备负责响应,从设备通过 sck 引脚得到主设备提供的时钟信号,从而使得主、从设备均使用同一个时钟进行同步的全双工通信。对于从设备而言,mosi 引脚输入来自主设备的发送数据,miso 引脚输出响应数据传给主设备。
spi 需要根据从机特性,选配时钟极性(cpol)和时钟相位(cpha),比如从机时钟空闲时为低电平,且在时钟信号的第一个跳变沿采样,此时时序见下图:
二、w25q80介绍
w25q80是一种串行闪存存储器,主要特点包括:
容量:8 mbit(1 mb)的存储容量,可以存储大量数据。
spi接口:采用spi接口进行数据通信,具备高速的数据传输能力。
快速读取:支持快速的连续读取操作,可提供高效的读取性能。
块擦除:支持块擦除功能,可以批量擦除数据,提高擦除效率。
低功耗:采用低功耗设计,适用于对功耗要求较高的应用场景。
w25q80可以划分为 4096 个扇区,每个扇区包含 256 个页,每个页的大小为 256 字节。
下图为w25q80的指令:
三、例程
1.介绍
本例程实现spi与w25q80通信,spi查询w25q80的设备号,并全片擦除后写入数据,再读取出来,看写入的数据与读取的数据是否一致。
2.编码详情
1)初始化配置spi,速度为pclk1(36mhz)的32分频,约为1.125mhz;
spi_initstructure.spi_mode = spi_mode_master;
spi_initstructure.spi_datasize = spi_datasize_8b; spi_initstructure.spi_datawidth = 8; spi_initstructure.spi_cpol = spi_cpol_low; spi_initstructure.spi_cpha = spi_cpha_1edge; spi_initstructure.spi_nss = spi_nss_soft; spi_initstructure.spi_baudrateprescaler = spi_baudrateprescaler_32; spi_initstructure.spi_firstbit = spi_firstbit_msb; spi_init(spi2, &spi_initstructure); exspi_dataedgeadjust(spi2, spi_dataedgeadjust_fast); spi_bidirectionallineconfig(spi2, spi_direction_tx); spi_bidirectionallineconfig(spi2, spi_direction_rx); spi_cmd(spi2, enable); 2)编写spi发送和读取数据的函数
uint32_t writeandreaddata(uint8_t data){ spi_senddata(spi2, data); while (1) { if(spi_getflagstatus(spi2, spi_flag_txept)) { break; } } while (1) { if(spi_getflagstatus(spi2, spi_flag_rxavl)) { return spi_receivedata(spi2); } }} 3)获取w25q80的设备id
spi_csinternalselected(spi2, enable); // 片选 writeandreaddata(0x9f); // 读id指令 id |= writeandreaddata(0x00) << 16; id |= writeandreaddata(0x00) << 8; id |= writeandreaddata(0x00); spi_csinternalselected(spi2, disable); // 取消片选 printf(read device id: %x, id); 4)全片擦除w25q80,并检查状态等待擦除完成
spi_csinternalselected(spi2, enable); writeandreaddata(0x06); // 写使能 spi_csinternalselected(spi2, disable); spi_csinternalselected(spi2, enable); writeandreaddata(0xc7); // 全片擦除指令 spi_csinternalselected(spi2, disable); spi_csinternalselected(spi2, enable); writeandreaddata(0x05); // 读状态寄存器 while(1) { temp = writeandreaddata(0x00); if((temp & 0x01) == 0x0) // 擦除完成 break; } spi_csinternalselected(spi2, disable); printf(erase complete); 5)写数据,并检查状态等待写完
for (i = 0; i < 256; i++) txdata[i] = i; spi_csinternalselected(spi2, enable); writeandreaddata(0x06);// 写使能 spi_csinternalselected(spi2, disable); spi_csinternalselected(spi2, enable); writeandreaddata(0x02); // 页编程 writeandreaddata(0x00); // 页地址 writeandreaddata(0x00); writeandreaddata(0x00); for (i = 0; i < 256; i++) { writeandreaddata(txdata[i]); } spi_csinternalselected(spi2, disable); spi_csinternalselected(spi2, enable); writeandreaddata(0x05); // 读状态寄存器 while(1) { temp = writeandreaddata(0x00); if((temp & 0x01) == 0x0) // 页编程完成 break; } spi_csinternalselected(spi2, disable); printf(page programm complete); 6)读数据,并打印出来
spi_csinternalselected(spi2, enable); writeandreaddata(0x03); // 读数据 writeandreaddata(0x00); // 页地址 writeandreaddata(0x00); writeandreaddata(0x00); for (i = 0; i < 10; i++) { rxdata[i] = writeandreaddata(0x00); } spi_csinternalselected(spi2, disable); printf(read data completely); for (i = 0; i < 10; i++) printf(rxdate[%d] = %d, i, rxdata[i]); 3.串口输出结果
下图为串口输出数据,基本符合程序流程和结果。
4.逻辑分析仪
下图为逻辑分析仪截取的发送接收图片,可以清楚的看到当前sck速度接近1.125mhz,以及发送数据也符合预期。
宜家发布“Rognan”系列可变形家具产品
【安防】激光对射功能及案例解析
将生物医学传感器固定在适当位置,使用医用安全胶带减少错误
AMD营收加速增长 创7年来单季最高水平
病害肉快速分析仪是什么,有什么作用?
基于MM32F0140的SPI与W25Q80通信的实现方案
如何实现一个验证MCU指令
智能电表,让生活更智能
以单片机为控制中心的智能微波信号源发生器设计
基于人工智能技术的地震监测系统将是未来预报地震的发展新方向
燃气流量计检定的现状
墨奇科技新一代“指纹-身份识别”AI系统
解析质检仪的光电读出原理
阿里云通过城市大脑人工智能信号灯对城区的堵点进行信号优化
蚂蚁电竞ANT27VU显示器:4K分辨率+144Hz屏幕刷新率
线性驱动系统研发生产企业凯迪股份发布2022第一季度报告
微软取消2020年发布的双屏幕Windows 10X设备
工控机维修_工控机的usb口用不了
华为、中兴全球范围内推进5G预商用
关于电源产品投标时标书文件的撰写方法