Примеры программирования
Nolist
.include "M103def.inc"
List
;Тест 1
; Исходные данные : 15 вывод (OCO1A/PB5) МК настраивается на обычный выход (внешне подключен светодиод катодом к "Земле" ),
; 9 вывод МК как вход (внешне подключена кнопка со схемой подавления дребезга, на выводе уровень лог1
; при нажатой кнопке)
;После включения питания МК переходит на программный опрос 9 вывода с постоянной задержкой между моментами начала каждого очередного
;опроса. Состояние вывода отображает на 15-м. Таким образом, светодиод для глаз будет гореть столько времени, сколько будет нажата кнопка.
.equ ck1024 = 7;
.def temp =r16 ;Регистр временного хранения
.def temp2 =r17 ;
.def count =r19 ;Счетчик
.def S1 =r20 ;
.def S2 =r21 ;
.def timer0 =r24 ; флаг - таймер0 в работе - должен инкрементироваться
;сегмент кода
.cseg ;
.org 0 ;
Rjmp begin_ ;передать управление на начало основной программы
Org OVF0addr
Rjmp TIM0_OVF ;передать управление на обработку прерывания от таймера
Org 0x0030
Begin_: cli
;Организовать программный стек в конце сегмента SRAM
Ldi temp,low(RAMEND)
Out SPL,temp
Ldi temp,high(RAMEND)
Out SPH,temp
;Инициализировать PORTB (РВ5 - выдача, остальные прием)
In temp,low(PORTB) ;read PORTB latch
sbr temp,(1<<PB5) ;set PB5
Out low(PORTB),temp ;output to PORTB
Clr temp
sbr temp,(1<<PB4) ;set PB4
sbr temp,(1<<PB5) ;set PB5
Out low(DDRB),temp ; Set port B(5) as output
;Инициализировать PORTЕ (все на прием)
In temp,low(PORTE) ;read PORTE latch
sbr temp,(1<<PE7) ;set PE7
Out low(PORTE),temp ;output to PORTE
Clr temp
Out low(DDRE),temp ; Set port E as input
;Инициализировать локальные переменные
Ldi count,low(0xcc)
Clc
;Запрограммировать таймер0
;TCCR0 : -,PWM0,COM01,COM00,CTC0,CS02,CS01,CS00
; 0 0 0 1 0 1 1 1
ldi temp,(ck1024+0x10)
out low(TCCR0),temp ;
; CK/1024 ASSR = 0<<AS0
in temp,low(ASSR) ;
cbr temp,(1<<AS0)
out low(ASSR),temp ;
;TCNT0 = 0
Ldi temp,0
out low(TCNT0),temp ;
;OCR0 = 128
Ldi temp,0x7
out low(OCR0),temp ;
;Очистить флаг переполнения таймер0
In temp,low(TIFR)
sbr temp,(1<<TOV0)
Out low(TIFR),temp
; ожидать установку 0 в ASSR[2-0]
wait_0:
in temp,low(ASSR) ;
Andi temp,0x7
Brne wait_0
;Разрешить прерывание от таймера0
In temp,low(TIMSK)
sbr temp,(1<<TOIE0)
Out low(TIMSK),temp
;Разрешить все прерывания
Sei
;Рабочий цикл -
cicle_:
; rcall delay_
;cont_:
Rjmp cicle_ ;Повторить бесконечно
Quit: rjmp quit
;Процедуры
set_pb5:
Push temp
In temp,low(PORTB) ;read PORTB latch
sbr temp,(1<<PB5) ;set PB5
Out (PORTB),temp ;output to PORTB
Pop temp
Ret
clr_pb5:
Push temp
In temp,low(PORTB) ;read PORTB latch
cbr temp,(1<<PB5) ;clear PB5
Out low(PORTB),temp ;output to PORTB
Pop temp
Ret
;Пауза
delay_:
Push temp
In temp,low(SREG) ;Cохранить системные регистр
Push temp ;Сохранить его в стеке
Ldi temp,1
Dell0: clr temp2
Dell1: dec temp2
Brne dell1
Dec temp
Brne dell0
Pop temp
Out low(SREG),temp ;Все вернуть
Pop temp
Ret
;Обработчик прерывания по переполнению таймера0
;Отобразить состояние РЕ7 на выход РВ5
TIM0_OVF: in S1,low(SREG)
In count,low(PINE)
sbrc count, PE7 ;
Rcall set_pb5
sbrs count, PE7 ;
Rcall clr_pb5
Adiw timer0,1 ; количество прерываний
Out low(SREG),S1
Reti
;***************************************************************************
Nolist
.include "M103def.inc"
List
rjmp begin_ ;
;***************************************************************************
;* Работа с внутренней памятью.
;* Обеспечивает копирование блока внутренней памяти программ во внутреннюю SRAM
;* Затем выполняет перезапись участка внутренней памяти во внешнюю
;* Затем выполняет считывание из внешней памяти и сравнение с внутренней
;* Если сравнение проходит успешно то зажигает светодиод (постоянное свечение)
;* Если сравнения нет (хотя бы одна ошибка), то светодиод переходит в мигающий режим
;* Z-pointer: Используется для задания стартового адреса Flash-блока ( start address x 2, тип слово)
;* Y-pointer: Используется для задания стартового адреса памяти SRAM
;* X-pointer: Используется для задания стартового адреса памяти XRAM (внешней расширенной памяти)
;* romsize: Размер блока внешней памяти
;*
;***************************************************************************
;***** Подпрограмма копирования блока из ФЛЕШ в SRAM
.def flashsize=r16 ;размер блока для копирования
.def temp =r18 ;
.def temp1 =r19 ;
.def temp2 =r20 ;
.def ramtemp =r1 ;
.def ramsize =r17 ;
;****************************************************************************
;*
;* Попрограмма копирования size байт из PM в SRAM , из SRAM в XRAM
;*
;****************************************************************************
.equ SIZE = 20
.equ BLOCK1 =$100 ;начальный адрес области в SRAM
.equ BLOCK2 =$7010 ;начальный адрес области в XRAM
.equ SRAMEND = 4096-2
;***** Main Program Register variables
.org $30
begin_:
;Организуем программный стек в конце сегмента SRAM
Ldi r21,1
Ldi temp,low(SRAMEND)
Out SPL,temp
Ldi temp,high(SRAMEND)
Out SPH,temp
In temp,PORTB ;read PORTB latch
sbr temp,(1<<PB4) ;set PB4
Out PORTB,temp ;output to PORTB
Clr temp
sbr temp,(1<<PB4) ;set PB4
Out DDRB,temp ; Set port B(4) as output
;***** рарешить использование XRAM( MCUCR |= 0xc0 -- SRE=1, SRW = 0 без ВСТАВКИ ТАКТА ОЖИДАНИЯ)
In temp,low(MCUCR) ;read MCUCR
sbr temp,(1<<SRE) ;set SRE
cbr temp,(1<<SRW) ;clear SRW
Out low(MCUCR),temp ;output to MCUCR
Rcall SetLed
CopyBlock:
;***** ROM -> SRAM
ldi ZH,high(F_TABLE*2)
ldi ZL,low(F_TABLE*2);
Ldi YH,high(BLOCK1)
ldi YL,low(BLOCK1) ;
Ldi flashsize,SIZE
rcall flash2ram ;
;***** SRAM -> XRAM
Ldi ZH,high(BLOCK1)
ldi ZL,low(BLOCK1) ;
ldi YH,high(BLOCK2) ;
ldi YL,low(BLOCK2) ;
Ldi ramsize,SIZE
rcall ram2ram ;
; ldi ZH,high(F_TABLE*2);
; ldi ZL,low(F_TABLE*2);
; ldi YH,high(BLOCK2) ;
; ldi YL,low(BLOCK2) ;
; ldi ramsize,SIZE
; clr temp1
; rcall cmpromram
; or temp1,temp1
;Cont1:
; breq Cont
Rcall SetLed
Rcall delay_
Rcall ClearLed
Rcall delay_
; dec temp1
; rjmp Cont1
;Cont:
Rjmp CopyBlock
Forever:rjmp forever
SetLed:
Push temp
In temp,PORTB ;read PORTB latch
sbr temp,(1<<PB4) ;set PB4
Out PORTB,temp ;output to PORTB
Pop temp
Ret
ClearLed:
Push temp