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

 
 
> Timer/Counter не выдает тактовый сигнал в режиме генератора, at91sam7s256
Bulat
сообщение Sep 28 2009, 10:20
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Мне необходимо сконфигурировать таймер TC0 в режиме генератора, чтобы он выдавал на выводе TIOA тактовый сигнал с частотой 100 кГц. Прерывание должно вызываться при равенстве значения счетчика числу, записаному в регистр RA. Частота синхронизации MCK\8,то есть 48МГц\8 = 6 МГц.
Ниже приведен код инициализирующий таймер. Прерывание вызывается (лампочка моргает), но на выходе TIOA нет тактового сигнала! Тактирование этого таймера в PMC разрешил, в контролере PIO даный вывод также разрешил управлять переферией. Почему нет сигнала?
Структура с настройками таймера
Код
typedef struct _AT91S_MIPS_TIMER {
unsigned int     Id;
unsigned short    RA_100;
unsigned short    RC_100;
unsigned char    Div;
} AT91S_MIPS_TIMER, *AT91PS_MIPS_TIMER;

Заполнение полей структуры
Код
#define TC_CLKS_MCK8             0x1
const AT91S_MIPS_TIMER MipsTimer = { AT91C_ID_TC0,30,60,TC_CLKS_MCK8};


Разрешение выхода TIOA таймера TC0 в контроллере PIO
Код
void PIO_ini()
{
  regs->PIOA_PER = 0x1;
  regs->PIOA_PDR = ~0x1;
  regs->PIOA_BSR=0x1;
}

Инициализация таймера TC0
Код
void Init_Mips_Timer()
{
  //* Init timer interrupt

    AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC,1 << MipsTimer.Id);
    
    //* Disable the clock and the interrupts
    MipsTimerBase->TC_CCR = AT91C_TC_CLKDIS;
    MipsTimerBase->TC_IDR = 0xFFFFFFFF;
    
    dummy = MipsTimerBase->TC_SR;
    //* Suppress warning
    dummy=dummy;
    
    //* Set the Mode of the Timer Counter
    MipsTimerBase->TC_CMR = AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | MipsTimer.Div;
   //* open Timer 0 interrupt
    AT91F_AIC_ConfigureIt ( AT91C_BASE_AIC, MipsTimer.Id, TIMER_INTERRUPT_LEVEL,AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, timer0_irq_handler);
    MipsTimerBase->TC_IER = AT91C_TC_CPAS;                                      //Enable the RA Compare interrupt
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, MipsTimer.Id);
}

Запуск таймера
Код
void Start_Mips_Timer()
{
    //* Enable the clock and Start timer
        MipsTimerBase->TC_CCR = AT91C_TC_CLKEN;
        MipsTimerBase->TC_RA = MipsTimer.RA_100; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = MipsTimer.RC_100;
        MipsTimerBase->TC_CCR = AT91C_TC_SWTRG;                                
}

Обработка прерываний от таймера (при совпадении с RA)
Код
void timer0_irq_handler()
{
  //моргание лампочкой
  regs->PIOA_ODSR = 0x2;
  int ps=100000;
  while(ps!=0)ps--;
  regs->PIOA_ODSR = 0x0;

  dummy=dummy;
}
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 6)
aaarrr
сообщение Sep 28 2009, 11:35
Сообщение #2


Гуру
******

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



Цитата(Bulat @ Sep 28 2009, 14:20) *
Разрешение выхода TIOA таймера TC0 в контроллере PIO
Код
void PIO_ini()
{
  regs->PIOA_PER = 0x1;
  regs->PIOA_PDR = ~0x1;
  regs->PIOA_BSR=0x1;
}

В результате для PA0 выбран периферийный блок B, но сам вывод в режиме PIO.

Цитата(Bulat @ Sep 28 2009, 14:20) *
Обработка прерываний от таймера (при совпадении с RA)
Код
void timer0_irq_handler()
{
  //моргание лампочкой
  regs->PIOA_ODSR = 0x2;
  int ps=100000;
  while(ps!=0)ps--;
  regs->PIOA_ODSR = 0x0;

  dummy=dummy;
}

А здесь все вообще должно глухо зависнуть из-за отсутствия чтения TC_SR.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Sep 28 2009, 11:51
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Sep 28 2009, 17:35) *
В результате для PA0 выбран периферийный блок B, но сам вывод в режиме PIO.


А здесь все вообще должно глухо зависнуть из-за отсутствия чтения TC_SR.

Извините, это я тут перепутал, на самом деле в в прошивке у меня так:
Код
regs->PIOA_PER = 0x0;
  regs->PIOA_PDR = 0x1;
  regs->PIOA_BSR=0x1;

то есть PIO-контроллер у меня правильно настроен.
Цитата(aaarrr @ Sep 28 2009, 17:35) *
А здесь все вообще должно глухо зависнуть из-за отсутствия чтения TC_SR.

Так при инициализации таймера у меня же стоить присвоение dummy = MipsTimerBase->TC_SR;
поэтому в обработчике я уже просто пишу dummy = dummy; Разве при этом не происходит считывание из MipsTimerBase->TC_SR;?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 28 2009, 12:38
Сообщение #4


Гуру
******

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



Цитата(Bulat @ Sep 28 2009, 15:51) *
Так при инициализации таймера у меня же стоить присвоение dummy = MipsTimerBase->TC_SR;
поэтому в обработчике я уже просто пишу dummy = dummy; Разве при этом не происходит считывание из MipsTimerBase->TC_SR;?

Разумеется, нет.
И оставьте просто MipsTimerBase->TC_SR;, без всяких dummy.
Go to the top of the page
 
+Quote Post
Bulat
сообщение Sep 29 2009, 03:36
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Всеравно не удается добиться генерации сигнала на выходе TIOA, там только нулевой уровень. Хотя лампочка моргает (прерывания обрабатываются).
Запуск таймера
Код
void Start_Mips_Timer()
{
    //* Enable the clock and Start timer
        MipsTimerBase->TC_CCR = AT91C_TC_CLKEN;
        MipsTimerBase->TC_RA = MipsTimer.RA_100; MipsTimerBase->TC_RB = MipsTimerBase->TC_RC = MipsTimer.RC_100;
        MipsTimerBase->TC_CCR = AT91C_TC_SWTRG;  
        while(1);                            
}

Обработка прерываний от таймера (при совпадении с RA)
Код
void timer0_irq_handler()
{
  //моргание лампочкой
  regs->PIOA_ODSR = 0x2;
  int ps=10000;
  while(ps!=0)ps--;
  regs->PIOA_ODSR = 0x0;
  ps=100000;
  while(ps!=0)ps--;

  dummy=MipsTimerBase->TC_S;
}
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Sep 29 2009, 12:14
Сообщение #6


Гуру
******

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



Вообще-то вот такой нехитрый код замечательно выдает 100kHz на PA0 при 48MHz MCK:
Код
void tc0_init(void)
{
    *AT91C_PIOA_PDR = AT91C_PA0_TIOA0;
    *AT91C_PIOA_BSR = AT91C_PA0_TIOA0;

    *AT91C_PMC_PCER = 1UL << AT91C_ID_TC0;

    *AT91C_TC0_CMR = AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV2_CLOCK;
    *AT91C_TC0_RA = 29;
    *AT91C_TC0_RC = 59;
    *AT91C_TC0_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}
Go to the top of the page
 
+Quote Post
Bulat
сообщение Sep 30 2009, 05:02
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 206
Регистрация: 12-10-06
Из: ufa
Пользователь №: 21 241



Цитата(aaarrr @ Sep 29 2009, 18:14) *
Вообще-то вот такой нехитрый код замечательно выдает 100kHz на PA0 при 48MHz MCK:
Код
void tc0_init(void)
{
    *AT91C_PIOA_PDR = AT91C_PA0_TIOA0;
    *AT91C_PIOA_BSR = AT91C_PA0_TIOA0;

    *AT91C_PMC_PCER = 1UL << AT91C_ID_TC0;

    *AT91C_TC0_CMR = AT91C_TC_ASWTRG_CLEAR | AT91C_TC_ACPC_CLEAR | AT91C_TC_ACPA_SET | AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP_AUTO | AT91C_TC_CLKS_TIMER_DIV2_CLOCK;
    *AT91C_TC0_RA = 29;
    *AT91C_TC0_RC = 59;
    *AT91C_TC0_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
}

Когда я записал у себя *AT91C_TC0_RA = 29; *AT91C_TC0_RC = 59; сразу нашел ошибку, никак не связанную с инициализацией таймера. Спасибо за помощь!
Go to the top of the page
 
+Quote Post

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

 


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


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