一、前言
现在需要将ADC采集到的数据储存至SD卡中,ADC采用AD7764,处理器采用STM32F103ZET6。下面对设计过程进行记录。
1.1 AD7764介绍
- 312K输出,109db信噪比。
- 输出速率由外部时钟控制
- DMA数据传输
1.2 SD卡储存方式介绍
- SDIO协议
- DMA数据传输
- FatFs文件系统(传输速率最高1M)
1.3 控制方式
- 开始采集按钮
- 关闭采集按钮
- 屏幕刷新按钮(后期实现)
二、方案介绍
2.1 方案一
- AD7764采集数据存储到SRAM中,触发中断
- 中断程序调用SD卡储存程序
注:这种方法比较容易实现,但是可能会引起数据保存速率的降低,先用这种方法作为测试。
2.2 方案二
- 开辟1024字节的储存空间BUFF。
- AD7764采集到的数据储存到这个BUFF中,储存一半后触发中断。
- 在中断程序中调用存储程序,储存一半结束,等待下一次中断
2.3 控制方案
功能比较简单,三个按钮对应三个功能,用传统方式就好。注:复杂的控制推荐使用状态机的方式。
三、实现步骤
3.1 SD卡相关
3.1.1 SDIO+DMA基础驱动
采用官方的驱动,驱动下载链接附上:sdio_sdcard.c 和 sdio_sdcard.h。如果引脚对应上了,就不需要进行修改。如果没有对应上,需要修改引脚,中断,DMA设置。我运气好,对应上了[滑稽]。
测试方法可以使用SD_ReadBlock,和SD_WriteBlock两个函数进行测试,注:每次读可以的大小为:1~512,写的最小单位是512字节,对应不上则会出错。因为这个原因,我选择了死亡Fatfs文件系统。
3.1.2 Fatfs移植
由于文件比较多,可以去官网下载,在上一小节移植成功了后,只需要修改ff.c这一个文件,修改两个地方如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28DRESULT disk_read (
BYTE drv, /* Physical drive nmuber (0..) */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to read (1..255) */
)
{
if(count==1)
{
SD_ReadBlock((u32 *)(&buff[0]),sector << 9 ,SECTOR_SIZE);
}
return RES_OK;
}
DRESULT disk_write (
BYTE drv, /* Physical drive nmuber (0..) */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Sector address (LBA) */
BYTE count /* Number of sectors to write (1..255) */
)
{
if(count==1)
{
SD_WriteBlock((u32 *)(&buff[0]),sector << 9 ,SECTOR_SIZE);
}
return RES_OK;
}
移植成功后,先进行测试。测试代码如下(要是代码可折叠显示就好了):
1 | SD_Check(); //挂载SD卡,测试是否成功 |
至此,SD卡驱动已经全部移植成功。
3.2 AD7764电压采集
目标实现功能如下:
3.2.1 SPI配置相关
3.2.2 DMA配置相关
3.3.3 中断配置相关
3.3.4 双缓存结构
为了实现一边采集数据,一边储存至SD卡中,采用双缓存结构实现,可参考文章
3.2.5 读取控制程序相关
3.2.6 SPI从机模拟
由于手上没有AD7764的板子,需要用STM32模拟一个,可参考文章。
3.3 控制功能实现
按键实现以下功能:
- 按下按键后有效,只会生效一次,再次有效需要松开再按
- 支持多个按键同时按下
- 不阻塞
- 软件消抖
- 每个按键对应一个功能
实现代码如下:
1 | u8 Get_key() |
担心有小伙伴不能理解KEY_Scan()的实现方式,他这个函数和硬件相关,不同硬件编写有些不一样,下面也附上代码作为参考:
1 | u8 KEY_Scan() |
3.4 显示功能实现
功能暂时用不上保留,后期有需求在补上
四、测试
4.1 ADC测试
4.2 SD卡测试
4.3 储存速度测试
五、总结
虽然还没有做完,但是牛批!!!