Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт дек 03, 2010 11:45:26
спасибо вам, GP1 
Здесь можно немножко помяукать :)
https://radiokot.ru/forum/
Код: Выделить всё
.def n=r17
.def tmp=r16
...
ldi ZL,low(buff1)
ldi ZH,high(buff1)
ldi YL,low(buff2)
ldi YH,high(buff2)
;***************************
ldi n, 0x0A
NEXT:
ld tmp,Z+
st Y+,tmp
dec n
brne NEXT
....
;***************************
.dseg
buff1: .byte 10
buff2: .byte 10
Код: Выделить всё
timer_0_ovf:
lpm temp,z+
cpi temp,0b01101111 ;проверка с девяткой
breq init ;инициализирую начало матрици
sei ;разрешение прерывания для срабатывания таймера
rjmp inf2 ;переход на бесконечный вывод
Код: Выделить всё
.org 0x0070
deci_s:.Byte 1; Десятки секунд
.org 0x0071
second:.Byte 1;Единицы секунд
.....
.....
lpm temp,z+; Читаем данные
.....
andi zl, 0x01; Очищаем старшие биты
Код: Выделить всё
.def sec = r17
.def deci_s = r18
.....
timer_0_ovf:
lpm sec,z+
cpi temp,0b01101111 ;проверка с девяткой
breq init ;инициализурую начало матрици
;;Вот здесь надо как-то сохранить указатель секунд;;
lpm deci_s,z ;(z+?) ;гружу значения для 2 индикатора
;;Загрузхить значение указателя для десяток. При этом если в предыдущем сравнении небыло правды, то не увеличивать указатель;;
cpi temp,0b01101111 ;проверка с девякой
breq init ;инициализурую начало матрици
;;Сохранить указатель для десяток секунд. Вернуть указатель для секунд;;
rjmp inf2 ;переход на бесконечный вывод
inf2:
out portb,sec
ldi temp,0b00000001
out portc,temp
;rcall delay ;возможность регулировки частоты
out portb,deci_s
ldi temp,0b00000010
out portc,temp
;rcall delay
sei ;разрешение прерывания для срабатывания таймера
rjmp inf2 ;жду следующего прерывания по таймеру
Код: Выделить всё
lpm temp, z+На какой плате? При чём тут АСМ?Necroteeth писал(а):не могли бы опытные коты ответить мне, правильно сделаны соединения на плате или нет?
Платы я не вижу до сих пор. Ресет через 10 кОм на "+" питания, через 0,1 мкФ на "-" питания. "-" питания - GND, "+" питания - Vсс.Necroteeth писал(а):плата самодельная
.device ATmega16
.nolist
.include "D:\Program Files\Atmel\AVR Studio\Appnotes\m16def.inc"
.list
;********************************
;определяем переменные
;рабочие:
.def work=r16
.def work1=r17
.def h_part=r19
.def l_part=r20
.def t_count1_L=r21
.def count1_symbol=r22
.def t_count0=r23
.def t_count1_H=r24
.def speed_value=r25
.def speed_value_1=r26
.def BLDC_cnt=r27
.def period_cnt=r28
.def data_byte1=r29
;порты:
;PORTD
.equ SHIM=PD7
.equ UH=PD6
;********************************
.cseg
.org 0x0000
;*****************************
jmp RESET ; Reset Handler
jmp EXT_INT0 ; IRQ0 Handler
jmp EXT_INT1 ; IRQ1 Handler
jmp TIM2_COMP ; Timer2 Compare Handler
jmp TIM2_OVF ; Timer2 Overflow Handler
jmp TIM1_CAPT ; Timer1 Capture Handler
jmp TIM1_COMPA ; Timer1 CompareA Handler
jmp TIM1_COMPB ; Timer1 CompareB Handler
jmp TIM1_OVF ; Timer1 Overflow Handler
jmp TIM0_OVF ; Timer0 Overflow Handler
jmp SPI_STC ; SPI Transfer Complete Handler
jmp USART_RXC ; USART RX Complete Handler
jmp USART_UDRE ; UDR Empty Handler
jmp USART_TXC ; USART TX Complete Handler
jmp ADC ; ADC Conversion Complete Handler
jmp EE_RDY ; EEPROM Ready Handler
jmp ANA_COMP ; Analog Comparator Handler
jmp TWSI ; Two-wire Serial Interface Handler
jmp EXT_INT2 ; IRQ2 Handler
jmp TIM0_COMP ; Timer0 Compare Handler
jmp SPM_RDY ; Store Program Memory Ready Handler
EXT_INT0:ret
EXT_INT1:ret
TIM2_COMP:ret
TIM2_OVF:ret
TIM1_CAPT:ret
TIM1_COMPA:ret
TIM1_COMPB:ret
;TIM1_OVF:
TIM0_OVF:ret
SPI_STC:ret
;USART_RXC:
;USART_UDRE:
USART_TXC:ret
ADC:ret
EE_RDY:ret
ANA_COMP:ret
TWSI:ret
EXT_INT2:ret
TIM0_COMP:ret
SPM_RDY:ret
;****************************
; ///TMR1 OVF///
;****************************
TIM1_OVF:
;запретить прерывания по переполнению
;извлекаем номер периода и продолжаем счёт
clr work
out TCCR1B,work;останов таймера
out TCNT1H,work;сбросить таймер-счётчик
out TCNT1L,work
ser work
out TIFR,work;cбросить флаги таймеров
main:
mov t_count1_H,BLDC_cnt;записать число с компа в реги.
mov t_count1_L,BLDC_cnt
exit_1:
ldi work,0b00000011
out TCCR1B,work;пуск таймера 1 с преддел.
out TCNT1H,t_count1_H;записать число с компа в реги таймера
out TCNT1L,t_count1_L
sbis PORTD,UH;светик вкл?
rjmp led_on;
rjmp led_off;тогда вырубить
exit:
reti
;-------------------
led_on:
sbi PORTD,UH
rjmp exit
led_off:
cbi PORTD,UH
rjmp exit
;****************************
; ///USATR RXC///
;****************************
USART_RXC:
in BLDC_cnt,UDR;cчитываем байт
exit_2:
sbi UCSRB,UDRIE;разрешаем прерывание по пустому буферу.
reti
;****************************
; ///USATR UDR///
;****************************
USART_UDRE:;прерывание по пустому буферу.
ser work
out UDR,work
cbi UCSRB,UDRIE;запретить прерывание до след. байта с компа
reti
RESET:
ldi r16,high(RAMEND) ; Main program start
out SPH,r16 ; Set stack pointer to top
ldi r16,low(RAMEND)
out SPL,r16
sei ; Enable interrupts
; ///PORTD///
ldi work,0b11111111
out DDRD,work
ldi work,0b01000000;светик на РД6
out PORTD,work
;***********************************
; ///настройка таймера 1 на прерывание по переполнению///
ldi work,0b00000000;stop timer1
out TCCR1B,work;
ldi t_count1_H,0x00;
ldi t_count1_L,0x00;
out TCNT1H,t_count1_H;clr TCNT
out TCNT1L,t_count1_L;clr TCNT1
ldi work,0b00000100;разрешить прерывание по переполн. таймера1
out TIMSK,work
;***********************************
; ///настройка USART///
; Set baud rate
ldi work,47;предделитель для 9600бодов при частотe 7.3728МГц
out UBRRL,work
; Enable receiver and transmitter
ldi work,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<UDRIE);разрешить П/П, разрешить прерывание по принятому байту в UDR
out UCSRB,work
; Set frame format: 8data, 1 stop bit, no parity
ldi work,10000110;(URSEL, UCSZ1, UCSZ0)
out UCSRC,work
cbi UCSRB,RXCIE
;*****************************
;main loop
;*****************************
main_loop:
ldi work,0b00000011;предделитель
out TCCR1B,work
out TCNT1H,t_count1_H;заряжем таймер первым значением
out TCNT1L,t_count1_L
sbi UCSRB,RXCIE;разрешаем прерывание "байт с компа в буфере"
main_loop_1:
rjmp main_loop_1
и МК начал принимать данные... но очень странно. пишешь число в порт - скорость мигания светика меняется. пишешь то же число - снова меняется( существенно:на глаз видно). Бывает перестаёт мигать, бывает гаснет на долго...USART_RXC:
in BLDC_cnt,UDR;cчитываем байт
exit_2:
sbi PORTB,PB0
sbi UCSRB,UDRIE;разрешаем прерывание по пустому буферу.
reti
спасибо за помощьGudd-Head писал(а):100 мкФ на ресете слишком много, 0.1 будет достаточно. Между питанием и "землёй" можно поставить пару кондёров (неск-ко мкФ электролит + неэлектролит ~0,1 мкФ) поближе к МК.
В даташите вроде написано, что на AVcc надо подавать питание, даже если вы не будете использовать аналоговую перифирию. Равно как и AGND стоит соединить с GND от греха подальше.Necroteeth писал(а):смущал вопрос об объединения земли программатора и питания, а также о avcc. ну коли про них Вы ничего не сказали, то добавлю конденсаторы по питанию и буду пробовать
///настройка USART///
; Set baud rate
ldi work,23;предделитель для 19200бодов при частотe 7.3728МГц
out UBRRL,work
; Enable receiver and transmitter
ldi work,(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<UDRIE);разрешить П/П, разрешить прерывание по принятому байту в UDR
out UCSRB,work
; Set frame format: 8data, 1 stop bit, no parity
ldi work,10000110;(URSEL, UCSZ1, UCSZ0)
out UCSRC,work
ldi work,00000110;писать в UBRRH(URSEL=0)
out UCSRC,work
clr work
out UBRRH,work
out UCSRA,work
cbi UCSRB,RXCIE