Ich gebe zu so viel habe ich noch nicht in c für den AVR geschrieben.
Aber ich möchte hinterher nicht alles neu machen weil ich eine dumme gebaut habe.
Zu meiner Frage:
Zur Zeit arbeitet ich so das in den Interrupt Routinen nur das wichtigste gemacht wird und die eingleiche arbeit finden im Main statt.
Das mache ich so damit die Interrupts sich nicht gegenseitig unter Brechen.
Wenn ich mir jetzt andere Software so angucken gibt es welche die haben überhaupt kein Main (spich da steht nur wihle) und wieder ander arbeiten komplett ohen interupts bzw. mit nur sehr wenig.
Das ist das was ich gestern verbrochen habe. Im Simulator tut es.Code:/************************************** mains.c Autor: Numberfive versuchen das ganze mal zu verstehen. Alle die im Netzt beispiel code habe sei an dieser stelle gedankt man komme nie auf die Idee irgend wo Interupts zu enablen wenn dafür keine signal procedure hat dann springt der AVR wieder in die main routine Danke an Picknick für das Seriale Protokoll *************************************/ #include <avr/io.h> #include <avr/interrupt.h> #include <inttypes.h> //#include <stdlib.h> //#define F_CPU 16000000 // 16 MHz jetzt im Makefile #define UART_BAUD_RATE 19200 // 19200 Baud #define UART_BAUD_SELECT (F_CPU/(UART_BAUD_RATE*16l)-1) #define SCLOCK 16; // _BV = BitValue #define SETBIT(ADDRESS,BIT)(ADDRESS |=(1<<BIT)) #define CLEARBIT(ADDRESS,BIT)(ADDRESS &= ~(1<<BIT)); typedef unsigned char BYTE; typedef unsigned short WORD; //MN Funktions void WDT_off(void); void InitCom(void); void InitTimer1(void); void InitAD(void); void SendAlive(void); //RS232 Protokoll funktionen #define CTL_M_MASK 0xF8 #define CTL_M_ADON 0x08 #define CTL_C_BASE 0xA8 #define CTL_C_STX CTL_C_BASE + 1 #define CTL_C_ETX CTL_C_BASE + 2 #define CTL_C_PFX CTL_C_BASE + 3 void TxSendStuffByte (BYTE bTxChar); void TxSendFrameByte (BYTE bTxChar); void TxStartFrame ( void ); void TxCloseFrame ( void ); void SendChar(BYTE Zeichen); void SendADValue(BYTE nToClass,BYTE nToIdent,BYTE nPort); // Public Vars volatile BYTE IsHardBeat = 0; volatile BYTE IsPCData = 0; volatile BYTE HardBeatCount = 0; volatile BYTE bTxBcc; // Checksum für BCC volatile BYTE bSerialInBuffer[128]; volatile BYTE bBefehlbuffer[128]; volatile BYTE bInBufferPos = 0; volatile BYTE waitforad = 1; //Interupts SIGNAL(SIG_OVERFLOW1) { IsHardBeat = 1; TCNT1 = 49910;//Reload Timer } SIGNAL(SIG_UART_RECV) { BYTE Zeichen = UDR; if(bInBufferPos == 0) { if(Zeichen == CTL_C_STX) { bSerialInBuffer[0] = CTL_C_STX; bInBufferPos++; } } else { if(Zeichen == CTL_C_ETX) { bSerialInBuffer[bInBufferPos] = CTL_C_ETX; //Copy Buffer resetInbuffer for(BYTE nSize=0;nSize<=bInBufferPos;nSize++) { bBefehlbuffer[nSize] = bSerialInBuffer[nSize]; } bInBufferPos = 0; IsPCData = 1; } else { bSerialInBuffer[bInBufferPos] = Zeichen; bInBufferPos++; if(bInBufferPos == 128) { //Übergelaufen bInBufferPos = 0; } } } } SIGNAL(SIG_UART_TRANS) { // nix machen aber sonst komme ich immer wider forne an } SIGNAL(SIG_UART_DATA) { // nix machen aber sonst komme ich immer wider forne an } SIGNAL(SIG_ADC) { //Mal sehen der ad wander ist fertig waitforad = 0; } //Interupts ende int main (void) { //hauptprg hier geht der controler immer als erstes hin InitCom(); WDT_off(); InitAD(); SETBIT(DDRD,PD7); // Das ist der lautsprecher bSerialInBuffer[0] = 0X00; bSerialInBuffer[1] = 0X00; bSerialInBuffer[2] = 0X00; bSerialInBuffer[3] = 0X00; bSerialInBuffer[4] = 0X00; InitTimer1();//Timer 1 auf 1 sec sei();//interupt enable for(;;) { if(IsHardBeat == 1) { IsHardBeat = 0; HardBeatCount++; if(HardBeatCount == 5) { HardBeatCount=0; SendAlive(); } } if(IsPCData == 1) { IsPCData = 0; BYTE nPos = 1; BYTE nCheckSum = 0; // Das geht schief wenn das BCC maskiert ist while(bBefehlbuffer[nPos+1] != CTL_C_ETX) { if(bBefehlbuffer[nPos] != CTL_C_PFX) { nCheckSum ^= bBefehlbuffer[nPos]; } else { nPos++; nCheckSum ^= bBefehlbuffer[nPos]-CTL_M_ADON; } nPos++; } if(nCheckSum == bBefehlbuffer[nPos]) { //BCC OK if(bBefehlbuffer[1] == 0x05) { //NXT Bekommen if(bBefehlbuffer[5] == 0x00) { //Erste Gerät auf diesem Roboter ist ein ADWandler mit der Adresse 0x25 TxStartFrame(); TxSendFrameByte(0x09); TxSendFrameByte(0x00); TxSendFrameByte(0x25); TxSendFrameByte(0x00); TxSendFrameByte(0x01); TxSendFrameByte(0x82); TxSendFrameByte(0x00); TxCloseFrame(); } if(bBefehlbuffer[5] == 0x01) { //.. ist ein ADWandler mit der Adresse 0x29 TxStartFrame(); TxSendFrameByte(0x09); TxSendFrameByte(0x00); TxSendFrameByte(0x25); TxSendFrameByte(0x01); TxSendFrameByte(0x02); TxSendFrameByte(0x82); TxSendFrameByte(0x01); TxCloseFrame(); } if(bBefehlbuffer[5] == 0x02) { // Ich bin das Letzt und ein RN-Control TxStartFrame(); TxSendFrameByte(0x09); TxSendFrameByte(0x00); TxSendFrameByte(0x2D); TxSendFrameByte(0x00); TxSendFrameByte(0xFF); TxSendFrameByte(0x62); TxSendFrameByte(0x00); TxCloseFrame(); } } else if(bBefehlbuffer[1] == 0x25) { if(bBefehlbuffer[2] == 0x00) { SendADValue(bBefehlbuffer[3],bBefehlbuffer[4],0); } } } } } //Ende MainLoop } void InitCom(void) { /* Set baud rate */ /* wenn wir in das h register schreiben wollen muß da ein 0 drin sein */ UCSRC = (0<<URSEL); UBRRH = (UART_BAUD_SELECT>>8); UBRRL = UART_BAUD_SELECT; /* Enable receiver and transmitter und die Interupts*/ UCSRB = _BV(RXEN)|_BV(RXCIE);//|_BV(TXCIE); /* Set frame format: 8data, 1stop bit */ UCSRC = (1<<URSEL)|(0<<USBS)|(0<<UCSZ2)|_BV(UCSZ1)|_BV(UCSZ0); // Braucht man nicht aber das ist dir register umschaltung ob man // das hight byte des UBRR sieht oder UCSRC UCSRC != _BV(URSEL); } void WDT_off(void) { //WDR(); WDTCR |=(1<<WDTOE) | (1<<WDE); WDTCR = 0x00; } void InitTimer1(void) { SETBIT(TCCR1B,CS10); SETBIT(TCCR1B,CS11); //SETBIT(TCCR1B,CS12); //enable interrupt timer SETBIT(TIMSK,TOIE1); // 1 sec bei Teiler 1024 TCNT1 = 49910; TCNT1 = 100;//<- Für SIM } void InitAD(void) { //Init ADwandler ADCSRA = (1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //CLEARBIT(ADCSRA,ADFR); // Kein Freilauf CLEARBIT(ADMUX,REFS1); SETBIT(ADMUX,REFS0); // externe vergleichs Quelle SETBIT(ADCSRA,ADIE); } void SendAlive(void) { TxStartFrame(); TxSendFrameByte(0x01); TxSendFrameByte(0x00); TxSendFrameByte(0x00); TxSendFrameByte(0x00); TxCloseFrame(); } void SendADValue(BYTE nToClass,BYTE nToIdent,BYTE nPort) { CLEARBIT(ADCSRA,ADEN); // aus schlaten damit ich den port wechseln kann //ADMUX = nPort; geht nicht da sind noch 2 bit's if(nPort == 0) { CLEARBIT(ADMUX,MUX4); CLEARBIT(ADMUX,MUX3); CLEARBIT(ADMUX,MUX2); CLEARBIT(ADMUX,MUX1); CLEARBIT(ADMUX,MUX0); } else if(nPort == 1) { CLEARBIT(ADMUX,MUX4); CLEARBIT(ADMUX,MUX3); CLEARBIT(ADMUX,MUX2); CLEARBIT(ADMUX,MUX1); SETBIT(ADMUX,MUX0); } // Bit invertieren messung starten ADCSRA |=_BV(ADSC); waitforad = 1; // warten bis messung abgesclossen ist und wert gültig while(waitforad != 0) { //warten auf den adwandler; }; // den wert aus dem register holen if(nPort == 0) { TxStartFrame(); TxSendFrameByte(nToClass); TxSendFrameByte(nToIdent); TxSendFrameByte(0x25); TxSendFrameByte(0x00); TxSendFrameByte(ADCL); TxSendFrameByte(ADCH); TxCloseFrame(); /* pBuffer[0] = nToClass; pBuffer[1] = nToIdent; pBuffer[2] = 0x25; pBuffer[3] = 0x00; pBuffer[4] = LOBYTE(nValue); pBuffer[5] = HIBYTE(nValue);*/ } //Result = ADCH*256 + ADCL; } void SendChar(BYTE Zeichen) { SETBIT(UCSRB,TXEN); //Warten bis schnittstelle bereit loop_until_bit_is_set(UCSRA,UDRE); // Zeichen ins register schreiben UDR = Zeichen; CLEARBIT(UCSRB,TXEN); } // -------------------------------------------------------------- void TxStartFrame ( void ) { bTxBcc = 0; SendChar ( CTL_C_STX ); } // -------------------------------------------------------------- void TxCloseFrame ( void ) { TxSendStuffByte ( bTxBcc );// auch das BCC mit ev. prefixed werden SendChar ( CTL_C_ETX ); } // -------------------------------------------------------------- void TxSendFrameByte (BYTE bTxChar) { bTxBcc ^= bTxChar; TxSendStuffByte( bTxChar ); } // -------------------------------------------------------------- void TxSendStuffByte (BYTE bTxChar) { if((bTxChar & CTL_M_MASK) == CTL_C_BASE) { SendChar( CTL_C_PFX ); SendChar( bTxChar + CTL_M_ADON ); } else { SendChar( bTxChar ); } }







Zitieren

Lesezeichen