Таймеры и внутренний тактовый генератор на микроконтроллере Freescale

Я использую MC9S08AW60A с платой DEMO9S08AW60E (Freescale). Я изучил таймеры, предоставленные MCU. Я хочу знать, как именно реализовать таймеры по коду. Пакет Freescale также поставляется с Processor Expert (графический интерфейс для настройки MCU).

Я написал следующий код для последовательного включения светодиодов БЕЗ использования функции ЗАДЕРЖКИ, т.е. только путем изменения/использования ТАЙМЕРОВ и ВНУТРЕННЕГО ГЕНЕРАТОРА ЧАСОВ.

//------------CODE BEGINS------------

PTFDD = 0xFF;
TPM1SC = 0x0E;//configures the Timer 1 Status and Control Register
TPM1C2SC = 0x98;//configures the TImer 1 CHANNEL 2 Status and Control Register
ICGC1= 0xE8; //Have altered the ICG with respect to TPM.
ICGC2= 0x8E;
//As you can see i have not altered the ICG in any way.And the same values as above 
//(for TPM) i have emulated using the Processor Expert.  
for (i=1;i<=8;i++)
  {
    if (i==8) i = 1;       
if (i==1) PTFD = 0x01;    
if (i==2) PTFD = 0x02;    
if (i==3) PTFD = 0x04;    
if (i==4) PTFD = 0x08;    
if (i==5) PTFD = 0x10;    
if (i==6) PTFD = 0x20;    
if (i==7) PTFD = 0x40;
}

//----------CODE ENDS-----------------

Но все, что я получаю:

  1. Светодиоды горят, но очень тускло, я думаю, они переключаются очень быстро. Я прав?
  2. Кроме того, нужно ли менять настройки ICG при использовании TImer?
  3. Кроме того, я инициализировал устройство с помощью Processor Expert и написал то же самое, что и код. мешает ли. (я убедился, что оба представляют одни и те же значения, иначе это показало бы мне ошибку.

В техническом описании см. стр. 165 для таймера/ШИМ и стр. 129 для Inter Clock Generator.

Что касается вашего первого вопроса, у вас есть осциллограф, который вы можете проверить? Если нет, попробуйте установить точку останова и пройти через нее. Если вы это сделаете, каждый светодиод должен загореться на полную яркость и должен измениться только при переходе к следующему шагу.
@embedded.kyle: я проверил это. Интересно, что светодиоды не горят. И я также только что понял, что светодиоды и таймер имеют одни и те же контакты. Может в этом причина??
@embedded.kyle: да, я могу взять осциллограф. Какие пины проверять?
Они не загораются, когда вы проходите через них? Это любопытно. Я не знаком с чипом, поэтому мне придется немного проверить таблицу данных. Но при нормальной работе используйте осциллограф, чтобы проверить контакты, которые управляют каждым светодиодом. Вы должны иметь доступ к ним из заголовков. Проверьте частоту прямоугольной волны, которая ими управляет.
Попробуйте установить TPM1SC = 0x10. ELSnB:ELSnAоба должны быть равны 0, чтобы таймер не переключал вывод при сравнении.
@embedded.kyle: спасибо, приятель, что изучил это. Это все еще не имеет значения. светодиоды просто тусклые.

Ответы (1)

По-видимому, поскольку частота таймера очень высока, для ее настройки нам потребуется большое значение Prescaler Setting (макс. 128). Поговорив с моим коллегой, он сказал, что мне нужно генерировать периодический «тик» с соответствующим периодом мигания для каждого светодиода. Чтобы убедиться, что светодиод (ON или OFF) соответствует TICK, а не тактовой частоте шины. Да, это работает, но я все еще сбит с толку.

  1. Если вы можете использовать таблицу данных, чтобы понять различные функции регистра, то почему установка частоты таймера в соответствии с требованиями не работает?

  2. Более того, разве этот «тик» не совпадает с функцией задержки??

вот код для того же самого (кстати, этот код был предложен мне на форуме freescale, но он также может помочь кому-то еще; я не беру кредит на этот код):

// Assumed bus frequency: 8.0 MHz
// TPM prescale divisor:  4



// Global variables:
byte tic_cnt;             // Timer tick counter
byte ch_nbr;              // LED channel number



// LED mask values:
#define mLED0    0x01
#define mLED1    0x02
#define mLED2    0x04
#define mLED3    0x08
#define mLED4    0x10
#define mLED5    0x20
#define mLED6    0x40
#define mLED7    0x80



#define TIC_INCR 20000    // 10 ms tick period, with prescale 4


//***************************************************************

// LED blink polling function

void LED_poll( void)

{

   if (!tic_cnt)

  {        // Timeout occurred

      tic_cnt = 50;       // Start new 500ms timing interval


      ch_nbr++;

      if (ch_nbr == 8)  ch_nbr = 0;

      if (ch_nbr == 0)  PTFD = mLED0;  // Turn LED0 on, other LEDs off
      if (ch_nbr == 1)  PTFD = mLED1;  // Turn LED1 on, other LEDs off
      if (ch_nbr == 2)  PTFD = mLED2;  // Turn LED2 on, other LEDs off
      if (ch_nbr == 3)  PTFD = mLED3;  // Turn LED3 on, other LEDs off
      if (ch_nbr == 4)  PTFD = mLED4;  // Turn LED4 on, other LEDs off
      if (ch_nbr == 5)  PTFD = mLED5;  // Turn LED5 on, other LEDs off
      if (ch_nbr == 6)  PTFD = mLED6;  // Turn LED6 on, other LEDs off
      if (ch_nbr == 7)  PTFD = mLED7;  // Turn LED7 on, other LEDs off
   }
}

__interrupt VectorNumber_Vtpm1ch0 void ISR_TPM1_ch0( void)

{

   TPM1C0_CH0F = 0;       // Clear TPM channel flag

   TPM1C0V += TIC_INCR;   // Set next software compare

   if (tic_cnt)  tic_cnt--;
}
«Если вы можете использовать таблицу данных, чтобы понять различные функции регистров, то почему установка частоты таймера в соответствии с требованиями не работает?» Возможно, аппаратное обеспечение таймера не поставляется с аппаратным предварительным масштабированием, достаточно большим для создания желаемых задержек.
«Более того, разве этот «тик» не совпадает с функцией задержки??» Нет, далеко не так. Функция задержки — это то, что просто сжигает циклы ЦП в цикле, мало заботясь о точности в реальном времени. С решением прерывания, таким как то, которое вы опубликовали, ЦП может выполнять значимые задачи, ожидая вашего таймера. Например, он может запускать основной цикл программы и мигать светодиодом в качестве «фоновой задачи». И в то же время вы получаете гораздо лучшую точность в реальном времени.
@Lundin: спасибо, приятель. это многое прояснило.