读取adc值,adc0832读取数据的过程
墨初 知识笔记 41阅读
结论优先程序并发处理不当引起寄存器标志位被非预期清除引起进入死循环。
现象在进行AD读取数据时有一个等待ADC转换完成的标志位概率性卡死在while等待ADC数据转换完成。

static err_t gd32_adc_read(struct drv_adc_device *dev, int16_t channel, uint32_t *buf, size_t size) { struct gd32_adc *adc (struct gd32_adc *)(dev->private_data); uint32_t adc_periph (uint32_t)(adc->adc_periph); if (buf NULL) { return -E_INVAL; } adc_channel_length_config(adc_periph, ADC_REGULAR_CHANNEL, 1); adc_regular_channel_config(adc_periph, 0, channel, ADC_SAMPLETIME_239POINT5); for (size_t i 0; i < size; i) { adc_software_trigger_enable(adc_periph, ADC_REGULAR_CHANNEL); gd32_udelay(2); while (!adc_flag_get(adc_periph, ADC_FLAG_EOC)) ; adc_flag_clear(adc_periph, ADC_FLAG_EOC); buf[i] (uint16_t)adc_regular_data_read(adc_periph); } return size;}
在不同任务中都有调用获取AD数据的操作死循环出现时定位到在while (!adc_flag_get(adc_periph, ADC_FLAG_EOC))处
一开始推测问题出现方向

1. 函数参数传递异常
2. 寄存器的置位异常硬件动作
验证1仿真时定位到问题现场传参正确可排除
验证2手动置起转换完成标志位不复现但暂无法证明硬件置位异常首先还是从自身找问题
想到一个读取AD的动作发生在硬件定时器超时回调里中断优先级高于任务执行可能出现在任务正在读取AD数据中来了硬件定时器中断读取过程被打断此时中断中读取完成把转换完成标志位清除退出中断回调继续执行任务读取此时一直等不到标志被置起。
这里存在设计缺陷我们移出在中断里读取AD操作中断不做耗时延时操作同时同一个ADC控制器应该作为临界资源互斥访问。
标签: