杂
序
这篇文章向大家介绍下基于STM32F4的adc采集与SD卡储存
实验室
学长的要求是利用STM32采集Adc值转存于SD中 后利用Matlab进行快速傅里叶变化分析频率(FFT天下第一 )
简介
ST(意法半导体)推出了以基于ARM® Cortex™-M4为内核的STM32F4系列高性能微控制器,其采用了90 纳米的NVM 工艺和ART(据说以后可以操作学长的28nm工具FPGA )。
/这里用的是某点原子
调用的资源:Adc
模拟数字转换器即A/D转换器,简称ADC,通常是指一个将模拟信号转变为数字信号的电子元件。
调用的外设:SD卡
SD卡相对于u盘、flash来说是比较适合于单片机系统的大容量存储设备,容量选择尺度大(几十M 到几十G) 、更换简单、移动方便,是单片机大容量外部存储器的首选。
实现过程
Adc
ADC 的通道与引脚的对应关系在 STM32F4 的数据手册可以查到,这里使用 ADC1 的通道 5
首先初始化IO 设置为模拟输入
__HAL_RCC_ADC1_CLK_ENABLE(); //使能 ADC1 时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启 GPIOA 时钟
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //
初始化ADC 设置ADC分频系数、分辨率、模式、扫描方式、对齐方式等信息
在 HAL 库中,初始化 ADC 是通过函数 HAL_ADC_Init 来实现的,该函数声明为:
HAL_StatusTypeDef HAL_ADC_Init(ADC_HandleTypeDef* hadc);
入口参数hadc 为 ADC_HandleTypeDef 结构体指针类型,结构体定义为:
//结构体 ADC_HandleTypeDef
typedef struct
{
ADC_TypeDef *Instance; //ADC1/ ADC2/ ADC3
ADC_InitTypeDef Init; //初始化结构体变量
__IO uint32_t NbrOfCurrentConversionRank; //当前转换序列
DMA_HandleTypeDef *DMA_Handle; //DMA 方式使用
HAL_LockTypeDef Lock;
__IO HAL_ADC_StateTypeDef State;
__IO uint32_t ErrorCode;
}ADC_HandleTypeDef;
//结构体 ADC_InitTypeDef
typedef struct
{
uint32_t ClockPrescaler; //分频系数 2/4/6/8 分频 ADC_CLOCK_SYNC_PCLK_DIV4
uint32_t Resolution; //分辨率 12/10/8/6 位:ADC_RESOLUTION_12B
uint32_t DataAlign; //对齐方式:左对齐还是右对齐:ADC_DATAALIGN_RIGHT
uint32_t ScanConvMode; //扫描模式 DISABLE
uint32_t EOCSelection; //EOC 标志是否设置 DISABLE
uint32_t ContinuousConvMode; //开启连续转换模式或者单次转换模式 DISABLE
uint32_t DMAContinuousRequests;//开启 DMA 请求连续模式或者单独模式 DISABLE
uint32_t NbrOfConversion; //规则序列中有多少个转换 1
uint32_t DiscontinuousConvMode;//不连续采样模式 DISABLE
uint32_t NbrOfDiscConversion; //不连续采样通道数 0
uint32_t ExternalTrigConv; //外部触发方式 ADC_SOFTWARE_START
uint32_t ExternalTrigConvEdge; //外部触发边沿
}ADC_InitTypeDef;
在设置完了以上信息后,就可以开启 AD 转换器了(通过 ADC_CR2 寄存器控制)
HAL_ADC_Start(&ADC1_Handler); //开启 ADC
配置通道,读取通道ADC值
在完成上面的步骤后,ADC已经准备好。接下来设置规则序列 1 的通道,然后启动 ADC 转换。在转换结束后,读取转换结果值。
设置规则序列通道以及采样周期的函数是:
HAL_StatusTypeDef HAL_ADC_ConfigChannel(
ADC_HandleTypeDef* hadc,
ADC_ChannelConfTypeDef* sConfig);
第一个参数就不用多说了,第二个入口参数 sConfig,它
是 ADC_ChannelConfTypeDef 结构体指针类型,结构体定义如下:
typedef struct {
uint32_t Channel; //ADC 通道
uint32_t Rank; //规则通道中的第几个转换
uint32_t SamplingTime; //采样时间
uint32_t Offset; //备用,暂未用到
}ADC_ChannelConfTypeDef;
//实例
ADC1_ChanConf.Channel= ADC_CHANNEL_5; //通道 5
ADC1_ChanConf.Rank=1; //第 1 个序列,序列 1
ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
ADC1_ChanConf.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
配置好通道并且使能 ADC 后,接下来就是读取 ADC 值。采取的是查询方式读取(最近期末时间紧迫 下次尝试DMA ), 所以还要等待上一次转换结束。此过程 HAL 库提供了专用函数 HAL_ADC_PollForConversion,函数定义为:
HAL_StatusTypeDef HAL_ADC_PollForConversion(
ADC_HandleTypeDef* hadc,
uint32_t Timeout);
等待上一次转换结束之后,接下来就是读取 ADC 值,函数为:
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc);
SD卡
通过今天的学习主要了解SD卡与文件系统FATFS的使用,具体实现原理可参考以下博客讲解
https://blog.csdn.net/vca821/article/details/80738151?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
https://blog.csdn.net/nulidehahafr/article/details/84146148
hal 库 SD 卡支持源文件 stm32f4xx_hal_sd.c 和 stm32f4xx_II_sdmmc.h以及对应头文件stm32f4xx_hal_sd.h和stm32f4xx_II_sdmmc.h
而要想真正应用SD卡就必须使用文件系统管理,使用 FATFS 来管理 SD 卡实现 SD 卡文件的读写等。
FatFs 是一个通用的文件系统(FAT/exFAT)模块,用于在小型嵌入式系统中实现FAT文件系统。 FatFs 组件的编写遵循ANSI C(C89),完全分离于磁盘 I/O 层,因此不依赖于硬件平台。它可以嵌入到资源有限的微控制器中,如 8051, PIC, AVR, ARM, Z80, RX等等,不需要做任何修改。
FATFS 是一个完全免费开源的 FAT 文件系统模块它完全用标准 C 语言编写,所以具有良好的硬件平*立性。
FATFS 的源码可在http://elm-chan.org/fsw/ff/00index_e.html下载。
应用层的函数f_open f_read f_write f_close 等,可以像在PC 上读/写文件那样简单。(具体函数应用参考主函数代码)
主函数代码
核心代码如下
f_opendir((u8 *)"0:/"); //打开目录
delay_ms(5); //延迟5ms(开心就好
f_open((u8 *)"xdpnb.txt",2); //打开目录下文件(模式2 r+) (Xdp牛逼
for(t = 0; t < 2048; t++){ //采样2048次
adcx=Get_Adc_Average(ADC_CHANNEL_5,1);//获取Adc通道5的转换值 1次取平均
rui[t] = adcx; //存于Rui数组
}
for(t = 0; t < 2048; t++){ //为了保证采样质量 区分采集与转存过程
myitoa(rui[t],tem,10); //调用自定义数字转字符函数 存于临时数组
f_write((u8 *)tem,0X4); //向SD卡写入数组 长度4
f_write((u8 *)"\r\n",0X2); //换行符(用于Matlab解析
}
f_close(); //关闭文件!
(Ps:打开文件后一定要close close close)
模拟采集的adc数值为实验室信号源所产生的正弦波
具体实验现象与原理移步学长博客
TerayTech
离线式数字信号处理(一)—— 使用Matlab读取TXT文件并做FFT分析
离线式数字信号处理(二)——使用Matlab对STM32F4 ADC采集到的数据进行分析
(即将接手学长的28nm)Xilinx ZYNQ学习笔记(一)——使用PS读写SD卡