其它文章链接,独家吐血整理
(实验3)单片机,STM32F4学习笔记,代码讲解【按键输入实验】【正点原子】【原创】
(实验4)单片机,STM32F4学习笔记,代码讲解【串口实验】【正点原子】【原创】
(实验5)单片机,STM32F4学习笔记,代码讲解【外部中断实验】【正点原子】【原创】
(实验6,实验7)单片机,STM32F4学习笔记,代码讲解【看门狗实验】【正点原子】【原创】
(实验8)单片机,STM32F4学习笔记,代码讲解【定时器实验】【正点原子】【原创】
(实验9)单片机,STM32F4学习笔记,代码讲解【PWM输出实验】【正点原子】【原创】
(实验10)单片机,STM32F4学习笔记,代码讲解【输入捕获实验】【正点原子】【原创】
(实验11)单片机,STM32F4学习笔记,代码讲解【电容触摸按键实验】【正点原子】【原创】
(实验12)单片机,STM32F4学习笔记,代码讲解【OLED显示实验】【正点原子】【原创】
(实验13)单片机,STM32F4学习笔记,代码讲解【TFTLCD彩屏显示实验】【正点原子】【原创】
(实验15)单片机,STM32F4学习笔记,代码讲解【RTC实时时钟实验】【正点原子】【原创】
(实验17)单片机,STM32F4学习笔记,代码讲解【待机唤醒实验】【正点原子】【原创】
(实验23)单片机,STM32F4学习笔记,代码讲解【DMA实验】【正点原子】【原创】
(实验25)单片机,STM32F4学习笔记,代码讲解【SPI实验】【正点原子】【原创】
(实验34)单片机,STM32F4学习笔记,代码讲解【FLASH模拟EEPROM实验】【正点原子】【原创】
(实验36)单片机,STM32F4学习笔记,代码讲解【外部SRAM实验】【正点原子】【原创】
(实验37)单片机,STM32F4学习笔记,代码讲解【内存管理实验】【正点原子】【原创】
(实验38)单片机,STM32F4学习笔记,代码讲解【SD卡实验】【正点原子】【原创】
(实验39)单片机,STM32F4学习笔记,代码讲解【FATFS实验】【正点原子】【原创】
(实验46)单片机,STM32F4学习笔记,代码讲解【FPU测试实验】【正点原子】【原创】
(实验47)单片机,STM32F4学习笔记,代码讲解【DSP-FFT测试实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验】【正点原子】【原创】
(实验50)单片机,STM32F4学习笔记,代码讲解【串口IAP实验-RTC时钟实验】【正点原子】【原创】
(实验55)单片机,STM32F4学习笔记,代码讲解【网络通信实验】【正点原子】【原创】
实验现象
本实验通过KEY1按键来控制W25Q128的写入,通过另外一个按键KEY0来控制W25Q128的读取。并在LCD模块上面显示相关信息。DS0提示程序正在运行。同时,我们可以通过USMART控制读取W25QXX的ID或者整片擦除。
SPI驱动程序
略
主程序
int main(void)
{
u8 key;
u16 i=0;
u8 datatemp[SIZE];
u32 FLASH_SIZE;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LED_Init(); //初始化LED
LCD_Init(); //LCD初始化
KEY_Init(); //按键初始化
W25QXX_Init(); //W25QXX初始化
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
LCD_ShowString(30,70,200,16,16,"SPI TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2014/5/6");
LCD_ShowString(30,130,200,16,16,"KEY1:Write KEY0:Read"); //显示提示信息
while(W25QXX_ReadID()!=W25Q128) //检测不到W25Q128
{
LCD_ShowString(30,150,200,16,16,"W25Q128 Check Failed!");
delay_ms(500);
LCD_ShowString(30,150,200,16,16,"Please Check! ");
delay_ms(500);
LED0=!LED0; //DS0闪烁
}
LCD_ShowString(30,150,200,16,16,"W25Q128 Ready!");
FLASH_SIZE=16*1024*1024; //FLASH 大小为16字节
POINT_COLOR=BLUE; //设置字体为蓝色
while(1)
{
key=KEY_Scan(0);
if(key==KEY1_PRES)//KEY1按下,写入W25Q128
{
LCD_Fill(0,170,239,319,WHITE);//清除半屏
LCD_ShowString(30,170,200,16,16,"Start Write W25Q128....");
W25QXX_Write((u8*)TEXT_Buffer,FLASH_SIZE-100,SIZE); //从倒数第100个地址处开始,写入SIZE长度的数据
LCD_ShowString(30,170,200,16,16,"W25Q128 Write Finished!"); //提示传送完成
}
if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
{
LCD_ShowString(30,170,200,16,16,"Start Read W25Q128.... ");
W25QXX_Read(datatemp,FLASH_SIZE-100,SIZE); //从倒数第100个地址处开始,读出SIZE个字节
LCD_ShowString(30,170,200,16,16,"The Data Readed Is: "); //提示传送完成
LCD_ShowString(30,190,200,16,16,datatemp); //显示读到的字符串
}
i++;
delay_ms(10);
if(i==20)
{
LED0=!LED0;//提示系统正在运行
i=0;
}
}
}
代码讲解
//SPI=串行外围设备接口,高速,全双工,同步的通信总线
//MISO,MOSI,SCLK(主设备产生),CS(主设备控制)
//主机和从机都各自有一个串行移位寄存器,通过MISO,MOSI信号线来控制进行交换数据
//SPI=可以同时发出和接收串行数据,如果只进行写操作,主机只需要忽略接收到的字节
//如果主机要读取从机的一个字节,那么必须发送一个空字节来引发从机的传输
总共有五个外设时钟函数,AHB123,APB12,五根时钟线
SPI=serial peripheral interface=串行外围设备接口,是一种高速,全双工,同步的通信总线
在芯片引脚上只占有四根线,分别是MISO MOSI SCLK CS,SPI总线有四种工作方式=2 * 2
就是说,时钟信号极性2种,时钟信号相位2种,组合就是四种
时钟极性为0就是空闲时信号线为低电平(也就说不工作时是低电平),为1则相反
时钟相位为0就是在串行同步时钟的第一个跳变沿(上升或者下降需要设置)数据被采样
为1则是第二个跳变沿(私以为这样会防止误判),主机与外设之间通信是同步进行的
如果只进行写操作,那么主机忽略从机发送过来的字节即可,MSB=数据高位在前
LSB=数据低位在前,我们选择MSB,另外SPI1也有SPI2,前者挂在SPB1时钟线
后者挂在SPB2时钟线,速度最高达到37.5Mhz
W25Q128=FLASH,前面也说过,是以块进行删除的,是128Mb=16M字节,1B=8b=字节,1KB=1Kb
=1024B,1MB=1Mb=1024Kb=1024KB,1GB=1024MB,1TB=1024GB
总之,我们俗称的1T就是1TB也就是1Tb,1G就是1Gb,所以128Mb=16M*8,因为FLASH以扇区为单位删除
W25Q128就是分为256个块,每块又分为16个扇区,每个扇区4K个字节,因此每次擦除4K个字节
//256164K=128Mb=12810241024字节,4K=41024字节,所以2561641024=16M字节
//一共4096个扇区,一个扇区4K字节=4096个8位变量