Naja mit dem Oszi messe ich direkt ab dem Controller. Die Led sitzt in einem kleinen USB>>RS232 umsetzer. Da komm ich nicht ran ich seh sie nur
Die _getkey() funktion will bei mir nicht funktionieren. Ich muss jetzt mal blöd fragen was der Unterschied zwischen blockierend und nicht blockierend ist. Ich versteh nicht so ganz was da blockiert wird...
Grüße!
Bean
naja wenn ich b_getkey verwende, tut sich wieder gar nichts. Lediglich bei nb_getkey bekomme ich eine Antwort wenn ich etwas sende. Das sieht aber eher nach Datenmüll aus...
Wenn ich b_getkey verwende komme ich zwar in die Funktion:
In diesem Fall wird "In b_getkey..." einmal auf dem Terminal ausgegeben. Dann hänge ich denke ich in der folgenden while Schleife...Code:char b_getkey () { char c; Print_String ("In b_getkey..."); while (!RI0); c = SBUF; RI0 = 0; return (c); }
Meine main sieht jetzt so aus:
Was könnte das noch sein? Ich verzweifle so langsam... Mit den AtMegas hat das ganze irgendwie besser und einfacher funktioniert...Code:void main (void) { unsigned char c; // Disable Watchdog timer PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer // enable) OSCILLATOR_Init (); // Initialize Oscillator PORT_Init(); // Initialize Port I/O UART0_Init (); // Initialize UART0 EA = 1; //Interrupts global freigeben //ES0 = 1; //UART0 interrupt freigeben while(1) { c= b_getkey (); putchar(c); } }
Grüße!
Bean
Das er bis zum print_string(...) kommt ist doch schon mal gut. Anschließend kommt er zur while(!RI0); und wartet dort, bis du ihm ein Zeichen über RX fütterst.
Da du am Eingang P0.5 was gemessen hast, was wie ein gesendetes Zeichen aussieht und b_getkey() eigentlich funktionieren müsste, liegt jetzt nur noch der PIN I/O und die Crossbar dazwischen.
Kannst du nochmal den kompletten Code so wie er jetzt ist posten?
sast
雅思特史特芬
开发及研究
So, guten Morgen!
Also hier nun noch der komplette code:
Ja kann natürlich sein dass das an der Crossbar liegt...Code:#include <c8051F330.h> #include <stdio.h> #define SYSCLK 24500000 #define BAUDRATE 115200 #define RX_length 25 //----------------------------------------------------------------------------- // Global Variables //----------------------------------------------------------------------------- //bit TX_ready; //True = OK zur Übertragung //char *TX_ptr; //pointer auf zu übermittelnden String bit RX_ready; //True = string empfangen char RX_buf[RX_length]; //Array als Eingangsbuffer anlegen unsigned char the_char; //zwischenspeicher sfr SBUF = 0x99; //----------------------------------------------------------------------------- // Function Prototypes //----------------------------------------------------------------------------- void OSCILLATOR_Init (void); void UART0_Init (void); void PORT_Init (void); void UART0_ISR (void); void Print_String (char pstring[]); char nb_getkey (); char b_getkey (); //----------------------------------------------------------------------------- // main Routine //----------------------------------------------------------------------------- void main (void) { unsigned char c; // Disable Watchdog timer PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer // enable) OSCILLATOR_Init (); // Initialize Oscillator PORT_Init(); // Initialize Port I/O UART0_Init (); // Initialize UART0 EA = 1; //Interrupts global freigeben //ES0 = 1; //UART0 interrupt freigeben while(1) { c= b_getkey (); putchar(c); } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // OSCILLATOR_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // This routine initializes the system clock to use the internal 24.5MHz // oscillator as its clock source. Also enables missing clock detector reset. // //----------------------------------------------------------------------------- void OSCILLATOR_Init (void) { OSCICN |= 0x03; // Configure internal oscillator for // its maximum frequency RSTSRC = 0x04; // Enable missing clock detector } //----------------------------------------------------------------------------- // PORT_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // P0.4 digital push-pull UART TX // P0.5 digital open-drain UART RX // //----------------------------------------------------------------------------- void PORT_Init (void) { P0SKIP |= 0x01; // Skip P0.0 for external VREF P1MDIN |= 0xEF; // Configure P1.4 as analog input. P0MDOUT |= 0x10; // enable UTX as push-pull output XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX) XBR1 = 0x40; // Enable crossbar and weak pull-ups } //----------------------------------------------------------------------------- // UART0_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1. // //----------------------------------------------------------------------------- void UART0_Init (void) { SCON0 = 0x10; // SCON0: 8-bit variable bit rate // level of STOP bit is ignored // RX enabled // ninth bits are zeros // clear RI0 and TI0 bits if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2); CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx CKCON |= 0x08; } else if (SYSCLK/BAUDRATE/2/256 < 4) { TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01 CKCON |= 0x09; } else if (SYSCLK/BAUDRATE/2/256 < 12) { TH1 = -(SYSCLK/BAUDRATE/2/12); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00 } else { TH1 = -(SYSCLK/BAUDRATE/2/48); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10 CKCON |= 0x02; } TL1 = TH1; // Init Timer1 TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload TMOD |= 0x20; TR1 = 1; // START Timer1 TI0 = 1; // Indicate TX0 ready } /* void UART0_ISR (void) interrupt 4 { static unsigned char RX_index = 0; //receive buffer index unsigned char the_char; //zwischenspeicher Print_String ("In ISR..."); //Debugausgabe auf UART //RI0 = 0; if (RI0==1) { the_char = SBUF0; RX_buf[RX_index] = the_char; //Byte in array speichern if(RX_index < (RX_length-2)) { RX_index++; } else { RX_index = 0; RX_ready = 1; RX_buf[RX_index-1] = '\0'; } } } */ void Print_String (char pstring[]) { unsigned char i = 0; while (pstring[i]) { putchar(pstring[i++]); } } char nb_getkey () { char c; int i; //Print_String ("In nb_getkey..."); while(!RI0 && i++<100); if(RI0) { c = SBUF; RI0 = 0; } else c = '\3'; return (c); } char b_getkey () { char c; Print_String ("In b_getkey..."); while (!RI0); c = SBUF; RI0 = 0; return (c); }
Aber ich wüsste nicht woran...
Grüße
Bean
So, ich kann jetzt mit dem oben geposteten Code Zeichen an den Controller senden und bekomme diese auch wieder von dem Controller zurück. Es ist ein etwas seltsames Problem. Wenn ich das Programm über den grünen Knopf in der Silicon Labs IDE starte, dann tut sich gar nichts auf der Schnittstelle. Wenn ich dann aber nur die USB Verbindung meines Toolsticks trenne und wieder neu anstöpsel, also quasie ein Hardwarereset mache, dann funktioniert das ganze Spielchen...
Habt ihr mir da eine Idee woran das noch liegen kann? Jetzt will ich mich dann aber doch noch an der UART mit Interrupt versuchen...
Grüße und Danke!
Bean
So na gut
gerade wollte ich dir noch ein paar Tipps geben, wie du deine Hardware checken musst, da ich in der Software nichts auffälliges gefunden hatte.
Der Programmieradapter kann natürlich das Verhalten des UART beeinflussen. Man kann auch sonst nicht einfach zwei Sender parallel am UART betreiben. Dafür müssen sie über Dioden getrennt werden.
Das mit dem Interrupt sollte eigentlich auch kein Problem sein, wenn du nicht vergisst den Interrupt auch einzuschalten.
Mal noch was zum PXMDIN wenn du ein bestimmtes Pin auf Null setzen willst, dann geht das nicht, in dem du einfach alle anderen auf 1 oderst. Du muss den Pin direkt auf Null setzen. Bei deinem P1.4 wäre das
P1MDIN &= ~0x40;// Configure P1.4 as analog input
sast
雅思特史特芬
开发及研究
Hallo
Ich wollte jetzt noch das mit dem Interrupt ausprobieren. Das funktioniert aber leider auch nicht... Hab den meisten Code aus der AN122.
Ich hab so das Gefühl als wenn der Controlller gar nicht in die ISR kommt. Ich hab mir wieder so eine Debug Ausgabe gemacht. Aber auf dem Terminial sehe ich nichts...
Hie mal mein jetziger Code:
Kannst mir da auch noch irgendwie weiter helfen @sast? Alle Anderen dürfen natürlich auch helfenCode:#include <c8051F330.h> #include <stdio.h> #define SYSCLK 24500000 #define BAUDRATE 115200 #define RX_length 25 //----------------------------------------------------------------------------- // Global Variables //----------------------------------------------------------------------------- //bit TX_ready; //True = OK zur Übertragung //char *TX_ptr; //pointer auf zu übermittelnden String bit RX_ready; //True = string empfangen char RX_buf[RX_length]; //Array als Eingangsbuffer anlegen unsigned char the_char; //zwischenspeicher sfr SBUF = 0x99; //----------------------------------------------------------------------------- // Function Prototypes //----------------------------------------------------------------------------- void OSCILLATOR_Init (void); void UART0_Init (void); void PORT_Init (void); void UART0_ISR (void); void Print_String (char pstring[]); char nb_getkey (); char b_getkey (); //----------------------------------------------------------------------------- // main Routine //----------------------------------------------------------------------------- void main (void) { unsigned char c; // Disable Watchdog timer PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer // enable) OSCILLATOR_Init (); // Initialize Oscillator PORT_Init(); // Initialize Port I/O UART0_Init (); // Initialize UART0 EA = 1; //Interrupts global freigeben //ES0 = 1; //UART0 interrupt freigeben while(1) { while (RX_ready == 0); putchar(the_char); } } //----------------------------------------------------------------------------- // Initialization Subroutines //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // OSCILLATOR_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // This routine initializes the system clock to use the internal 24.5MHz // oscillator as its clock source. Also enables missing clock detector reset. // //----------------------------------------------------------------------------- void OSCILLATOR_Init (void) { OSCICN |= 0x03; // Configure internal oscillator for // its maximum frequency RSTSRC = 0x04; // Enable missing clock detector } //----------------------------------------------------------------------------- // PORT_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // P0.4 digital push-pull UART TX // P0.5 digital open-drain UART RX // //----------------------------------------------------------------------------- void PORT_Init (void) { P0SKIP |= 0x01; // Skip P0.0 for external VREF P1MDIN |= 0xEF; // Configure P1.4 as analog input. P0MDOUT |= 0x10; // enable UTX as push-pull output XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX) XBR1 = 0x40; // Enable crossbar and weak pull-ups } //----------------------------------------------------------------------------- // UART0_Init //----------------------------------------------------------------------------- // // Return Value : None // Parameters : None // // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1. // //----------------------------------------------------------------------------- void UART0_Init (void) { SCON0 = 0x10; // SCON0: 8-bit variable bit rate // level of STOP bit is ignored // RX enabled // ninth bits are zeros // clear RI0 and TI0 bits if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2); CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx CKCON |= 0x08; } else if (SYSCLK/BAUDRATE/2/256 < 4) { TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01 CKCON |= 0x09; } else if (SYSCLK/BAUDRATE/2/256 < 12) { TH1 = -(SYSCLK/BAUDRATE/2/12); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00 } else { TH1 = -(SYSCLK/BAUDRATE/2/48); CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10 CKCON |= 0x02; } TL1 = TH1; // Init Timer1 TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload TMOD |= 0x20; TR1 = 1; // START Timer1 TI0 = 1; // Indicate TX0 ready } void UART0_ISR (void) interrupt 4 using 3 { static unsigned char RX_index = 0; //zwischenspeicher unsigned char the_char; if(RI0 == 1) { Print_String ("In ISR..."); //Debugausgabe auf UART RI0 = 0; if(RX_ready != 1) { the_char = SBUF0; if (the_char != '\#') RX_buf[RX_index] = the_char; if(RX_index < (RX_length -2)) { RX_index++; } else { RX_index = 0; RX_ready = 1; RX_buf[RX_index-1] = '\0'; } } } } void Print_String (char pstring[]) { unsigned char i = 0; while (pstring[i]) { putchar(pstring[i++]); } } /* char nb_getkey () { char c; int i; //Print_String ("In nb_getkey..."); while(!RI0 && i++<100); if(RI0) { c = SBUF; RI0 = 0; } else c = '\3'; return (c); } char b_getkey () { char c; //Print_String ("In b_getkey..."); while (!RI0); c = SBUF; RI0 = 0; return (c); } */
Grüße!
Bean
Moin,
zum Interrupt: Du musst natürlich ES0 auch wieder einschalten.
Das RI0 = 0; würde ich ganz zum Schluss in der Routine verwenden.
Hast du mal den letzten Teil meine letzten Beitrages durchgelesen.
sast
雅思特史特芬
开发及研究
Ja hab ich gelesen. Aber die KOnfiguration der Ports kommt so aus dem Config Tool von SiLabs raus. Darum hab ich das so genommen.
Du meinst ES0 direkt nach den globalen Interrupts freigeben?
Grüße
Bean
Lesezeichen