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.

[参考译文] TM4C129ENCPDT:主应用循环和计时器速度

Guru**** 2928560 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1002880/tm4c129encpdt-main-application-loop-and-timer-speed

器件型号:TM4C129ENCPDT

我的计时器有问题。 当我将计时器设置为像这样运行时、

MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock/2);

主应用程序循环将不再运行、对微控制器的简单 ping 将超时。 降低计时器的速度将解决此问题、

MAP_TimerLoadSet(TIMER0_BASE, TIMER_A, ui32SysClock);

计时器运行以下代码、

//=========================================================================
//          Auto Range Event Timer
//=========================================================================
void Timer0IntHandler(void)
{
   char cOne, cTwo;

   // Clear the timer interrupt.
   MAP_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
   // Toggle the flag for the first timer.
   HWREGBITW(&g_ui32Flags, FLAG_AUTORNG) ^= 1;

   uint32_t status_led_c;
   uint32_t status_led_a;
   uint32_t status_led_b;
   uint32_t status_led_d;

   uint32_t adc_count_a;
   uint32_t adc_count_b;
   uint32_t adc_count_c;
   uint32_t adc_count_d;

   //UARTprintf("==============================\n");
   //UARTprintf("CH A \t CH B \t CH C \t CH D \n");
   //UARTprintf("==============================\n");

   switch (STATE_A) {
      case 'R':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
         UARTprintf("%c:%c \t\t|", R_CH_A, STATE_A);
         previous_range('A', CH_A_PRE_R);
         if (R_CH_A == '5' | R_CH_A == '6' | R_CH_A == '7') {
             STATE_A = 'M';
         }
         else {
             STATE_A = 'M';
         }
         break;
      case 'U':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
         UARTprintf("%c:%c (UP) \t|", R_CH_A, STATE_A);
         set_range('A', R_CH_A+1);
         STATE_A = 'R';
         CH_A_PRE_R = R_CH_A+1;
         break;
      case 'D':
         //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);
          UARTprintf("%c:%c (DWN) \t\t|", R_CH_A, STATE_A);
         set_range('A', R_CH_A-1);
         STATE_A = 'R';
         CH_A_PRE_R = R_CH_A-1;
         break;
      case 'S':
          //UARTprintf("KIRT CH A: STATE %c (%d)", STATE_A, SD_CH_A);
          adc_count_a = read_adc_A();
          //UARTprintf("   CH A: ADC Reading = %d\n", adc_count_a);
          if (SD_CH_A < 5) {
              SD_CH_A++;
          }
          else {
              STATE_A = 'M';
          }
          UARTprintf("%c:%c (%d)(%d) \t|", R_CH_A, STATE_A, SD_CH_A, adc_count_a);
          break;
      case 'M':
          //0. Reset stabilize delay.
          SD_CH_A = 0;
          //1. Channel A Toggle LED Status Light.
          status_led_a = ROM_GPIOPinRead(GPIO_PORTB_BASE, GPIO_PIN_2);
          status_led_a ^= 1 << 2;
          ROM_GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_2, status_led_a);
          //UARTprintf("KIRT CH A: STATE %c\n", STATE_A);

          //2. Measure Channel A ADC.
          //Read the ADC
          adc_count_a = read_adc_A();
          M_R_CH_A = R_CH_A;
          //UARTprintf("   CH A: ADC Reading = %d\n", adc_count_a);
          CH_A = adc_count_a;
          //Read the PN.
          PN_CH_A = ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_0);
          UARTprintf("%c:%c (%d) \t|", R_CH_A, STATE_A, adc_count_a);

          //3. Switch Range based on ADC Count.
          //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
         if (adc_count_a > adc_count_low & adc_count_a < adc_count_high) {
             //UARTprintf("   CH A: CR = %d.IN\n", R_CH_A);
         }
         else {
             //b. Measurement To Low. Move Up in Range.
            if (adc_count_a < adc_count_low & R_CH_A != '7') //ADC Count Low, Move to Higher Range.
            {
                //UARTprintf("   CH A: SR = %d.L\n", R_CH_A);
                STATE_A = 'U';
            }
            //c. Measurement to High. Move Down in Range.
            if (adc_count_a > adc_count_high & R_CH_A != '1') //Too High, Move to Lower Range.
            {
                //UARTprintf("   CH A: SR = %d.H\n", R_CH_A);
                STATE_A = 'D';
            }
        break;
         }

      }

   switch (STATE_B) {
         case 'R':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
            UARTprintf("%c:%c \t\t|", R_CH_B, STATE_B);
            previous_range('B', CH_B_PRE_R);
            STATE_B = 'M';
            if (R_CH_B == '5' | R_CH_B == '6' | R_CH_B == '7') {
                 STATE_B = 'M';
             }
             else {
                 STATE_B = 'M';
             }
            break;
         case 'U':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
            UARTprintf("%c:%c (UP) \t|", R_CH_B, STATE_B);
            set_range('B', R_CH_B+1);
            STATE_B = 'R';
            CH_B_PRE_R = R_CH_B+1;
            break;
         case 'D':
            //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);
             UARTprintf("%c:%c (DWN) \t\t|", R_CH_B, STATE_B);
            set_range('B', R_CH_B-1);
            STATE_B = 'R';
            CH_B_PRE_R = R_CH_B-1;
            break;
         case 'S':
           //UARTprintf("KIRT CH B: STATE %c (%d)", STATE_B, SD_CH_B);
           adc_count_b = read_adc_B();
           //UARTprintf("   CH B: ADC Reading = %d\n", adc_count_b);
           if (SD_CH_B < 5) {
               SD_CH_B++;
           }
           else {
               STATE_B = 'M';
           }
           UARTprintf("%c:%c (%d)(%d) \t|", R_CH_B, STATE_B, SD_CH_B, adc_count_b);
           break;
         case 'M':
             //0. Reset stabilize delay.
             SD_CH_B = 0;
             //1. Channel A Toggle LED Status Light.
             status_led_b = ROM_GPIOPinRead(GPIO_PORTN_BASE, GPIO_PIN_2);
             status_led_b ^= 1 << 2;
             ROM_GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_2, status_led_b);
             //UARTprintf("KIRT CH B: STATE %c\n", STATE_B);

             //2. Measure Channel A ADC.
             uint32_t adc_count_b;
             adc_count_b = read_adc_B();
             M_R_CH_B = R_CH_B;
             //UARTprintf("   CH B: ADC Reading = %d\n", adc_count_b);
             CH_B = adc_count_b;
             PN_CH_B = ROM_GPIOPinRead(GPIO_PORTD_BASE, GPIO_PIN_7);
             UARTprintf("%c:%c (%d) \t|", R_CH_B, STATE_B, adc_count_b);

             //3. Switch Range based on ADC Count.
             //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
            if (adc_count_b > adc_count_low & adc_count_b < adc_count_high) {
                //UARTprintf("   CH B: CR = %d.IN\n", R_CH_B);
            }
            else {
                //b. Measurement To Low. Move Up in Range.
               if (adc_count_b < adc_count_low & R_CH_B != '7') //ADC Count Low, Move to Higher Range.
               {
                   //UARTprintf("   CH B: SR = %d.L\n", R_CH_B);
                   STATE_B = 'U';
               }
               //c. Measurement to High. Move Down in Range.
               if (adc_count_b > adc_count_high & R_CH_B != '1') //Too High, Move to Lower Range.
               {
                   //UARTprintf("   CH B: SR = %d.H\n", R_CH_B);
                   STATE_B = 'D';
               }
           break;
            }

         }

   switch (STATE_C) {
   case 'R':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c \t\t|", R_CH_C, STATE_C);
      previous_range('C', CH_C_PRE_R);
      STATE_C = 'M';
      if (R_CH_C == '5' | R_CH_C == '6' | R_CH_C == '7') {
           STATE_C = 'M'; //Changed to M from S.
       }
       else {
           STATE_C = 'M';
       }
      break;
   case 'U':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c (UP) \t|", R_CH_C, STATE_C);
      set_range('C', R_CH_C+1);
      STATE_C = 'R';
      CH_C_PRE_R = R_CH_C+1;
      break;
   case 'D':
      //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);
       UARTprintf("%c:%c (DWN) \t\t|", R_CH_C, STATE_C);
      set_range('C', R_CH_C-1);
      STATE_C = 'R';
      CH_C_PRE_R = R_CH_C-1;
      break;
   case 'S':
      //UARTprintf("KIRT CH C: STATE %c (%d)", STATE_C, SD_CH_C);
      adc_count_c = read_adc_C();
      UARTprintf("%c:%c (%d)(%d) \t|", R_CH_C, STATE_C, SD_CH_C, adc_count_c);
      //UARTprintf("   CH C: ADC Reading = %d\n", adc_count_c);
      if (SD_CH_C < 5) {
          SD_CH_C++;
      }
      else {
          STATE_C = 'M';
      }
      break;
   case 'M':
       //0. Reset stabilize delay.
        SD_CH_C = 0;
        //1. Channel C Toggle LED Status Light.
       status_led_c = ROM_GPIOPinRead(GPIO_PORTE_BASE, GPIO_PIN_1);
       status_led_c ^= 1 << 1;
       ROM_GPIOPinWrite(GPIO_PORTE_BASE, GPIO_PIN_1, status_led_c);
       //UARTprintf("KIRT CH C: STATE %c\n", STATE_C);

       //2. Measure Channel C ADC.
       uint32_t adc_count_c;
       adc_count_c = read_adc_C();
       M_R_CH_C = R_CH_C;
       //UARTprintf("   CH C: ADC Reading = %d\n", adc_count_c);
       CH_C = adc_count_c;
       PN_CH_C = ROM_GPIOPinRead(GPIO_PORTH_BASE, GPIO_PIN_2);
       UARTprintf("%c:%c (%d) \t|", R_CH_C, STATE_C, adc_count_c);

       //3. Switch Range based on ADC Count.
       //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
      if (adc_count_c > adc_count_low & adc_count_c < adc_count_high) {
          //UARTprintf("   CH C: CR = %d.IN\n", R_CH_C);
      }
      else {
          //b. Measurement To Low. Move Up in Range.
         if (adc_count_c < adc_count_low & R_CH_C != '7') //ADC Count Low, Move to Higher Range.
         {
             //UARTprintf("   CH C: SR = %d.L\n", R_CH_C);
             STATE_C = 'U';
         }
         //c. Measurement to High. Move Down in Range.
         if (adc_count_c > adc_count_high & R_CH_C != '1') //Too High, Move to Lower Range.
         {
             //UARTprintf("   CH C: SR = %d.H\n", R_CH_C);
             STATE_C = 'D';
         }
     break;
      }

   }

   switch (STATE_D) {
   case 'R':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c \t\t|", R_CH_D, STATE_D);
      previous_range('D', CH_D_PRE_R);
      STATE_D = 'M';
      if (R_CH_D == '5' | R_CH_D == '6' | R_CH_D == '7') {
           STATE_D = 'M';
       }
       else {
           STATE_D = 'M';
       }
      break;
   case 'U':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c (UP) \t|", R_CH_D, STATE_D);
      set_range('D', R_CH_D+1);
      STATE_D = 'R';
      CH_D_PRE_R = R_CH_D+1;
      break;
   case 'D':
      //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);
       UARTprintf("%c:%c (DWN) \t\t|", R_CH_D, STATE_D);
      set_range('D', R_CH_D-1);
      STATE_D = 'R';
      CH_D_PRE_R = R_CH_D-1;
      break;
   case 'S':
     //UARTprintf("KIRT CH D: STATE %c (%d)", STATE_D, SD_CH_D);
     adc_count_d = read_adc_D();
     UARTprintf("%c:%c (%d)(%d) \t|", R_CH_D, STATE_D, SD_CH_D, adc_count_d);
     //UARTprintf("   CH D: ADC Reading = %d\n", adc_count_d);
     if (SD_CH_D < 5) {
         SD_CH_D++;
     }
     else {
         STATE_D = 'M';
     }
     break;
   case 'M':
       //0. Reset stabilize delay.
               SD_CH_D = 0;
        //1. Channel C Toggle LED Status Light.
       status_led_d = ROM_GPIOPinRead(GPIO_PORTM_BASE, GPIO_PIN_4);
       status_led_d ^= 1 << 4;
       ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_4, status_led_d);
       //UARTprintf("KIRT CH D: STATE %c\n", STATE_D);

       //2. Measure Channel C ADC.
       uint32_t adc_count_d;
       adc_count_d = read_adc_D();
       M_R_CH_D = R_CH_D;
       //UARTprintf("   CH D: ADC Reading = %d\n", adc_count_d);
       CH_D = adc_count_d;
       PN_CH_D = ROM_GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_3);
       UARTprintf("%c:%c (%d) \t|", R_CH_D, STATE_D, adc_count_d);

       //3. Switch Range based on ADC Count.
       //a. Measurement in Range. -> adc_count_low < adc_count_c < adc_count_high
      if (adc_count_d > adc_count_low & adc_count_d < adc_count_high) {
          //UARTprintf("   CH D: CR = %d.IN\n", R_CH_D);
      }
      else {
          //b. Measurement To Low. Move Up in Range.
         if (adc_count_d < adc_count_low & R_CH_D != '7') //ADC Count Low, Move to Higher Range.
         {
            //UARTprintf("   CH D: SR = %d.L\n", R_CH_D);
             STATE_D = 'U';
         }
         //c. Measurement to High. Move Down in Range.
         if (adc_count_d > adc_count_high & R_CH_D != '1') //Too High, Move to Lower Range.
         {
             //UARTprintf("   CH D: SR = %d.H\n", R_CH_D);
             STATE_D = 'D';
         }
     break;
      }

   }

   UARTprintf("\n");
}

是否有办法在不影响主应用程序循环的情况下提高 Timer0IntHandler 的速度。 如果您想查看、我已附加 CCS 项目。

谢谢、

Allane2e.ti.com/.../enet_5F00_uip.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Allan、

    您遇到的问题是、您的计时器 ISR 执行时间太长。 因此、当您尝试减慢它的速度时、会发生另一个中断在您退出当前中断时等待。

    造成这种情况的主要原因是  在 ISR 内部使用 UARTprintf 语句。 切勿执行此操作、因为 它们是非常慢的 API 调用、会阻止 ISR 进一步处理。 您需要找到一种方法、让主应用程序通过使用您在计时器 ISR 中设置的标志来处理、以指示何时需要执行 UARTprintf。

    有关如何优化 ISR 的更多建议、请参阅我们入门指南的 ISR 最佳实践部分: https://www.ti.com/lit/pdf/spmu373

    此致、
    Ralph