Компилируется нормально, прошивается тоже. При включении мигает синий светодиод (т.е. нормально функционирует основной цикл программы - LOOP1). Но стоит только послать что то по юарту - МК "виснет" (т.е. вместо загорания зелёного светодиода мигающий синий останавливается в том состоянии, на которое пришллось прерывание).
Помогите, пожалуйста, определить, в чём проблема. Подозреваю, что намудрил с инициализацией UART'а...
Пишу на ассемблере. Вот текст программы (для компиляции использую AVR GCC, частота кварца 8 МГц).
Код
.nolist
#define __SFR_OFFSET 0
#include <avr/io.h>
#include <avr/interrupt.h>
.list
#define RED 0b11111011
#define BLUE 0b11110111
#define GREEN 0b11101111
#define OFF 0b11111111
tmp1 = 16
tmp2 = 17
led_color = 18
.global main
main:
.org 0
rjmp RESET ; Reset Handler
reti; EXT_INT0 ; IRQ0 Handler
reti; EXT_INT1 ; IRQ1 Handler
reti; TIM2_COMP ; Timer2 Compare Handler
reti; TIM2_OVF ; Timer2 Overflow Handler
reti; TIM1_CAPT ; Timer1 Capture Handler
reti; TIM1_COMPA ; Timer1 CompareA Handler
reti; TIM1_COMPB ; Timer1 CompareB Handler
reti; TIM1_OVF ; Timer1 Overflow Handler
reti; TIM0_OVF ; Timer0 Overflow Handler
reti; SPI_STC ; SPI Transfer Complete Handler
rjmp UART_RXC ; UART RX Complete Handler
reti; UART_DRE ; UDR Empty Handler
reti; UART_TXC ; UART TX Complete Handler
reti; ADC ; ADC Conversion Complete Interrupt
reti; EE_RDY ; EEPROM Ready Handler
reti; ANA_COMP ; Analog Comparator Handler
RESET:
ldi tmp1, lo8(RAMEND); Stack setup
out SPL, tmp1
ldi tmp1, hi8(RAMEND)
out SPH, tmp1
ldi tmp1, 51; set uart baudrate to 9600 baud
out UBRR, tmp1
ldi tmp1, (1<<TXEN)|(1<<RXEN)|(1<<RXCIE); enable RXint and enable tx/rx
out UCR, tmp1
ser tmp1
out DDRC, tmp1; set all PORTC bits as output
ldi led_color, BLUE; turn on blue led by default
ldi tmp2, OFF
sei ; global enable interrupts
LOOP1:
out PORTC, led_color; LED on
rcall wait_some_time
out PORTC, tmp2 ; LED off
rcall wait_some_time
rjmp LOOP1 ; repeat
wait_some_time:
push r24
push r25
ldi r24, 0xFF
ldi r25, 0xFF
wait_some_time_loop:
sbiw r24, 1
brne wait_some_time_loop
pop r25
pop r24
ret
UART_RXC:
ldi led_color, GREEN
reti
#define __SFR_OFFSET 0
#include <avr/io.h>
#include <avr/interrupt.h>
.list
#define RED 0b11111011
#define BLUE 0b11110111
#define GREEN 0b11101111
#define OFF 0b11111111
tmp1 = 16
tmp2 = 17
led_color = 18
.global main
main:
.org 0
rjmp RESET ; Reset Handler
reti; EXT_INT0 ; IRQ0 Handler
reti; EXT_INT1 ; IRQ1 Handler
reti; TIM2_COMP ; Timer2 Compare Handler
reti; TIM2_OVF ; Timer2 Overflow Handler
reti; TIM1_CAPT ; Timer1 Capture Handler
reti; TIM1_COMPA ; Timer1 CompareA Handler
reti; TIM1_COMPB ; Timer1 CompareB Handler
reti; TIM1_OVF ; Timer1 Overflow Handler
reti; TIM0_OVF ; Timer0 Overflow Handler
reti; SPI_STC ; SPI Transfer Complete Handler
rjmp UART_RXC ; UART RX Complete Handler
reti; UART_DRE ; UDR Empty Handler
reti; UART_TXC ; UART TX Complete Handler
reti; ADC ; ADC Conversion Complete Interrupt
reti; EE_RDY ; EEPROM Ready Handler
reti; ANA_COMP ; Analog Comparator Handler
RESET:
ldi tmp1, lo8(RAMEND); Stack setup
out SPL, tmp1
ldi tmp1, hi8(RAMEND)
out SPH, tmp1
ldi tmp1, 51; set uart baudrate to 9600 baud
out UBRR, tmp1
ldi tmp1, (1<<TXEN)|(1<<RXEN)|(1<<RXCIE); enable RXint and enable tx/rx
out UCR, tmp1
ser tmp1
out DDRC, tmp1; set all PORTC bits as output
ldi led_color, BLUE; turn on blue led by default
ldi tmp2, OFF
sei ; global enable interrupts
LOOP1:
out PORTC, led_color; LED on
rcall wait_some_time
out PORTC, tmp2 ; LED off
rcall wait_some_time
rjmp LOOP1 ; repeat
wait_some_time:
push r24
push r25
ldi r24, 0xFF
ldi r25, 0xFF
wait_some_time_loop:
sbiw r24, 1
brne wait_some_time_loop
pop r25
pop r24
ret
UART_RXC:
ldi led_color, GREEN
reti