[设计过程分享] MAX32630FTHR设计笔记(10):MAX32630本身存在问题:AD通道切换引起的干扰

Justice_Gao   2017-9-12 22:30 楼主
MAX32630的10位AD有多个通道,每个通道共用一个寄存器,如图 QQ截图20170912214330.png 我在调试的时候使用1个通道AIN0的时候,用示波器查看波形并没有问题,但是在使用AIN0和AIN1时就出现问题,代码程序如下:
  1. void TMR0_IRQHandler(void)
  2. {
  3. static uint8_t ADC_GET_Time=0;
  4. ADC_GET_Time++;
  5. if(ADC_GET_Time % 10==0)
  6. {
  7. adc_Channel=2;
  8. //ADC0_StartConvert(ADC_CH_0, 0, 1,4); //¿aê¼ADC0×a»»
  9. //ADC_StartConvert(ADC_CH_0_DIV_5, 0, 0);
  10. ADC_StartConvert(ADC_CH_0, 0, 0);
  11. ADC_GET_Time = 1;
  12. }
  13. else if((ADC_GET_Time % 2==0)&&(adc_Channel==0))
  14. {
  15. adc_Channel=1;
  16. //ADC0_StartConvert(ADC_CH_1, 0, 1,5); //¿aê¼ADC0×a»»
  17. ADC_StartConvert(ADC_CH_1, 0, 0);
  18. //ADC_StartConvert(ADC_CH_1_DIV_5, 0, 0);
  19. }
  20. TMR32_ClearFlag(MXC_TMR0);
  21. }
程序的功能是用定时器计时切换AD通道,切换周期为10ms,其他程序如下:
  1. #define USE_INTERRUPTS 1
  2. //#undef USE_INTERRUPTS
  3. /***** Globals *****/
  4. //#ifdef USE_INTERRUPTS
  5. volatile unsigned int adc_Channel = 0;
  6. //#endif
  7. /***** Functions *****/
  8. #ifdef USE_INTERRUPTS
  9. void AFE_IRQHandler(void)
  10. {
  11. uint16_t ADC_Value_Temp=0;
  12. ADC_GetData(&ADC_Value_Temp);
  13. /* Signal bottom half that data is ready */
  14. if(adc_Channel == 1)
  15. {
  16. //LED1_OFF;
  17. Get_ADC1_Data(ADC_Value_Temp);
  18. }
  19. else if(adc_Channel == 2)
  20. {
  21. Get_ADC2_Data(ADC_Value_Temp);
  22. }
  23. adc_Channel = 0;
  24. // LED0_TURN;
  25. ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF);
  26. return;
  27. }
  28. #endif
  29. void ADC0_Init()
  30. {
  31. /* Initialize ADC */
  32. ADC_Init();
  33. #ifdef USE_INTERRUPTS
  34. // NVIC_EnableIRQ(AFE_IRQn);
  35. NVIC_ClearPendingIRQ(AFE_IRQn);
  36. NVIC_DisableIRQ(AFE_IRQn);
  37. NVIC_SetPriority(AFE_IRQn, 1);
  38. NVIC_EnableIRQ(AFE_IRQn);
  39. #endif
  40. }
  41. /* ************************************************************************* */
  42. void ADC0_StartConvert(mxc_adc_chsel_t channel, unsigned int adc_scale, unsigned int bypass, uint32_t mode)
  43. {
  44. uint32_t ctrl_tmp;
  45. /* Clear the ADC done flag */
  46. ADC_ClearFlags(MXC_F_ADC_INTR_ADC_DONE_IF);
  47. /* Enable done interrupt */
  48. MXC_ADC->intr = MXC_F_ADC_INTR_ADC_DONE_IE;
  49. /* Insert channel selection */
  50. ctrl_tmp = MXC_ADC->ctrl;
  51. ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_CHSEL);
  52. ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) | (mode<<MXC_F_ADC_CTRL_ADC_CHSEL_POS));
  53. //ctrl_tmp |= ((channel << MXC_F_ADC_CTRL_ADC_CHSEL_POS) & MXC_F_ADC_CTRL_ADC_CHSEL);
  54. /* Clear channel configuration */
  55. ctrl_tmp &= ~(MXC_F_ADC_CTRL_ADC_REFSCL | MXC_F_ADC_CTRL_ADC_SCALE | MXC_F_ADC_CTRL_BUF_BYPASS);
  56. /* ADC reference scaling must be set for all channels but two*/
  57. if ((channel != ADC_CH_VDD18) && (channel != ADC_CH_VDD12)) {
  58. ctrl_tmp |= MXC_F_ADC_CTRL_ADC_REFSCL;
  59. }
  60. /* Finalize user-requested channel configuration */
  61. if (adc_scale || channel > ADC_CH_3) {
  62. ctrl_tmp |= MXC_F_ADC_CTRL_ADC_SCALE;
  63. }
  64. if (bypass) {
  65. ctrl_tmp |= MXC_F_ADC_CTRL_BUF_BYPASS;
  66. }
  67. /* Write this configuration */
  68. MXC_ADC->ctrl = ctrl_tmp;
  69. /* Start conversion */
  70. MXC_ADC->ctrl |= MXC_F_ADC_CTRL_CPU_ADC_START;
  71. }
这个问题美信技术支持也没有解决,这个问题无法避免,但是还是可以解决的,先来看现象
微信图片_20170912215422.jpg
图1
微信图片_20170912215431.jpg
图2
微信图片_20170912215425.jpg
图3
从图2和图3可以看出,杂波出现的周期刚好是10ms一次,所以我们可以这样处理,(1)降采样;(2)延时10ms以上采样(具体看你切换的时间周期)
本帖最后由 Justice_Gao 于 2017-9-12 22:32 编辑

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复