реклама на сайте
подробности

 
 
> at91sam7x128 и TC, проблемы с прерыванием
RuZaKi
сообщение Mar 12 2008, 11:59
Сообщение #1





Группа: Новичок
Сообщений: 5
Регистрация: 12-03-08
Пользователь №: 35 833



Не могу заставить работать прерывание от таймера T0 по достижению RC .
Сам таймер работает, + при бесконечном опросе флага AT91C_TC_CPCS в TC_SR (произошло накопление счетчика до значения RC) все робит как нуно. Но мне нужны прерывания по такому поводу.
Как правельно настроить, чтобы появились прерывания от таймера T0 по достижению счетчика значения RC ?

Код
#include "AT91SAM7S128.h"

void timer_tick10ms(void) __attribute__ ((interrupt)); // забыл вставить, но в моей проге это было и есть

void timer_tick10ms(void)
{
   unsigned int temp;

   AT91C_BASE_AIC->AIC_IDCR = (1<<AT91C_ID_TC0);
   temp=AT91C_BASE_TC0->TC_SR;
   led_tgl();
   AT91C_BASE_AIC->AIC_ICCR = (1<<AT91C_ID_TC0);
   AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
   AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_TC0);
   AT91C_BASE_AIC->AIC_EOICR = 0;//(1<<AT91C_ID_TC0);
}

void init_timer( void )
{
  AT91C_BASE_TCB->TCB_BCR = 1;
  AT91C_BASE_TCB->TCB_BMR = 0x15;
  AT91C_BASE_TC0->TC_CMR = (1 << 15) | (2<<13) | 1;//4
  AT91C_BASE_TC0->TC_RC = 0x1;
  //AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF;

  AT91C_BASE_TC0->TC_IDR &= ~((long)AT91C_TC_CPCS);
  AT91C_BASE_TC0->TC_IER |= AT91C_TC_CPCS;
  *AT91C_AIC_ICCR = (1<<AT91C_ID_TC0);

  AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFF;
  AT91C_BASE_AIC->AIC_EOICR = 0;//*/

  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned long)timer_tick10ms;
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] =  (1 << 5) | 0x7;

  AT91C_BASE_AIC->AIC_IDCR &= ~(1<<AT91C_ID_TC0);
  AT91C_BASE_AIC->AIC_IECR |= (1<<AT91C_ID_TC0);
  //AT91C_BASE_AIC->AIC_ISCR = (1<<AT91C_ID_TC0);
  ctl_global_interrupts_enable();
   //*/

  AT91C_BASE_PMC->PMC_PCER |= (1<<AT91C_ID_TC0);
  AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//запуск таймера
}

int init( void )
{
  int i;
  AT91PS_PMC pPMC = AT91C_BASE_PMC;
  AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
  pPMC->PMC_MOR = 1;//(( AT91C_CKGR_OSCOUNT & (0x06 <<8) | AT91C_CKGR_MOSCEN ));
  // Wait the startup time
  while(!(pPMC->PMC_SR & AT91C_PMC_MOSCS));

  pPMC->PMC_PLLR = ((AT91C_CKGR_DIV & 14) | (AT91C_CKGR_PLLCOUNT & (10<<8)) |    (AT91C_CKGR_MUL & (72<<16)));
  // Wait the startup time (until PMC Status register LOCK bit is set)
  while(!(pPMC->PMC_SR & AT91C_PMC_LOCK));

  pPMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2 | 1;
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

  pPMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK;
  while(!(pPMC->PMC_SR & AT91C_PMC_MCKRDY));

  //*******************
  i=AT91C_PMC_PCK0 | AT91C_PMC_PCK;
  *AT91C_PMC_SCER = i;
  *AT91C_PMC_SCDR = ~i;

  pPMC->PMC_PCKR[0]=0x00000015;
  while( !(pPMC->PMC_SR & AT91C_PMC_PCK0RDY) );

  //**************************************************
  pPMC->PMC_IER=0xffffffff;
  pPMC->PMC_SCER=0xffffffff;

  i=(1 << AT91C_ID_PIOB) | (1 << AT91C_ID_US1);
  pPMC->PMC_PCER = i;
  pPMC->PMC_PCDR = ~i;
  //**************************************************

  volatile AT91PS_PIO pPIO = AT91C_BASE_PIOB; // pointer to PIO data structure

  pPIO->PIO_OWER = LED_MASK | PB20_PIN_MASK;
  pPIO->PIO_PER = LED_MASK | PB20_PIN_MASK;
  pPIO->PIO_PPUDR = LED_MASK | PB20_PIN_MASK; //disabele pull-up on PB19
  pPIO->PIO_OER = LED_MASK | PB20_PIN_MASK; //enable output on PB19
  pPIO->PIO_CODR = LED_MASK | PB20_PIN_MASK;
  pPIO->PIO_ASR=0;
  pPIO->PIO_BSR=0;    
    
  init_timer();

  return 0;
}

int main( void ) //************************* M A I N ******************************
{

  init();
  led_off();

  while(1)  //********************** W H I L E ******************************
  {
    //;
    /*if( (AT91C_BASE_TC0->TC_SR & AT91C_TC_CPCS) )
//если постоянно читать флаг , все работает как нуно( переключение сигнала с нужным переудом)
     {
       led_tgl();
       *AT91C_AIC_ICCR = 0;//AT91C_TC_CPCS;
       AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;//перезапуск таймера
      }//*/
  }//while 1

  return -1;
}

код приведен не полностью , только самое важное.

Сообщение отредактировал RuZaKi - Mar 12 2008, 12:18
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
aaarrr
сообщение Mar 12 2008, 12:07
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Код
void timer_tick10ms(void)

У Вас прерывание сделано как простая функция.
Go to the top of the page
 
+Quote Post
RuZaKi
сообщение Mar 12 2008, 12:14
Сообщение #3





Группа: Новичок
Сообщений: 5
Регистрация: 12-03-08
Пользователь №: 35 833



забыл вставить в самом верху есть строка
Код
void timer_tick10ms(void) __attribute__ ((interrupt));


Сообщение отредактировал RuZaKi - Mar 12 2008, 12:18
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 12 2008, 12:24
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Брр. Много лишних и непонятных телодвижений. Попробуйте код из соседней ветки - он точно работает.
Go to the top of the page
 
+Quote Post
RuZaKi
сообщение Mar 12 2008, 12:59
Сообщение #5





Группа: Новичок
Сообщений: 5
Регистрация: 12-03-08
Пользователь №: 35 833



этот код не робит , да помоему он и не полный(для настройки прерывания от таймера).
Нуно же еще настраивать разрешение на прерывание - AIC_IECR, а как же остальные настройки типо
TC_BMR, TC_BCR и т.п.

+ не до конца ясно что должно быть обязательно в функции прирывания, типо обнуление AIC_EOICR , считывание в пустую регистр статуса таймера. Можете поподробнее это расписать.

Приведите плиз полный код для настройки прирываний от таймера.

Сообщение отредактировал RuZaKi - Mar 12 2008, 13:00
Go to the top of the page
 
+Quote Post
KAlex
сообщение Mar 12 2008, 13:15
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 387
Регистрация: 20-12-06
Из: Obninsk
Пользователь №: 23 719



Цитата(RuZaKi @ Mar 12 2008, 15:59) *
Приведите плиз полный код для настройки прирываний от таймера.


void InitTimerInt(void) {
unsigned int dummy;
AT91C_BASE_PMC -> PMC_PCER = 1 << AT91C_ID_TC0;//Enable the clock of the timer0 module ([PMC_PCER]: id = 12)
AT91C_BASE_TC0 -> TC_CCR = AT91C_TC_CLKDIS; //Disable clock [TC_CCR\CLKDIS {p366}] =1
AT91C_BASE_TC0 -> TC_IDR = 0x000000FF;//Disable all interrupts[TC_IDR {p379}]
dummy = AT91C_BASE_TC0 -> TC_SR;//Clear all status by read [TC_SR {p376}]
dummy=dummy;
AT91C_BASE_TC0 -> TC_CMR = AT91C_TC_CLKS_TIMER_DIV5_CLOCK | AT91C_TC_CPCTRG;
AT91C_BASE_TC0 -> TC_CCR = AT91C_TC_CLKEN; //Enable clock [TC_CCR\CLKEN {p366}] =1
AT91C_BASE_TC0 -> TC_RC = 937;//Period/MCK/1024 = 46875 (48 MHz / 1024 / 46875 = 1 sec)
void (*handler)(void);
handler = timer0_irq_handler;
AT91C_BASE_AIC -> AIC_IDCR = (1 << AT91C_ID_TC0);//Disable the interrupt on the interrupt controller
AT91C_BASE_AIC -> AIC_SVR[AT91C_ID_TC0] = (unsigned int)handler;//Interrupt handler routine pointer
AT91C_BASE_AIC -> AIC_SMR[AT91C_ID_TC0] = (2 << 0)|(5 << 5);//(priority =1);[AIC_SMR\SRCTYPE]=0 (Level sensitive)
AT91C_BASE_AIC -> AIC_ICCR = (1 << AT91C_ID_TC0);//[AIC_ICCR\PID12 {p146}]Clear the interrupt
AT91C_BASE_TC0 -> TC_IER = AT91C_TC_CPCS; //[TC_IER\CPCS[4]]=1 (RC Compare IRQ enable)
AT91C_BASE_AIC ->AIC_IECR = (1<<AT91C_ID_TC0);//Interrupt enable [AIC_IECR\PID12 {p145}]=1
AT91C_BASE_AIC -> AIC_ISCR = (1 << AT91C_ID_TC0);//Generate interrupt by software [AIC_ISCR\PID12 {p147}]=1
AT91C_BASE_TC0 -> TC_CCR = AT91C_TC_SWTRG;//Start timer [TC_CCR\SWTRG {p366}] =1
}

void timer0_irq_handler(void){
unsigned int dummy;
dummy = AT91C_BASE_TC0 -> TC_SR;//Acknowledge interrupt status
dummy = dummy;//Suppress warning <<variable "dummy" was set but never used>>
.
.
.
AT91C_BASE_AIC -> AIC_EOICR = AT91C_ID_TC0;
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 12 2008, 14:33
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(RuZaKi @ Mar 12 2008, 15:59) *
этот код не робит , да помоему он и не полный(для настройки прерывания от таймера).
Нуно же еще настраивать разрешение на прерывание - AIC_IECR, а как же остальные настройки типо
TC_BMR, TC_BCR и т.п.

Угу, IECR отсутствует - вырывал из живого проекта, а там он включается в другом месте.
Код
AT91C_BASE_AIC->AIC_IECR = (0x01 << AT91C_ID_TC0);


Какой смысл писать BMR и BCR, если использованы внутренние клоки и таймеры используются независимо?

Цитата(RuZaKi @ Mar 12 2008, 15:59) *
+ не до конца ясно что должно быть обязательно в функции прирывания, типо обнуление AIC_EOICR , считывание в пустую регистр статуса таймера. Можете поподробнее это расписать.

Приведите плиз полный код для настройки прирываний от таймера.

Вы сами и написали все, что нужно для прерывания - чтение SR и запись EOICR.
Go to the top of the page
 
+Quote Post
Kirill Frolov
сообщение Mar 12 2008, 18:39
Сообщение #8


Частый гость
**

Группа: Новичок
Сообщений: 111
Регистрация: 10-02-07
Из: St.Petersburg, Russia
Пользователь №: 25 241



Цитата(aaarrr @ Mar 12 2008, 15:07) *
Код
void timer_tick10ms(void)

У Вас прерывание сделано как простая функция.


У меня все прерывания сделаны как простыв функции -- и это работает... Что я делаю не так? ©
Нет, есть конечно ассемблерный кусок для вектора IRQ...

Вдогонку. Проблемы с подачей клока на нужный модуль MCU, правильное программирование вектора и разрешение прерывания в AIC -- это основное.

Сообщение отредактировал Kirill Frolov - Mar 12 2008, 18:41


--------------------
[ZX]
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Mar 12 2008, 19:33
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Kirill Frolov @ Mar 12 2008, 21:39) *
У меня все прерывания сделаны как простыв функции -- и это работает... Что я делаю не так? ©
Нет, есть конечно ассемблерный кусок для вектора IRQ...

У меня тоже, только куски на каждое прерывание свои.

Просто так как решение не очевидное, нужно явно и подробно все описывать. С телепатией далеко не у всех хорошо дела обстоят.
Go to the top of the page
 
+Quote Post
RuZaKi
сообщение Mar 13 2008, 09:04
Сообщение #10





Группа: Новичок
Сообщений: 5
Регистрация: 12-03-08
Пользователь №: 35 833



KAlex спасибо большое за код , ЗАРАБОТАЛО (после подрисовки ctl_global_interrupts_enable()wink.gif.
Ни ужели все дело в последовательности команд(своибразный танец с бубном)?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 12:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01472 секунд с 7
ELECTRONIX ©2004-2016