打开主菜单

谷雨文档中心 β

更改

NBDK-L4:基础实验教程

添加4,021字节2019年2月21日 (四) 11:55
gyu_spi.c
{
KEY_Poll(); // 按键轮训,监测是否有按键被按下
}
}
</syntaxhighlight>从按键回调函数中我们可以看到,UP(S1)及LEFT(S4)按键分别用于向W25Q80的地址0x000000以及0x001000写入一些字符'A'和'B'。而DOWN(S3)和RIGHT(S2)按键则负责从以上两个写入数据的地址读取数据。
 
注意W25Q80的写入数据流程:一定是先擦除,后写入。
 
读取流程:直接读取。<syntaxhighlight lang="c++" line="1" start="80">
void AppKey_cb(uint8_t key)
{
// 如果有相应按键被按下,则串口打印调试信息
if(key & KEY_UP)
{
// 擦除页面地址000000
HwFlashErase(0x000000);
for(int i=0;i<W25Q80_PROGRAM_PAGE_SIZE;i++)
{
txbuf[i]= 0x41;
}
// 向页面地址000000写入数据
HwFlashWrite(0x000000, txbuf, W25Q80_PROGRAM_PAGE_SIZE);
}
if(key & KEY_DOWN)
{
// 读取页面地址000000数据,将获取到的数据打印到串口
HwFlashRead(0x000000, rxbuf, W25Q80_PROGRAM_PAGE_SIZE);
printf("%s",rxbuf);
}
if(key & KEY_LEFT)
{
// 擦除页面地址001000
HwFlashErase(0x001000);
for(int i=0;i<W25Q80_PROGRAM_PAGE_SIZE;i++)
{
txbuf[i]= 0x42;
}
// 向页面地址001000写入数据
HwFlashWrite(0x001000, txbuf, W25Q80_PROGRAM_PAGE_SIZE);
}
if(key & KEY_RIGHT)
{
// 读取页面地址001000数据,将获取到的数据打印到串口
HwFlashRead(0x001000, rxbuf, W25Q80_PROGRAM_PAGE_SIZE);
printf("%s",rxbuf);
}
}
</syntaxhighlight>
 
==== gyu_util.c ====
请参照实验01中的介绍。
基础实验中的其他例程,大部分都是使用的相同的时钟配置函数,有特殊的时钟使用,将会在对应例程的源码详解中做针对性说明。
==== gyu_spi.c ====
下面4个函数,用于初始化SPI1接口,包含它的MOSI、MISO、CLK,以及单独的控制flash芯片的CSN引脚配置。
这边我们需要注意的是,配置了SPI1为主模式,数据位8bit,支持双向通信(收发都支持)。<syntaxhighlight lang="c++" line="1" start="35">
void MX_SPI1_Init(void)
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, pinSate); // 设置PA15输出
}
</syntaxhighlight>剩下的4个函数是留给用户去调用的SPI初始化、SPI读写、以及判断SPI是否繁忙的函数。 在这个例程中,除了Spi_Init()函数需要在main函数中调用初始化SPI接口,其他3个函数均使用于gyu_flash_ex.c中,用于flash芯片W25Q80的控制。<syntaxhighlight lang="c++" line="1" start="139">
void Spi_Init(void)
{
// 初始化SPI1接口
MX_SPI1_Init();
}
</syntaxhighlight><syntaxhighlight lang="c++" line="1" start="156">
int Spi_write(const uint8_t *buf, size_t len)
{
return HAL_SPI_Transmit(&hspi1,(uint8_t*)buf,len,HAL_MAX_DELAY) ? -1 : 0;
}
</syntaxhighlight><syntaxhighlight lang="c++" line="1" start="170">
int Spi_read(uint8_t *buf, size_t len)
{
return HAL_SPI_Receive(&hspi1,(uint8_t*)buf,len,HAL_MAX_DELAY) ? -1 : 0;
}
</syntaxhighlight><syntaxhighlight lang="c++" line="1" start="183">
void Spi_flash(void)
{
// 确保SPI硬件模块完成(也就是返回状态不为busy)
while(HAL_SPI_GetState(&hspi1) == HAL_SPI_STATE_BUSY)
{ };
}
</syntaxhighlight>
 
==== gyu_flash.c ====
此文件中的函数仅有3个,分别为flash擦除,flash写入,flash读取。
 
结合我们main.c中的按键回调函数,就可以清楚的知道,这个文件中的函数是留给开发者去读写W25Q80的。
 
W25Q80擦除指定page的函数,注意写入数据前,一定要先擦除数据。<syntaxhighlight lang="c++" line="1" start="36">
void HwFlashErase(uint32_t page)
{
// 判断W25Q80是否正常
if (W25Q80_Flash_open())
{
W25Q80_Flash_erase(page, HAL_FLASH_PAGE_SIZE); // 擦除数据
}
}
</syntaxhighlight>W25Q80向指定page写入数据的函数。<syntaxhighlight lang="c++" line="1" start="53">
void HwFlashWrite(uint32_t page, uint8_t *pBuf, uint16_t len)
{
// 判断W25Q80是否正常
if (W25Q80_Flash_open())
{
W25Q80_Flash_write(page, len, pBuf); // 写入数据
}
}
</syntaxhighlight>W25Q80从指定page读取数据的函数。<syntaxhighlight lang="c++" line="1" start="72">
void HwFlashRead(uint32_t page, uint8_t *pBuf, uint16_t len)
{
// 判断W25Q80是否正常
if (W25Q80_Flash_open())
{
W25Q80_Flash_read(page, len, pBuf); // 读取数据
}
}
</syntaxhighlight>
 
==== gyu_flash_ex.c ====
这个文件,是我们这个例程中的重中之重,所以我们将它放在最后来说明。这个文件阅读之前,请大家一定对于W25W80的寄存器有一定了解,不然理解上会出现空缺。
 
[[分类:NB-IOT]]
[[分类:NBDK-L4]]
[[分类:教程]]
__强显目录__
510
个编辑