19 августа 2012 г.

Первый блин на Tiny26

Моя первая программа на МК. Каждые 2 секунды меняет уровень на первом контакте порта A на противоположный. Так сказать, программа типа "помигать диодом".


.device ATiny26
.include "tn26def.inc"

.def Flag = r16
.def Temp = r17
.def Delay_count = r18

rjmp RESET ; Reset handler
reti ;rjmp EXT_INT0 ; IRQ0 handler
reti; rjmp PIN_CHANGE ; Pin change handler
reti; rjmp TIM1_CMP1A ; Timer1 compare match 1A
reti; rjmp TIM1_CMP1B ; Timer1 compare match 1B
reti; rjmp TIM1_OVF ; Timer1 overflow handler
rjmp TIM0_OVF ; Timer0 overflow handler
reti; rjmp USI_STRT ; USI Start handler
reti; rjmp USI_OVF ; USI Overflow handler
reti; rjmp EE_RDY ; EEPROM Ready handler
reti; rjmp ANA_COMP ; Analog Comparator handler
reti; rjmp ADC ; ADC Conversion Handler
;

TIM0_OVF:
    dec Delay_count
    breq END_TIMER
    reti

END_TIMER:
    clr Temp
    out TCCR0, Temp    ;stopping timer

    out PORTA, Flag

    ldi Temp, 0b00000001
    eor Flag, Temp

    rcall START_TIMER
    reti

RESET:
    ldi r16, RAMEND
    out SP, r16
    
    ;allow Timer0 interrupt
    ldi Temp, (1<<TOIE0)
    out TIMSK, Temp
    
    ;set all A port contacts to OUT mode
    ldi temp, 0b11111111
    out DDRA, temp

    clr Temp
    out PORTA, Temp

    clr Flag

    sei
    rcall START_TIMER

MAIN_CYCLE:
    rjmp MAIN_CYCLE


START_TIMER:
    ldi Delay_count, 128    ;(128*256*64) / 1000000 = 2,097s
    ldi Temp, 0b00000011    ;prescaler 1/64
    out TCCR0, Temp         ;start timer
    ret;

Таймер

Fuse биты я не программировал - оставил по умолчанию. А по умолчанию, согласно даташиту (раздел "Calibrated Internal RC Oscillator"), для МК установлена частота 1 МГц (CKSEL3...0 = 0001).

Таймер у меня работает от тактовой частоты МК, но с предделителем 1/64, т.е. на частоте 1/64  МГц. Таким образом, я могу создать задержку  0,016 - 4,194 с.

Я обрабатываю прерывание по переполнению таймера, поэтому таймер у меня всегда отсчитывает 256 промежутков. На самом деле я не уверен, 256 их или 255. Согласно моему представлению о работе таймера, промежуток 255 - 0 (переполнение) тоже следует учитывать. Таким образом, задержку я рассчитываю по формуле:
(число в доп. регистре * 256) / (частота * предделитель)

Например, для этой программы расчет такой:
(128 * 256) / (1000000Гц * 1/64) или (128 * 256 * 64) / 1000000 = 2,097с

С помощью только таймера на частоте 1 МГц можно создать задержку, величиной в 0,262 с = 262 мкс (табл. 1). Если дополнительно использовать ещё и регистр, то можно получить задержку 67,109 с (табл. 2).

Таблица 1. Частота 1 МГц, без использования доп. регистра.
Предделитель Задержка (с)
1 0,0002
1/8 0,002
1/64 0,016
1/256 0,066
1/1024 0,262

Таблица 2. Частота 1 МГц, с использования доп. регистра (8 бит).
Предделитель Задержка (с)
1 0,0002 - 0,066
1/8 0,002 - 0,524
1/64 0,016 - 4,194
1/256 0,066 - 16,777
1/1024 0,262 - 67,109

Предделитель для таймера с индексом 0 задается с помощью битов CS00..02 регистра TCCR0 (табл. 3). Запись значения, соответствующего предделителю, запускает таймер. Запись нулей в эти биты его останавливает.

Таблица 3.
CS02 CS01 CS00 Описание
0 0 0 Стоп (остановка таймера)
0 0 1 CK
0 1 0 CK/8
0 1 1 CK/64
1 0 0 CK/256
1 0 1 CK/1024
1 1 0 От внешнего источника (T0) по заднему фронту
1 1 1 От внешнего источника (T0) по переднему фронту
 CK - внутренний источник тактовой частоты.

Так это выглядит:
На фото есть лишние узлы. Вверху слева расположен стабилизатор напряжения +5В. Он рассчитан на входное напряжение 7-35В. Моя схема питается от 4-х батареек по 1,5В, т.е. напряжение питания 6В. При входном напряжении на стабилизаторе 6В на выходе получаем 4,3В. Это ниже необходимого уровня питания МК, однако данная программа нормально работает и в таком режиме. Также на схеме есть шлейф к программатору и 9 идущих от него проводов.

Так это работает:

Комментариев нет:

Отправить комментарий