- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 19

Thema: Frage zu Software Uart mit TimerOverflow Interrupt

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    04.03.2010
    Beiträge
    26
    Blog-Einträge
    1
    Hi !
    Du hast recht, das ergibt 600Hz war was das probiren angeht war ich schon nen stück weiter, habe es aber irgendwie übersehen das ich den vorladewert schon verändert habe zur halben bitlänge, 5ms sind 1,5 bitlängen um das startbit zu überspringen..... 0-7 ist doch 8 ^^ oder ? ^^

    hab es ja jetzt mit 600Hz und nem flag versucht sprich bei der isr des timers wird nur jeder 2.overflow ausgewertet(was man in dieser ver des programms nicht sieht da ich irgendwie zu blöd binn in ner antwort code einzufügen) aber die idee mit 600Hz und dem flag führt immer noch zum selben Ergebniss.... Was ist denn ein CTC ?

  2. #2
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    5ms sind 1,5 bitlängen um das startbit zu überspringen
    Du musst ja aber nur ein halbes Bit überbrücken, denn mit dem Timer überbrückst du ja dann ein komplettes weiteres Bit. Aber wie gesagt, mit _delay_ms ist das sowieso Murks. Lass einfach den ersten Timer-Interrupt nach 1,5 Bits kommen.

    0-7 ist doch 8 ^^ oder ?
    Code:
        udr |= (1<<bitCnt++);
    }
    
    if(bitCnt == 7)
    Beim Einlesen von Bit 6 wird bitCnt auf 7 erhöht, und dann greift sofort das "bitCnt == 7", also ließt du nur 0-6.

    Was ist denn ein CTC ?
    Ein Timer-Mode, bei dem du nicht manuell den Timer vorladen musst, und damit sehr viel genauere Abstände zwischen den Interrupts hast.
    MfG
    Stefan

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    04.03.2010
    Beiträge
    26
    Blog-Einträge
    1

    Lächeln Mist du hast recht....

    Hi !
    Erst mal Danke für deine Antworten....
    Mist ich erhöhe ja wirklich nur bis 6 ^^(wo hab ich nur meinen Kopf)
    Also Das mit dem CTC hört sich gut an, da muss ich mich gleich mal drüber schlau machen....
    Hier Jetzt erst mal der versprochene Code, damit sollte es doch aber rein theoretisch bei 300Baud doch funktionieren oder ? (mit ausnahme davon das ich immer noch das startbit mit einlese....)
    Also ich würde wirklich gerne erst mal versuchen dieses Beispiel irgendwie zum laufen zu Bringen, so rein für den Kopf und das Verständniss... Achso, der chip den ich verwende ist ein Mega8 bei 16MHz

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    #include "init.h"
    #include "lcd.h"
    
    
    //SoftUART PINS
    #define RXPIN 2
    #define RXINT INT0
    #define UARTDDR DDRD
    #define UARTPIN PIND
    #define UARTPORT PORTD
    #define T0REL 152
    
    char iOut[20];
    
    unsigned char bitFlag = 0;
    unsigned char bitCnt = 0;
    unsigned char udr = 0;
    
    
    void cfgInt0(void)
    {
        MCUCR |= (1<<ISC01);        //INT0 falling edge
        GICR |= (1<<INT0);            //INT0 interrupt enable
    }
    
    void cfgTimer0(void)
    {
        TCNT0 = T0REL;
        TCCR0 |= (1<<CS02);
        //TIMSK |=(1<<TOIE0);
    }
    
    void cfgSoftUart(void)
    {
        UARTDDR &=~ (1<<RXPIN);        //RX Pin als Input
        UARTPORT &=~ (1<<RXPIN);    //RX Pin auf 0
    
        cfgInt0();                    //Software UART Interrupt
        cfgTimer0();                //Software UART Timer
    }
    
    
    int main(void)
    {
        cfgPorts();
        cfgSoftUart();
        cfgLcd(LCD_ON_CURSOR_OFF);
        lcdCls();
        enableInterrupts();
    
        _delay_ms(200);
        lcdPrint("Software Uart",1,1);
    
        while(1)
    
        {    
            itoa(udr,iOut,10);
            lcdPrint("                    ",1,3);
            lcdPrint(iOut,1,3);
            itoa(udr,iOut,2);
            lcdPrint(iOut,5,3);
            
            _delay_ms(1000);
        }
          return 0;
    }
    
    
    ISR(INT0_vect)
    {
        GICR &=~ (1<<INT0);
        TCNT0 = T0REL;
        TIMSK |=(1<<TOIE0);
    }
    
    ISR(TIMER0_OVF_vect)
    {
        TCNT0 = T0REL;
        if(bitFlag == 0)
        {
            bitFlag = 1;
        }else 
        {
            bitFlag = 0;
            if(!(PIND & (1 << PD2)))
            {
                udr &=~ (1<<bitCnt++);
            }else
            {
                udr |= (1<<bitCnt++);
            }
    
            if(bitCnt == 8)
            {
                bitCnt = 0;
                TIMSK &=~(1<<TOIE0);
                GIMSK |= (1<<INT0);
            }
        }
    }
    So sollte ich doch eigendlich die halbe bitzeit erwischen oder nicht ? Leider funktioniert das so immer noch nicht.... aber für 300 Baud sollte das mit dem timer overflow doch eigendlich genau genug sein oder nicht ?!?

    Mfg Fugitivus

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Du hast auch noch ein Problem mit deinen Interrupts. Auch wenn ein Interrupt gerade nicht enabled ist, setzt das entsprechende Ereignis doch das zugehörige Flag. Wenn der Interrupt dann enabled wird, kommt er sofort, weil das Flag ja schon gesetzt ist. Also musst du im INT0-Interrupt das Flag für den Overflow löschen, und im Overflow-Interrupt nach dem letzten Bit das Flag für INT0. Aber Achtung, schau erst im Datenblatt nach, wie man diese Flags löscht, ein "&=~" wäre da nämlich falsch.

    PS: Benutze entweder die Bezeichnung GIMSK oder die Bezeichnung GICR. Beides zu benutzen verwirrt doch nur.
    MfG
    Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    04.03.2010
    Beiträge
    26
    Blog-Einträge
    1

    Danke !

    das mit den flags werde ich gleich mal kontrollieren ! hört sich irgendwie genau nach meinem problem an !
    Danke !

    Mfg Fugitivus

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    04.03.2010
    Beiträge
    26
    Blog-Einträge
    1

    Super Herzlichen Dank !

    Das war also das was ich nicht wusste, wieder was dazu Gelernt !
    Herzlichen Dank ! Dann werd ich mich jetzt mal mit CTC auseinandersetzen....



    Mfg Fugitivus

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    04.03.2010
    Beiträge
    26
    Blog-Einträge
    1

    Habs mal mit 38400 Baud getestet funktioniert wunderbar....

    Habs mal mit 38400 Baud getestet funktioniert wunderbar....

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    
    #include "init.h"
    #include "lcd.h"
    
    
    //SoftUART PINS
    #define RXPIN 2
    #define RXINT INT0
    #define UARTDDR DDRD
    #define UARTPIN PIND
    #define UARTPORT PORTD
    
    #define T0REL 204
    #define T0WAIT 48
    
    char iOut[20];
    
    unsigned char sFlag = 0;
    unsigned char bitCnt = 0;
    unsigned char udr = 0;
    
    
    void cfgInt0(void)
    {
        MCUCR |= (1<<ISC01);        //INT0 falling edge
        GICR |= (1<<INT0);            //INT0 interrupt enable
    }
    
    void cfgTimer0(void)
    {
        TCNT0 = T0WAIT;
        TCCR0 = 1;                    //pre = 1
        //TIMSK |=(1<<TOIE0);
    }
    
    void cfgSoftUart(void)
    {
        UARTDDR &=~ (1<<RXPIN);        //RX Pin als Input
        UARTPORT &=~ (1<<RXPIN);    //RX Pin auf 0
    
        cfgInt0();                    //Software UART Interrupt
        cfgTimer0();                //Software UART Timer
    }
    
    
    int main(void)
    {
        cfgPorts();
        cfgSoftUart();
        cfgLcd(LCD_ON_CURSOR_OFF);
        lcdCls();
        enableInterrupts();
    
        _delay_ms(200);
        lcdPrint("Software Uart",1,1);
    
        while(1)
    
        {    
            itoa(udr,iOut,10);
            lcdPrint("                    ",1,3);
            lcdPrint(iOut,1,3);
            itoa(udr,iOut,2);
            lcdPrint(iOut,5,3);
            
            _delay_ms(1000);
        }
          return 0;
    }
    
    
    ISR(INT0_vect)
    {
        GICR &=~ (1<<INT0);
        TCNT0 = T0WAIT;
        TCCR0 = 1;
        TIFR |= (1<<TOV0);
        TIMSK |=(1<<TOIE0);
    }
    
    ISR(TIMER0_OVF_vect)
    {
        TCNT0 = T0REL;
    
        if(sFlag == 0)
        {
            sFlag = 1;
            TCCR0 = 2;
        }else
        {
            if(!(PIND & (1 << PD2)))
            {
                udr &=~ (1<<bitCnt++);
            }else
            {
                udr |= (1<<bitCnt++);
            }
        }
        if(bitCnt == 8)
        {
            bitCnt = 0;
            sFlag = 0;
            TIMSK &=~(1<<TOIE0);
            GIFR |= (1<<INTF0);
            GICR |= (1<<INT0);
        }
    
    }
    mal gucken wie sowas mit ctc aussieht.....
    noch mal super herzlichen dank !
    mfg Fugitivus

Ähnliche Themen

  1. Software Uart, Interrupt möglich?
    Von hunni im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 12
    Letzter Beitrag: 07.03.2011, 16:53
  2. Frage zu Software Uart
    Von Blamaster im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 11
    Letzter Beitrag: 29.06.2008, 12:35
  3. Interrupt bei Software UART?
    Von coCo im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 5
    Letzter Beitrag: 30.11.2006, 16:22
  4. Interrupt (Oder Trick)beim Software Uart
    Von frank-wob im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 3
    Letzter Beitrag: 09.08.2006, 10:43
  5. Ampelsteuerung, AVR AT90S8535 ,TimerOverflow Interrupt
    Von gizzi im Forum AVR Hardwarethemen
    Antworten: 8
    Letzter Beitrag: 18.05.2006, 18:51

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen