Frekvencmeter bom naredil kar po svoje in sem naletel na problem pri kodi.
Torej ideja je, da bi bila koda v glavnem pisana v C zaradi računanja in prikazovanja podatkov na LCD zaslon. Časovno kritični del pa bi bil napisan v assemblyju.
Če se ne motim lahko v C kodo v Atmel studio dodam assembly z asm("UKAZ");
TIMER2 bi na vsakih 10mS naredil interrupt. Takrat bo v asm preveril, če je preštel 100 interruptov. Če se je to zgodilo bo v ugasnil prescaler, ki ima 4 žice za krmiljenje. Nato pa mora C prebrati vrednost PORTB, TIMER1 in TIMER0, ki šteje kolikokrat se zgodi overflow na TIMER1. TIMER0 uporabljam zato ker lahko imam samo 1 interrupt. Drugi compare register TIMERja2 bo nastavljen tako, da ko doseže vrednost 0xFFFF odda pulz na izhodu, ki pa je povezan na vhod TIMERja1.
Zanima me, kako v zanko v asm dodam C kodo?
Kako se bo potem koda izvajala? Ali se bo vrnla naprej v glavo zanko iz asm zanke?
- Koda: Izberi vse
#include <avr/io.h>
#include <avr/interrupt.h>
asm("ELSE_LABEL:"
"OUT PORTC, r29"
//TUKAJ MORA C PREBRATI VHODE IN TIMMER0 + 1 IN SHRANITI KOT SPREMENLJIVKE
"OUT PORTC, r28"
)
void start_count(){
}
int main(void){
asm("LDI r31, 0x64"); //Load counter constant into mS sompare register
asm("LDI r29, 0x1F"); //Load prescaler STOP command constant in register
asm("LDI r28, 0x02"); //Load prescaler START command constant in register
asm("CLR r30"); //Clear mS count register
while (1){
}
ISR(TIMER2_COMPA_vect){
asm("INC r30"); //incriment mS counter
asm("CP r30, r31"); //compare mS counter with counter constant
asm("BRNE ELSE_LABEL"); //If equal jump
}
}
Mogoče bi naredil, da asm samo izklopi prescaler nato pa še C preveri stanje registrov in nato prebere?
Kaj mi vi priporočate?
Za tisti del v asm sem se odločil tudi zato, ker lahko izračunam koliko časa bo preteklo med interruptom in izklopom prescalerja in nato to napako programsko odpravim.
Hvala za pomoč!
Lp, Lovro