今天和大家分享一下使用STM32F769制作的位移采集装置
一:STM32F769 ADC 知识分享:
STM32F769xx 系列有3个 ADC,这些 ADC 可以独立使用,也可以使用双重/三重模式(提高采样率)。STM32F769 的 ADC 是 12 位逐次逼近型的模拟数字转换器。它有 19 个通道,可测量 16 个外部源、2 个内部源和 Vbat 通道的信号。这些通道的 A/D 转换可以单次、连续、扫描或间断模式执行。ADC 的结果可以左对齐或右对齐方式存储在 16 位数据寄存器中。 模拟看门
狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。STM32F769IGT6 包含有3个ADC。STM32F769的 ADC 最大的转换速率为2.4Mhz,也就是转换时间为 0.41us(在 ADCCLK=36M,采样周期为3个 ADC 时钟下得到),不要让 ADC 的时钟超过 36M,否则将导致结果准确度下降。
STM32F769将ADC的转换分为2个通道组:规则通道组和注入通道组。规则通道相当于你正常运行的程序,而注入通道呢,就相当于中断。在你程序正常执行的时候,中断是可以打断你的执行的。同这个类似,注入通道的转换可以打断规则通道的转换, 在注入通道被转换完成之后,规则通道才得以继续转换。
ADC 的主要特征:
可配置 12 位、10 位、8 位或6 位分辨率
在转换结束、注入转换结束以及发生模拟看门狗或溢出事件时产生中断
单次和连续转换模式
扫描模式,自动转化通道 0到通道 n数据
数据对齐以保持内置数据一致性
可独立设置各通道采样时间
外部触发器选项,可为常规转换和注入转换配置极性
不连续采样模式
双重/三重模式(具有2个或更多 ADC 的器件提供)
双重/三重 ADC 模式下可配置的 DMA 数据存储
双重/三重交替模式下可配置的转换间延迟
ADC转换类型(参见数据手册)
ADC 电源要求:供电在 2.4V 到 3.6V 下可全速运行,供电低至 1.8V 时为慢速运行
ADC 输入范围:VREF-≤VIN≤ VREF+
常规通道转换期间可产生 DMA 请求
二:STM32 cube MX 软件的配置如下所示:
三:STM32 cube MX 软件生成代码如下所示:
- hadc1.Instance = ADC1;
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
- hadc1.Init.Resolution = ADC_RESOLUTION_12B;
- hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
- hadc1.Init.ContinuousConvMode = ENABLE;
- hadc1.Init.DiscontinuousConvMode = DISABLE;
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
- hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- hadc1.Init.NbrOfConversion = 1;
- hadc1.Init.DMAContinuousRequests = ENABLE;
- hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
- if (HAL_ADC_Init(&hadc1) != HAL_OK)
- {
- Error_Handler();
- }
复制代码 上述软件代码是软件配置之后,自动生成的功能,然后我下载之后,发现代码进入的 void NMI_Handler(void) 错误,由于我使用的是DMA的方式接收的ADC的数据,所以DMA还在正常运行,也是搞不懂为什么,串口输出也不正常。
然后我查询了下代码,将ADC的初始化修改如下所示代码:
- hadc1.Instance = ADC1;
- hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
- hadc1.Init.Resolution = ADC_RESOLUTION_12B;
- hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
- hadc1.Init.ContinuousConvMode = ENABLE;
- hadc1.Init.DiscontinuousConvMode = DISABLE;
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
- hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
- hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
- hadc1.Init.NbrOfConversion = 1;
- hadc1.Init.DMAContinuousRequests = ENABLE;
- hadc1.Init.EOCSelection = DISABLE;
- if (HAL_ADC_Init(&hadc1) != HAL_OK)
- {
- Error_Handler();
- }
复制代码 下面是ADC 结构体的的变量解释
- typedef struct{
- uint32 t ClockPrescaler;//分频系数 2/4/6/8 分频
复制代码 这里发现是 cube MX 软件配置中对下述变量配置不太一样:
- hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
- hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
复制代码 配置好ADC代码后,我们就直接读取ADC的数据就可以了
主程序代码如下:
- HAL_Delay(200) ;
- HAL_GPIO_TogglePin(GPIOJ,GPIO_PIN_13) ;
- // HAL_Delay(200) ;
- // HAL_GPIO_TogglePin(GPIOJ,GPIO_PIN_5) ;
- // HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_4) ;
- // HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_12) ;
- if(usart1_flag == 1)
- {
- usart1_flag = 0 ;
- HAL_UART_Transmit(&huart1,Usart1_DEAL_RX_Buf,usart1_rx_len,100);
- // printf("Hello STM32! Hello congcong! Hello STM32f769!\r\n");
- printf("Hello STM32! Hello congcong! Hello STM32f769!\r\n" );
- }
- printf("ubADCSample data = %5d\r\n" ,ubADCSample);
复制代码 PC截图如下所示:
调试感想如下:
虽然使用STM32 读取了ADC的数据,但是数据飘动还是比较大了,对于工业控制并不是很好,所以这里我推荐以下几种处理方式:
1:中值滤波方式:
主要是程序在执行的时候,连续采集N次(需要注意下这里下,这里的N必须取值奇数),程序需要按大到小或者从小到达的顺序进行排序,然后取中间数值做为有效值。
- int MidValueDeal(int N)
- {
- int value_buf[N]; int i,j,k,temp;
- for( i = 0; i < N; ++i)
- {
- value_buf[i] = HAL_ADC_GetValue(&hadc1);
- }
- for(j = 0 ; j < N-1; ++j)
- {
- for(k = 0; k < N-j-1; ++k)
- { //从小到大排序,冒泡法排序
- if(value_buf[k] > value_buf[k+1])
- {
- temp = value_buf[k];
- value_buf[k] = value_buf[k+1];
- value_buf[k+1] = temp;
- }
- }
- }
- return value_buf[(N-1)/2];
- }
复制代码 2:算术平均数滤波:连续取值N个数据,对所有的数据进行取平均值;
- int AverValueDeal(int N)
- {
- int sum = 0;
- unsinged short i;
- for(i = 0; i < N; ++i)
- {
- sum += HAL_ADC_GetValue(&hadc1);
- }
- return sum/N;
- }
复制代码 相比之下:STM32F769的硬件上面没有过采样的硬件配置,对于STM32U083单片机,已经支持硬件的过采样功能。当时测试时候发现,经过硬件处理之后,数据稳定性得到提高。
不过即使没有硬件的过采样,我们依然可以使用软件模拟过采样、滤波采样的功能,对数据进行处理。
最后,大家在调试ADC时候有什么好的建议和想法,麻烦评论区留言。
|
用标准的基准源进行观察。打印出ADC的值,使用分析软件进行分析评估。
不知道是不是我配置的问题,这个AD的数据,感觉还没有U083单片机的采集稳定
需要进行滤波算法进行处理吧。这么高的主频处理起来应该不难。但是这个12bit的ADC,他的应用场景不是高精度的ADC采集。如果想稳定,最好使用专业的ADC吧。
[md]嗯,这个正好有个机会研究一下,,感觉不如U0系列的好呢😄
这个也不能这样说,F769在当年可以说是高档产品了。他还有其他的功能,综合性能比U0要强很多。但是U0的使用的内核比F769要新,在能耗性能比上要比F7xx要好。各有所长。