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

 
 
> Счётчики в atmega128
Fly-away
сообщение Oct 15 2006, 09:56
Сообщение #1





Группа: Новичок
Сообщений: 3
Регистрация: 4-09-06
Пользователь №: 20 077



Какой счётчик оптимально использовать для задач порядка "помигать лампочками"?
1 и 3 16-тиразрядные, там какие-то заморочки с загрузкой регистров, 0-ой и 2-ой 8-миразрядные, но умеют ШИМ и кажется не для того предназначены. Разрешите дилемму %)
Если у кого есть кусок кода - вообще шоколадно.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 3)
psw
сообщение Oct 15 2006, 10:40
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 16
Регистрация: 8-06-06
Пользователь №: 17 866



Цитата(Fly-away @ Oct 15 2006, 14:56) *
Какой счётчик оптимально использовать для задач порядка "помигать лампочками"?
1 и 3 16-тиразрядные, там какие-то заморочки с загрузкой регистров, 0-ой и 2-ой 8-миразрядные, но умеют ШИМ и кажется не для того предназначены. Разрешите дилемму %)
Если у кого есть кусок кода - вообще шоколадно.


Использовать можно любой, все зависит от того как часто тебе нужно мигать лампочками, хотя и это не принципиально...........


void init_devices( void )
{
_CLI(); //disable all interrupts
port_init();
timer0_init();

MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x01; //timer interrupt sources
_SEI(); //re-enable interrupts
}
//**********************************************************
//TIMER0 initialize - prescale:64
// desired value: 1mSec
void timer0_init( void )
{
TCCR0 = 0x00; //stop
TCNT0 = 0xC2; //set count
TCCR0 = 0x03; //start timer
}
//**********************************************************
#pragma vector=TIMER0_OVF_vect
__interrupt void TIMER0_OVF0( void )
{
if( tic < 0xff )
tic++;
TCNT0 = 0xC2; //reload counter value
}
//**********************************************************
void main( void )
{
init_devices();

while( 1 )
{
// твой код.......
}
}

используется 0-й таймер, каженся писал для меги 8535, писал в IAR, в основной программе слежу
за переменной tic которая увеличивается на единицу каждую mSec, а дальше от фантазии и поставленной задачи
Go to the top of the page
 
+Quote Post
Леонид Иванович
сообщение Oct 15 2006, 19:45
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 318
Регистрация: 21-07-06
Из: Минск
Пользователь №: 18 986



Код
;----------------------------------------------------------------------------

;Программа мигания двумя светодиодами
;Микроконтроллер: AT90S2313
;Частота кварца: 10 МГц

;----------------------------------------------------------------------------

.include "2313def.inc"       ;подключаем файл описания регистров

;----------------------------------------------------------------------------

;Константы:

.equ    FCLK = 10000000       ;тактовая частота, Гц
.equ    TSYS = 10000       ;системный квант времени, мкс

.equ    LED1_ON  = 500       ;время работы светодиода 1, мс
.equ    LED1_OFF = 500       ;время паузы светодиода 1, мс
.equ    LED2_ON  = 100       ;время работы светодиода 2, мс
.equ    LED2_OFF = 1900       ;время паузы светодиода 2, мс

;----------------------------------------------------------------------------

;Вычисляемые константы:

.equ MAXWORD = 0xFFFF
.equ MAXBYTE = 0xFF

.equ T1PRE = 8;перскалер таймера 1
.equ T1VAL = (((FCLK/T1PRE/1000*TSYS)/100)+5)/10

.if T1VAL > MAXWORD       ;проверка значения константы T1VAL
.error "out of range constant"
.endif

;----------------------------------------------------------------------------

;Перевод времени в миллисекундах в системные тики:

#define ms2sys(X) X*1000/TSYS

;----------------------------------------------------------------------------

;Определение портов:

#define PORT_LED1 PORTB,PB0;светодиод 1 подключен к выводу PB0
#define    PORT_LED2 PORTB,PB1;светодиод 2 подключен к выводу PB1

;----------------------------------------------------------------------------

;Глобальные регистровые переменные:

.def    temp    = r16       ;временный регистр temp
.def    tempA    = r17       ;временный регистр tempA
.def    tempB    = r18       ;временный регистр tempB

;----------------------------------------------------------------------------

.DSEG   ;сегмент данных

TickCnt: .byte 1;переменная счетчика "тиков" (системное время)

;Для однобайтного счетчика "тиков" максимальный интервал (интервал)
;переполнения равен 256*TSYS. Например, если TSYS = 10 мс, то максимальный
;интервал равен 2.56 секунды. Если надо больше, нужно или увеличить
;квант времени TSYS, или сделать счетчик "тиков" большей разрядности.

;----------------------------------------------------------------------------

.CSEG   ;сегмент кода

;----------------------------------------------------------------------------

;Векторы прерываний:

.org    0           ;по адресу 0 вектор сброса
    rjmp    Init       ;переход на основную программу

.org    OC1addr           ;по адресу OC1addr вектор прерывания по
    rjmp    Timer       ;совпадению таймера 1

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Программа начинает выполняться отсюда:
;Здесь пишем всякую инициализацию, которая должна
;выполняться один раз при старте программы.

Init:    ldi    temp,RAMEND   ;константа RAMEND определена в 2313def.inc
    out    SPL,temp   ;инициализируем стек

;Настройка портов:
    
    ldi    temp,0xFF   ;загружаем в temp FF    
    out    DDRB,temp   ;настраиваем порт B на вывод
    out    DDRD,temp   ;настраиваем порт D на вывод

;Настройка оборудования (таймера 1):

    ldi    temp,0x00
    out    TCCR1A,temp   ;OC и PWM запрещены

    ldi    temp,(1<<CTC1) | (1<<CS11)    
    out    TCCR1B,temp   ;очистка при совпадении, CK/8

    ldi    temp,high(T1VAL-1);загрузкарегистра сравнения
    out    OCR1AH,temp    
    ldi    temp,low(T1VAL-1)
    out    OCR1AL,temp

    ldi    temp,(1<<OCIE1A)
    out    TIFR,temp   ;очистка флага прерывания
    out    TIMSK,temp   ;разрешение прерывания по совпадению

    sei           ;общее разрешение прерываний:
            
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Инициализация процессов:

    rcall    Process1_Init   ;инициализация процесса 1
    rcall    Process2_Init   ;инициализация процесса 2

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Основной цикл программы (выполнение процессов):
    
Main:    rcall    Process1_Execute;выполнение процесса 1
    rcall    Process2_Execute;выполнение процесса 2
    rjmp     Main        ;цикл

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Обработчик прерывания по совпадению регистра сравнения
;и содержимого таймера 1:
    
Timer:    push    temp       ;сохранение регистра temp
    in    temp,SREG   ;temp <- SREG
    push    temp       ;сохранение SREG

    lds    temp,TickCnt   ;загружаем в temp значение TickCnt
    inc    temp       ;наращиваем значение
    sts    TickCnt,temp   ;сохраняем новое значение
        
Ovf:    pop    temp       ;восстановление SREG
    out    SREG,temp   ;SREG <- temp
    pop    temp       ;восстановление регистра temp
    reti           ;выход из обработчика и разрешение прерываний

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Процесс 1:

;Объявляем необходимые переменные:

.DSEG   ;сегмент данных

Led1Tm: .byte 1;время изменения состояния светодиода 1 (1 байт)

;Дальше будет код процесса:

.CSEG

;----------------------------------------------------------------------------

;Инициализация процесса:
;Инициируем включение светодиода без задержки.

Process1_Init:

    lds    temp,TickCnt
    subi    temp,ms2sys(LED1_OFF)
    sts    Led1Tm,temp
    ret

;----------------------------------------------------------------------------

;Выполнение процесса:

Process1_Execute:

    lds    tempA,TickCnt   ;чтение системного времени
    lds    tempB,Led1Tm   ;чтение времени предыдущего переключения
    mov    temp,tempA
    sub    temp,tempB   ;вычисляем, сколько времени прошло

    sbis    PORT_LED1   ;проверяем состояние порта светодиода
    rjmp    On1       ;если был выключен, переход на включение

;Выключение светодиода 1:

Off1:    subi    temp,ms2sys(LED1_ON);прошло время LED1_ON?
    brcs    Pret1       ;если нет, ничего не делаем, выход
    cbi    PORT_LED1   ;если да, выключаем светодиод
    sts    Led1Tm,tempA   ;и сохраняем время выключения
    rjmp    Pret1       ;выход

;Включение светодиода 1:

On1:    subi    temp,ms2sys(LED1_OFF);прошло время LED1_OFF?
    brcs    Pret1       ;если нет, ничего не делаем, выход
    sbi    PORT_LED1   ;если да, включаем светодиод
    sts    Led1Tm,tempA   ;и сохраняем время включения
Pret1:    ret           ;выход

;----------------------------------------------------------------------------
;----------------------------------------------------------------------------

;Процесс 2:

;Объявляем необходимые переменные:

.DSEG   ;сегмент данных

Led2Tm: .byte 1;время изменения состояния светодиода 2 (1 байт)

;Дальше будет код процесса:

.CSEG

;----------------------------------------------------------------------------

;Инициализация процесса:
;Инициируем включение светодиода без задержки.

Process2_Init:

    lds    temp,TickCnt
    subi    temp,ms2sys(LED2_OFF)
    sts    Led2Tm,temp
    ret

;----------------------------------------------------------------------------

;Выполнение процесса:

Process2_Execute:

    lds    tempA,TickCnt   ;чтение системного времени
    lds    tempB,Led2Tm   ;чтение времени предыдущего переключения
    mov    temp,tempA
    sub    temp,tempB   ;вычисляем, сколько времени прошло

    sbis    PORT_LED2   ;проверяем состояние порта светодиода
    rjmp    On2       ;если был выключен, переход на включение

;Выключение светодиода 2:

Off2:    subi    temp,ms2sys(LED2_ON);прошло время LED2_ON?
    brcs    Pret2       ;если нет, ничего не делаем, выход
    cbi    PORT_LED2   ;если да, выключаем светодиод
    sts    Led2Tm,tempA   ;и сохраняем время выключения
    rjmp    Pret2       ;выход

;Включение светодиода 2:

On2:    subi    temp,ms2sys(LED2_OFF);прошло время LED2_OFF?
    brcs    Pret2       ;если нет, ничего не делаем, выход
    sbi    PORT_LED2   ;если да, включаем светодиод
    sts    Led2Tm,tempA   ;и сохраняем время включения
Pret2:    ret           ;выход

;----------------------------------------------------------------------------


--------------------
Go to the top of the page
 
+Quote Post
defunct
сообщение Oct 15 2006, 21:05
Сообщение #4


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Fly-away @ Oct 15 2006, 12:56) *
Разрешите дилемму %)

Я бы для такого класса задач использовал бы 8-ми разрядный, т.к. 16-ти разрядные деффицит.. Ну и приоритет чтобы был поменьше - тобиш Tim0. Либо воткнул бы задачу часов на OVF Tim3 наинизший приоритет.
Go to the top of the page
 
+Quote Post

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

 


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


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