救急!32B1H的ADC采样,通道错位!
-
平台为初版样机,IAR+MCL调试
ADC0:采集MCU内部模拟量,为功能安全做准备;
ADC1:采集用户PCB上的一些模拟量,大部分为0-15通道。采集方式:PWM+TMU硬件触发,采样频率暂设置为1k;
问题描述:对于ADC1,当通道组设置为2路时,采集结果正确,之后在本组尝试增加通道数,IAR仿真结果错位。代码如下:
// 6-Adc初始化 Adc_Init(&Adc_Config); CddTrg_Init(&CddTrg_Config); Pwm_Init(&Pwm_Config); Adc_SetupResultBuffer(AdcConf_AdcConfigSet_Adc0_Gp1, HwTrigGroupRstFIFO);// 设置存储转换结果的buffer Adc_EnableGroupNotification(AdcConf_AdcConfigSet_Adc0_Gp1); // 使能通道组转换完成中断。EB中也要使能 Adc_EnableHardwareTrigger(AdcConf_AdcConfigSet_Adc0_Gp1); // adc1-group1 Adc_SetupResultBuffer(AdcConf_AdcConfigSet_Adc1_Gp1, HwTrigGroupRstFIF1);// 设置存储转换结果的buffer Adc_EnableGroupNotification(AdcConf_AdcConfigSet_Adc1_Gp1); // 使能通道组转换完成中断。EB中也要使能 Adc_EnableHardwareTrigger(AdcConf_AdcConfigSet_Adc1_Gp1); //adc1-gp1///////////////////////////////// ITCM_FUN void Adc1_HwTrgGroupNotification1(void) { debug_time[0]=precise_us_time(1); precise_us_time(0); Adc_StartGroupConversion(AdcConf_AdcConfigSet_Adc1_Gp2); if(Adc_GetGroupStatus(AdcConf_AdcConfigSet_Adc1_Gp1)==ADC_STREAM_COMPLETED) // { Adc_ReadGroup(AdcConf_AdcConfigSet_Adc1_Gp1, HwTrigGroupRseultPhys1); for(uint8 LoopCnt = 0; LoopCnt<Adc1_Gp1_CHANNEL_NUMBER; LoopCnt++) { HwTrigGroupRseultPhys1[LoopCnt] = (uint32)HwTrigGroupRseultPhys1[LoopCnt]*3300/4095 * 1603/100 ; } } }
这种错位有点像常见的DMA传输带来的错位;是否有函数或办法,把采集值跟通道号关联起来,这样的话就不会造成错位了。
现在是样机调试阶段,所以每出现一个新问题,没有太多时间去一点点测试填坑;
-
目前MCAL ADC转换结果没带通道编号。你用的是HotFix0.1版本吗?如果不是建议升级到这个版本,这个版本修复过一个硬件触发+DMA传输采集结果的问题。另外我看ADC1用的两个硬件触发的group,需要注意一个group转换完成后,如果想切换group,需要先将当前group disable掉。
-
houjun_xiao
经测试,在通道组完成通知中,重启硬件触发,貌似不再错位。// 重启通道组,不然采集结果会错位,时间开销10us Adc_DisableHardwareTrigger(AdcConf_AdcConfigSet_Adc1_Gp1); Adc_EnableHardwareTrigger(AdcConf_AdcConfigSet_Adc1_Gp1);
但执行这两行代码会消耗10us。显然不是最佳答案,但实测确实不错位了,如果屏蔽这两条代码,还是会错位。
后台需要给一个更科学合理的解决方案才行。因为这个问题属于挺严重的问题。
附:config版本是最新的,之前也安装过hotfix插件,但ytc还是老提醒安装这个插件。
-
ADC1的两个Group gp1配置硬件触发,gp2配置的软件触发?ADC1配置的DMA传输转换结果?是这样吗?
-
houjun_xiao
adc1的gp2暂时触发不起来,最初是想着adc1-gp2在adc-gp1的完成中断通知中进行软件触发,简单测了一下,adc1-gp2未响应触发,之后暂时把adc1的通道都放在gp1(但不支持通道28,回头再解决)。adc触发均采用pwm硬件触发,代码如下:
ITCM_FUN void Adc1_HwTrgGroupNotification1(void) { static uint8_t sum_count=0; static uint32_t sum_value[Adc1_Gp1_CHANNEL_NUMBER]={0}; uint16 ad_value[Adc1_Gp1_CHANNEL_NUMBER]; uint8_t i; // debug_time[0]=precise_us_time(1); precise_us_time(0); precise_us_time(0); if(Adc_GetGroupStatus(AdcConf_AdcConfigSet_Adc1_Gp1)==ADC_STREAM_COMPLETED){ Adc_ReadGroup(AdcConf_AdcConfigSet_Adc1_Gp1, ad_value); if(sum_count<8){ for(i = 0; i<Adc1_Gp1_CHANNEL_NUMBER; i++) sum_value[i] += ad_value[i]; sum_count++; } if(sum_count>=8){ // 测试 for(i = 0; i<Adc1_Gp1_CHANNEL_NUMBER; i++){ sum_value[i]= sum_value[i]>>3; if(i<2){ HwTrigGroupRseultPhys1[i] = sum_value[i]*3300/4095 * 1603/100 ; // 电压-mV } else{ HwTrigGroupRseultPhys1[i] = sum_value[i]*3300/4095 * 1000/783 ; // 电流-mA } sum_value[i]=0; } sum_count = 0; power.v24v.value = (HwTrigGroupRseultPhys1[1]+50)/100; } // 重启通道组,不然采集结果会错位,时间开销10us Adc_DisableHardwareTrigger(AdcConf_AdcConfigSet_Adc1_Gp1); Adc_EnableHardwareTrigger(AdcConf_AdcConfigSet_Adc1_Gp1); } if(sum_count==0) debug_time[0]=precise_us_time(1); }
代码
-
Gp2如果配置为SW触发模式,那么在调用Adc_StartGroupConversion函数前,需要先将Gp1 disable,否则Gp1(硬件触发的Group)会持续占有ADC资源,导致Gp2无法转换。所以如果存在需要软硬件触发交替采集的情况,需要在每个Group 完成的Notification函数中去启动另外一个Group,需要注意的是,如果在硬件的Notification中去触发软件Group采集,那么需要先disable当前硬件的Group。 另外,HA0 ADCIN的0-15channel无法与16-32channel混用在一个Group.
-
houjun_xiao 谢谢支持
最后是ADC1的gp1, gp2均采用了硬件触发。初始化时gp1使能硬件触发,gp2禁止硬件触发,
gp1通知函数中禁止1,使能2;
gp2中禁止2,使能1;
这样的话每一group实际采样频率为触发频率的1/2,短时间测试是没有错位了。
希望能稳定,千万不能是上车测试后过个十天半个月来一个错位,那将是致命错误。
-
两个硬件Group只能采用这种轮换的方式。
发帖前请查看
帮助没办法联网的电脑使用YCT
帮助改进和优化YT CONFIG TOOL,有机会抽取YTM32B1ME0 EVB哦...