Ale to je uzasne
Ako sa Ti podarilo, aby kod v procesore po vbehnuti do podprogramu prerusenia zahlasil nejaku chybu? Z toho logicky vyplyva, ze to prerusenie sa vykona. Akurat neviem, co ten kod sleduje a co a hlavne KDE to hlasi.
Ak Ti chybu zahlasi prekladac pri preklade, tak to prosim napis.
Alebo sa tam deje nieco uplne ineho? Ako to mame vediet?
Skus sem dat vypisy tych chyb. Ak to naozaj hlasi tvoj kod na nejakom tvojom display, alebo cez UART, (ved ako by to inak mohol hlasit )
daj sem tie jeho hlasky a uved, co ten tvoj kod skuma, ked sa mu to nepaci a ohlasuje to.
Alebo nabuduce poriadne napis, co sa ti tam deje, aby ti bolo mozne poradit.
to Technik:
Samozrejme, ze pouzitie slovnych oznaceni jednotlivych bitov nie je samospasitelne a pri novom procesore si VZDY treba PORIADNE pozriet dokumentaciu. V kazdom pripade sa tym zvysuje citatelnost zdrojaku, hlavne ak ho treba predlozit na posudenie inym. To je ale myslim pravidlo, ktore by sa malo tykat nielen C-cka, ale aj ASM. Jednoducho, stabna kultura.
Problem so zdrojakmi a s roznymi procesormi riesim nasledovne(ale tiez treba vediet, ze to nemusi byt samospasitelne riesenie ako uz uviedol Technik):
inicializacny header. Tu je okrem procesora vybrany i hardver a premapovanie prislusnych pinov na nazvy jednotlivych svoriek (tato cast tu nie je uvedena)
#define XTAL 14745600
#define F_CPU XTAL
// Definice makier s parametrami
#define SET(BAJT,BIT) ((BAJT) |= (1<<(BIT)))
#define RES(BAJT,BIT) ((BAJT) &= ~(1<<(BIT)))
#define NEG(BAJT,BIT) ((BAJT) ^= (1<<(BIT)))
#define TST(BAJT,BIT) ((BAJT) & (1<<(BIT)))
#define ATmega8 0
#define ATmega644P 1
#define PROCESOR ATmega8
#if (PROCESOR == up_mega8)
#ifndef __AVR_ATmega8__
#define __AVR_ATmega8__
#endif
#include <avr/iom8.h>
#define ZAKAZ_GLOB_PRERUSENIE cli()
#define POVOL_GLOB_PRERUSENIE sei()
#define TB_DEFAULT_1 114 //115-1 pouzije sa POCET_PRVEJ_PREDVOLBY
#if (XTAL == 7372800)
#define TB_NASTAV_CASOVAC (TCCR2 = ((1<<WGM21) + 3) // mod CTC a preddelic 32, CS22 = L, CS21 = H, CS20 = H
#elif (XTAL == 14745600)
#define TB_NASTAV_CASOVAC (TCCR2 = (1<<WGM21) + 4) // mod CTC a preddelic 64, CS22 = H, CS21 = L, CS20 = L
#endif
#define TB_POVOLENIE_PRERUSENIA (SET(TIMSK,OCIE2)) // povolenie interuptu pri compare match
#define TB_ZAKAZ_PRERUSENIA (RES(TIMSK,OCIE2)) // zakaz interuptu pri compare match
#define TB_CNT TCNT2
#define TB_PREDVOLBA OCR2
#define TB_SIG_OUTPUT_COMPARE SIG_OUTPUT_COMPARE2 // nazov vektoru pre prerusenie od casovaca CZ - compare match
#elif PROCESOR ATmega644P
#ifndef __AVR_ATmega644__
#define __AVR_ATmega644__
#endif
#include <avr/iom644.h>
#define ZAKAZ_GLOB_PRERUSENIE cli()
#define POVOL_GLOB_PRERUSENIE sei()
#define TB_DEFAULT_1 114 //115-1 pouzije sa POCET_PRVEJ_PREDVOLBY
#if (XTAL == 7372800)
// mod CTC a preddelic 64, CS22 = H, CS21 = L, CS20 = L
#define TB_NASTAV_CASOVAC TCCR2A = (1<<WGM21);\
TCCR2B = (1<<CS22)
#elif ((XTAL == 14745600) || (XTAL == 18432000)) // mod CTC a preddelic 128, CS22 = H, CS21 = L, CS20 = H
#define TB_NASTAV_CASOVAC TCCR2A = (1<<WGM21);\
TCCR2B = (1<<CS22) | (1<<CS20)
#endif
#define TB_POVOLENIE_PRERUSENIA (SET(TIMSK2,OCIE2A)) // povolenie interuptu pri compare match
#define TB_ZAKAZ_PRERUSENIA (RES(TIMSK2,OCIE2A)) // zakaz interuptu pri compare match
#define TB_CNT TCNT2
#define TB_PREDVOLBA OCR2A
#define TB_SIG_OUTPUT_COMPARE SIG_OUTPUT_COMPARE2A // nazov vektoru pre prerusenie od casovaca CZ - compare match
// definovanie COM0
#define COM0_BAUD_RATE(komunikacna_rychlost) UBRR0H = 0xff & ((F_CPU / ((komunikacna_rychlost) * 16L) - 1)>>8);\
UBRR0L = 0xff & (F_CPU / ((komunikacna_rychlost) * 16L) - 1)
#define COM0_REG_DATA_OUT UDR0
#define COM0_REG_DATA_IN UDR0
#define COM0_SETUP_ASYNCHRON_8N1 UCSR0C = ( (3<<UCSZ00));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_SETUP_ASYNCHRON_8E1 UCSR0C = ( (3<<UCSZ00) | (1<<UPM01));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_SETUP_ASYNCHRON_8O1 UCSR0C = ( (3<<UCSZ00) | (1<<UPM01) | (1<<UPM00));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_SETUP_ASYNCHRON_8N2 UCSR0C = ( (1<<USBS0) | (3<<UCSZ00));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_SETUP_ASYNCHRON_8E2 UCSR0C = ( (1<<USBS0) | (3<<UCSZ00) | (1<<UPM01));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_SETUP_ASYNCHRON_8O2 UCSR0C = ( (1<<USBS0) | (3<<UCSZ00) | (1<<UPM01) | (1<<UPM00));\
RES(UCSR0A,U2X0);\
RES(UCSR0A,MPCM0)
#define COM0_OTVOR_RX SET(UCSR0B,RXEN0)
#define COM0_ZATVOR_RX RES(UCSR0B,RXEN0)
#define COM0_OTVOR_TX SET(UCSR0B,TXEN0)
#define COM0_ZATVOR_TX RES(UCSR0B,TXEN0)
#define COM0_RX_INT_POVOL SET(UCSR0B,RXCIE0)
#define COM0_RX_INT_ZAKAZ RES(UCSR0B,RXCIE0)
#define COM0_TX_INT_POVOL SET(UCSR0B,TXCIE0)
#define COM0_TX_INT_ZAKAZ RES(UCSR0B,TXCIE0)
#define COM0_POVOL_INT_PRAZDNEHO_BUFERU SET(UCSR0B,UDRIE0)
#define COM0_ZAKAZ_INT_PRAZDNEHO_BUFERU RES(UCSR0B,UDRIE0)
#define COM0_ZRUS_PRIZNAK_PRAZDNEHO_BUFERU RES(UCSR0A,UDRE0)
#define COM0_ZRUS_PRIZNAK_PRIJATIA_ZNAKU RES(UCSR0A,RXC0)
#define COM0_ZRUS_PRIZNAK_ODVYSIELANIA_ZNAKU RES(UCSR0A,TXC0)
#endif
priklad samotneho programu, uryvok z rozsiahlejsieho cyklu
#include "tb_ini.h"
//.....
int main(void)
{
TB_PREDVOLBA = TB_DEFAULT_1;
TB_NASTAV_CASOVAC;
TB_POVOLENIE_PRERUSENIA;
POVOL_GLOB_PRERUSENIE;
for(;;) {
}
}
ISR(TB_SIG_OUTPUT_COMPARE)
{
TB_PREDVOLBA = TB_DEFAULT_1;
// co len chcem
}
Takto napisany program v C-cku je v znacnom rozsahu nezavisly od pouziteho procesora, pripadne od celej rodiny procesorov. Dolezite je si na zaciatku povedat, ake makra maju zmysel. Napriklad POVOL_PRERUSENIE, ZAKAZ_GLOB_PRERUSENIE.
S ATmega je velky problem v nastavovani komunikacnych parametrov po jednotlivych castiach. Napriklad tu si nastavim paritu a inde si nastavim pocet prenasanych bitov. Musel by som si obsah toho sibnuteho registra niekde odpamatat, lebo sa don neda robit OR. Preto tie makra vyzeraju ako vyzeraju, napriklad COM0_SETUP_ASYNCHRON_8N2. Ale v praxi to nevadi. Pre iny typ procesora s logickejsie vyriesenym nastavenim parametrov UARTU sa da makro tiez tak napisat, aby vyhovovalo tomuto principu.
Kto si vsak zavedie pri svojej praci ake pravidla, je v podstate na tom, co mu najviac vyhovuje. Mne ide hlavne o jednoduchu adaptaciu zdrojaku na rozny hardver a pre rozne procesory zvycajne dane tym hardverom. Projekt sa snazim skladat z co najvaciseho (rozumne) poctu logicky nezavislych celkov. Jeden subor je na komunikaciu a veci s nou spojene, iny na AD, dalsi na spristupneie ext. flash pamati cez SPI, LED display, LCD display. Vsetko tak, aby bolo samotne jadro riesiace ulohu co najviac odbremenene od takychto stereotypnych uloh. Pri rieseni novej ulohy si skopirujem tie *.c subory, ktore potrebujem do projektu (aj tieto *.c subory sa vyvijaju, tak aby som nejakou banalnou zmenou nemal problem pri preklade programu tri roky stareho projektu ukladam v projekte vsetko co k nemu patri), vytvorim samotne jadro novej aplikacie A JE TO…