Zdravím všechny místní, potřeboval bych od Vás pomoc s nalezením chyby ve dvou programech. Chtěl jsem na Arduinu rozblikat diodu pomocí časovače v CTC módu v C a později v Asembleru, ale ani v jednom z jazyků se mi to bohužel nepovedlo. Budete někdo vědět, kde by mohl být problém? U programu v Asembleru jsem si kvůli lazení zkusil rozblikat OC1A, který funguje výborně, časovač tedy běží. Dokonce to vypadá, že se program přerušení jednou provede, ale vypadá to, že se provede právě jednou. U programu v C se mi podle všeho nedaří ani rozchodit přerušení. Díky všem za odpovědi.
Program v Asembleru:
; register name definition
.equ pinb, 0x23
.equ ddrb, 0x24
.equ portb, 0x25
.equ pinc, 0x26
.equ ddrc, 0x27
.equ portc, 0x28
.equ pind, 0x29
.equ ddrd, 0x2A
.equ portd, 0x2B
.equ iopinb, 0x3
.equ ioddrb, 0x4
.equ ioportb,0x5
.equ iopinc, 0x6
.equ ioddrc, 0x7
.equ ioportc,0x8
.equ iopind, 0x9
.equ ioddrd, 0xA
.equ ioportd,0xB
.equ spl, 0x5D
.equ sph, 0x5E
.equ sreg, 0x5F
.equ iospl, 0x3D
.equ iosph, 0x3E
.equ iosreg, 0x3F
.equ timsk1, 0x6F
.equ tccr1a, 0x80
.equ tccr1b, 0x81
.equ tccr1c, 0x82
.equ tifr1, 0x36
.equ iotifr1,0x16
.equ mcucr, 0x55
.equ iomcucr,0x35
.equ tcnt1l, 0x84
.equ tcnt1h, 0x85
.equ ocr1al, 0x88
.equ ocr1ah, 0x89
.equ RAMEND, 0x8FF
.org 0x0
rjmp START ; Go to the begin of the program
.org 0x2C ; TIM1_COMPA interrupt
rjmp TOOGLE_LED ; Toogle LED if interrupt occurs
.org 0x68
START: ; Begin of the program, initialization part
; sei
cli ;
ldi r17, 0x0
in r16, iomcucr
ori r16, 0x1
out iomcucr, r16
out iomcucr, r17
ldi r16, hi8(RAMEND);
out iosph, r16 ;
ldi r16, lo8(RAMEND);
out iospl, r16 ;
ldi r16, 0; ;
sts tcnt1h, r16 ;
sts tcnt1l, r16 ;
ldi r16, 0x0 ;
out ioportc, r16 ;
ldi r16, 0xFF ;
out ioddrc, r16 ;
out ioddrb, r16
ldi r16, hi8(31250) ;
ldi r17, lo8(31250) ;
sts ocr1ah, r16 ;
sts ocr1al, r17 ;
ldi r16, 0x40 ;
sts tccr1a, r16 ;
ldi r16, 0x8 ;
sts tccr1b, r16 ;
ldi r16, 0x2 ;
sts timsk1, r16 ;
ldi r16, 0x0
sts tifr1, r16
ldi r16, 0x0
out ioportb, r16
lds r16, tccr1b ;
andi r16, 0xF8 ;
ori r16, 0x4 ;
sei ;
sts tccr1b, r16 ;
INFINITE_LOOP:
rjmp INFINITE_LOOP
TOOGLE_LED:
in r16, ioportb ;
ldi r17, 0x1 ;
eor r16, r17 ;
out ioportb, r16 ;
reti ;
Program v C (ano, hlavičkové soubory mám pojmenované hloupě, mea culpa):
Blinking_LED.c
#define __AVR_ATmega328P__
//#define __AVR_ATmega128__
#include <avr/io.h>
#include <avr/interrupt.h>
#include "Initialization.c"
#include "XorLED.c"
void main(void){
cli();
init();
sei();
TCCR1B &= 0xFC;
TCCR1B |= (1<<CS12); // Start TCNT1
}
Initialization.c
#define __AVR_ATmega328P__
//#define __AVR_ATmega128__
#include <avr/io.h>
#include <avr/interrupt.h>
void init(){
SP = RAMEND;
DDRC = 0x4;
PORTC = 0;
DDRB = 0x2;
PORTB = 0;
TIFR1 = 0;
TCNT1 = 0;
TCCR1A = 0;
TCCR1B = (1<<WGM12);
TIMSK1 = 0x2; //(1<<OCIE1A);
OCR1A = 31250;
return;
}
XorLED.c
#define __AVR_ATmega328P__
//#define __AVR_ATmega128__
#include <avr/io.h>
#include <avr/interrupt.h>
ISR(TIMER1_COMPA_vect){
PORTC ^= 0x4;
}