Тактовая частота периферийных устройств PCLK устанавливается с помощью регистров PCLKSEL0 и PCLKSEL1, и для упрощения настройки микроконтроллера она может быть выбрана равной частоте генератора на кварцевом резонаторе. Для этого должны быть запрограммированысоответствующие регистры (будут использованы в дальнейшем в функции main). Через регистр SCS необходимо разрешить работу генератора на кварцевом резонаторе:
SCS |= 0x20; // Разрешить генератор с кварцевым резонатором 12МГц
while( !(SCS & 0x40) ); //Подождать стабилизации частоты генератора
При этом системная тактовая частота CCLKбудет 12МГц. Затем через регистр PCLKSEL0 необходимо установить делитель частоты для таймера. Для таймера Т0 за это отвечают биты 3:2. Их значение определяется следующим образом:
Биты 3:2 |
Коэффициент деления |
00 |
PCLK = CCLK/4 |
01 |
PCLK = CCLK |
10 |
PCLK = CCLK/2 |
11 |
PCLK = CCLK/8 |
Следовательно, для использования частоты 12МГц без дополнительного деления необходимо выбрать комбинацию 01 и запрограммировать регистр:
PCLKSEL0 = 0x0004; // 0000 0100 - двоичный вид комбинации 01 для разрядов 3:2
В дальнейшем можно настроить таймер на генерацию прерываний с частотой 10Гц. Для этого необходимо разрешить прерывания от таймера и установить коэффициент деления 1200000 поскольку тактовая частота таймера 12000000 (12000000/1200000 = 10). Для инициализации таймера необходимо использовать соответствующую функцию:
void InitTimer0()
{
T0TCR &= ~0x01;// Запретить таймер
T0IR = 0x01; //Конфигурация регистра прерываний
T0CTCR = 0;//Конфигурация регистра управления
T0PC = 0; //Конфигурация регистра предделителя
T0MR0 = 1200000;//Конфигурация регистра сравнения
//частота PCLK = 12 МГц
//делится на T0MR0 и дает частоту прерываний 10Гц
T0MCR = (0x01 | 0x02); //Конфигурация регистра управления режима сравнения
InstallIRQ( TIMER0_INT, (void *)TimerHandler0, 0x03 );
T0TCR |= 0x01;// Разрешить таймер
}
Функция InstallIRQ() использовалась в предыдущей работе и предназначена для инициализации прерываний от различных периферийных устройств. В данном случае необходимо установить функцию прерывания от таймера TimerHandler0:
__irq __nested __arm voidTimerHandler0()
{
T0IR = 0x01;
VICADDRESS = 0; //Сброспрерывания
FIO2PIN = !FIO2PIN; //Инвертироватьсветодиоды
}
В данной функции при каждом вызове (возникновении прерывания 10 раз в секунду) происходит инвертирование состояния светодиодов. Таким образом, светодиоды должны мигать с частотой 5Гц.
Выполнение определенных действий непосредственно в обработчике прерываний не всегда оптимально. В таком случае можно воспользоваться дополнительной глобальной переменной – флагом события прерывания от таймера:
char T0_event; //Глобальная переменная - флаг события прерывания от таймера
int main (void)
{
. . .//Инициализация
while (1)//Loop forever
{
if( T0_event ) //Если прерывание случилось
{
T0_event = 0; //Сброс флага до следующего прерывания
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.