-
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
-
ok dann benutzt du die b_getkey()
blockierend heißt einfach, dass die Funktion solange wartet bis ein Zeichen über die UART Schnittstelle reinkommt. Bei der nichtblockierenden Funktion wird nach einer vorgegebenen Wartezeit die Funktion verlassen, auch wenn da nichts vom UART kam.
sast
-
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:
Code:
char b_getkey ()
{
char c;
Print_String ("In b_getkey...");
while (!RI0);
c = SBUF;
RI0 = 0;
return (c);
}
In diesem Fall wird "In b_getkey..." einmal auf dem Terminal ausgegeben. Dann hänge ich denke ich in der folgenden while Schleife... :-(
Meine main sieht jetzt so aus:
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);
}
}
Was könnte das noch sein? Ich verzweifle so langsam... Mit den AtMegas hat das ganze irgendwie besser und einfacher funktioniert... ;-)
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:
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);
}
Ja kann natürlich sein dass das an der Crossbar liegt... :-k
Aber ich wüsste nicht woran... :-k
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... 8-[
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:
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)
{
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);
}
*/
Kannst mir da auch noch irgendwie weiter helfen @sast? Alle Anderen dürfen natürlich auch helfen ;-)
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