【STM32F429学习记录】HAL库版——ADC+DMA双缓冲采样和软件滤波例程
2025-10-29 来源:bilibili
本次移植参考了安富莱V7的ADC+DMA双缓冲例程,双缓冲编程的核心就是利用DMA传输一半和传输完成的标志位进行搞事情,将弱定义的DMAx_Streamy_IRQHandler()函数重新定义一下,要注意修改DMAx_Streamy_IRQHandler()中断函数中DMAx->LISR的传输一半和传输完成寄存器的值,要和你自己使用的DMA通道对应上,我自己刚开始学习DMA移植的时候忽略的这一点导致程序卡死不能运行,剩下的部分根据F429的例子进行了小修改,欢迎大家提出补充意见。
下载地址:https://www.lanzous.com/iaisahi

/*
*********************************************************************************************************
* 函 数 名: DMA2_Stream0_IRQHandler
* 功能说明: DMA2 Stream0中断服务程序
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void DMA2_Stream0_IRQHandler(void)
{
/* 传输完成中断 */
if((DMA2->LISR & DMA_FLAG_TCIF0_4) != RESET)
{
s_DmaFlag = 2;
/* 清除标志 */
DMA2->LIFCR = DMA_FLAG_TCIF0_4;
}
/* 半传输完成中断 */
if((DMA2->LISR & DMA_FLAG_HTIF0_4) != RESET)
{
s_DmaFlag = 1;
/* 清除标志 */
DMA2->LIFCR = DMA_FLAG_HTIF0_4;
}
/* 传输错误中断 */
if((DMA2->LISR & DMA_FLAG_TEIF0_4) != RESET)
{
/* 清除标志 */
DMA2->LIFCR = DMA_FLAG_TEIF0_4;
}
/* 直接模式错误中断 */
if((DMA2->LISR & DMA_FLAG_DMEIF0_4) != RESET)
{
/* 清除标志 */
DMA2->LIFCR = DMA_FLAG_DMEIF0_4;
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_GetAdcValues
* 功能说明: 获取ADC的数据并打印
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_GetAdcValues(void)
{
uint32_t values;
/* 当前DMA操作是前半个缓冲,读取前半个缓冲的前4个数值求平均 */
if(s_DmaFlag == 1)
{
DISABLE_INT();
s_DmaFlag = 0;
values = (ADCxValues[0] + ADCxValues[1] + ADCxValues[2] + ADCxValues[3])/4;
ENABLE_INT();
}
/* 当前DMA操作是后半个缓冲,读取后半个缓冲的前4个数值求平均 */
else if(s_DmaFlag == 2)
{
DISABLE_INT();
s_DmaFlag = 0;
values = (ADCxValues[64] + ADCxValues[65] + ADCxValues[66] + ADCxValues[67])/4;
ENABLE_INT();
}
/* 注意: 末尾只有 r回车, 没有n换行,可以使PC超级终端界面稳定在1行显示 */
{
/* 超级终端界面上会显示一个不断旋转的字符
增加这个功能,是为了避免程序死机的假象,因为ADC采样值很稳定
*/
static uint8_t pos = 0;
if (pos == 0)
printf("|");
else if (pos == 1)
printf("/");
else if (pos == 2)
printf("-");
else if (pos == 3)
printf("\"); /* 注意:这个特殊字符需要转义 */
if (++pos >= 4)
{
pos = 0;
}
printf(" PC2口线ADC采样值 = %5d , 电压 = %4dmVr",values, ((uint32_t)values * 3300) / 65535);
}
}

- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 蓝牙信道探测技术原理与开发套件实践
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析




