This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[TI]TM4C123GH6PZ sys/bios ADC READ问题



如何在 sys/bios 用TSK实现对ADC的定周期read,之前用TSK timeout及timer定周期读都有问题,用timer定周期读程序跑飞,而用TSK timeout的方式,TSK总是出现堆栈溢出的问题。

希望高手能帮忙解决一下

 

提示的错误信息:

e: 0x200016d0.
Task stack size: 0x200.
R0 = 0x00000003  R8  = 0xffffffff
R1 = 0x0000054e  R9  = 0xffffffff
R2 = 0x00000e04  R10 = 0xffffffff
R3 = 0x0000054d  R11 = 0xffffffff
R4 = 0xffffffff  R12 = 0x00000000
R5 = 0xffffffff  SP(R13) = 0x20001898
R6 = 0xffffffff  LR(R14) = 0x0000b72b
R7 = 0xffffffff  PC(R15) = 0x00000e04
PSR = 0x80000000
ICSR = 0x00427803
MMFSR = 0x00
BFSR = 0x00
UFSR = 0x0002
HFSR = 0x40000000
DFSR = 0x0000000a
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...
 

 

adc read函数及ADC配置函数:

 

/*ADC READ函数*/

void wvdAdcRead()
{

 uint32_t aubADC_ReadData[ADC_READ];

    ADCProcessorTrigger(ADC1_BASE, 2);

    ADCSequenceDataGet(ADC1_BASE, 2, aubADC_ReadData);

}

/*TSK_ADC*/

void TSK_ADC(INT stacd)

 OS_StdMail_ts *astStdMail_p;
 OS_ErrCode_t aubOsRet;
 OS_StdMail_ts msg;
 astStdMail_p=&msg;
 
 wuwAdcControlWaitTime = OS_TOUT_FOREVER;
 wuwTempChkTime = 0;
 while(1)
 {
  
  aubOsRet = OS_ReceiveMail(MBX_ID_ADC, wuwAdcControlWaitTime, astStdMail_p);
  
  if (aubOsRet == OS_ERR_OK)
  {          /* Message reception result OK */
   if (astStdMail_p->uhEventCode == EV_ADC_CTRL_LOAD)
   {
    wuwAdcControlWaitTime = ADC_MSG_WAIT_TIME; 
    
    wvdAdcCtrlInfoNotice(TSK_ID_POWER, PM_CALLBACK_LOAD);

   }
   else if(astStdMail_p->uhEventCode == EV_ADC_CTRL_UNLOAD)
   {
    wuwAdcControlWaitTime = OS_TOUT_FOREVER;
    
    wvdAdcCtrlInfoNotice(TSK_ID_POWER, PM_CALLBACK_UNLOAD); 
   }
   else
   {
    ;
   }
  }
  else/* Message reception time-out */
  {

   wuwAdcControlWaitTime = ADC_MSG_WAIT_TIME;  

      
   wvdAdcRead();

}

}

}

 

/*ADC Configure*/

void wvdADCConfigure()
{
   SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);
 
   SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
 
   GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);
 
   ADCSequenceConfigure(ADC1_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);
 
   ADCSequenceEnable(ADC1_BASE, 2);
 
return;
}

  • 感觉楼主代码有两个问题:

    1)ADCSequenceConfigure之后还应该进行ADCSequenceStepConfigure设置,配置对哪些Channel采样等

    ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_IE | ADC_CTL_END | ADC_CTL_CH0);

    2)读之前应确认ADC转换是否完成

    while(!ADCIntStatus(ADC0_BASE, 0, false)) {}

  • 以下是修正后的代码,仍然有问题

    另外通过打log发现:

    ADCSequenceDataGet(ADC1_BASE, 2, aubADC_ReadData);返回值有时会为3,但实际上仅配置了两个采样序列,原因不明,不知道是否有关系

    void wvdADCConfigure()
    {
        SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);

        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

        GPIOPinTypeADC(GPIO_PORTD_BASE, GPIO_PIN_4 | GPIO_PIN_5);

        ADCSequenceConfigure(ADC1_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);


        ADCSequenceStepConfigure(ADC1_BASE, 2, 0, ADC_CTL_CH6);    /*Batt Volatage : AIN6  PD5*/
        ADCSequenceStepConfigure(ADC1_BASE, 2, 1, ADC_CTL_CH7|ADC_CTL_IE|ADC_CTL_END); /*Temperature : AIN7  PD4*/

     ADCSequenceEnable(ADC1_BASE, 2);
     
     return;
    }

     

    void wvdAdcRead()
    {

     uint32_t aubADC_ReadData[ADC_READ]; 

     //
        // Trigger the ADC conversion.
        //
        ADCProcessorTrigger(ADC1_BASE, 2);


     /*wait adc convert over*/
     while(!ADCIntStatus(ADC1_BASE, 2, false))
     {
      ;
     }


        ADCSequenceDataGet(ADC1_BASE, 2, aubADC_ReadData);


     nvdTemparaterCheck(aubADC_ReadData[1]);
     nvdBattVoltageCheck(aubADC_ReadData[0]);
     }

  • 因为没有用到中断,可以把中断去了

    ADCSequenceStepConfigure(ADC1_BASE, 2, 1, ADC_CTL_CH7|ADC_CTL_END); /*Temperature : AIN7  PD4*/

     

    楼主出问题的,读出来的前两个值都正确吗?可以试着在ADCSequenceDataGet(ADC1_BASE, 2, aubADC_ReadData);之前,先看看寄存器里面到底有多少个结果,可以看ADCSSFSTAT2寄存器的HPTRTPTRHPTR表示下个要写的位置,TPTR表示下个要读的位置。