-
hmm also ich hab jetzt nochmal folgenden Code ausprobiert:
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;
sbit RI = 0x98;
//-----------------------------------------------------------------------------
// 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)
{
// 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)
{
nb_getkey ();
b_getkey ();
}
}
//-----------------------------------------------------------------------------
// 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(!RI && i++<100);
if(RI)
{
c = SBUF;
RI = 0;
}
else
c = '\3';
return (c);
}
char b_getkey ()
{
char c;
Print_String ("In b_getkey...");
while (!RI);
c = SBUF;
RI = 0;
return (c);
}
Da wird wenn ich den Controller starte jeweils einmal in nb_getkey und einmal in b_getkey gesprungen. Ich lass mir das jeweils auf dem Terminal ausgeben. Aber Zeichen kann ich so nicht empfangen. :-k
Mit der Abfrage hast recht, das muss ich noch ändern.
Aber im Moment will ich eigentlich nur mal ein Zeichen aus Sbuf auslesen... 8-[
Grüße!
Bean
-
Ich weiß nicht ob SBUF und RI bei dir die gleichen Register sind wie beim F300. Dazu musst du schon mal etwas in deiner Dokumentation schnüffeln. Im Datenblatt hatten die den UART0 auch immer mit RI0 betitelt (siehe Seite 90). Die Definition könnte auch in der Headerdatei zu deinem Kontroller stehen. Also nimm lieber die aus dem Header. Mein Code war nur als Beispiel gemeint.
sfr SBUF = 0x99;
sbit RI = 0x98;
sollten bei dir dann eigentlich nicht nötig sein.
nb_ bedeutet nicht blockierend und b_ logischerweise blockierend.
Du benötigst nur eins von beiden, je nach deiner Strategie.
Er läuft also in der main bis b_getkey und hängt dann dort für alle Ewigkeit bis das der Strom euch scheidet.
Das letzte was du siehst sollte also erst mal In b_getkey... sein.
Wenn du bis dahin kommst läuft dein Programm soweit. Die Funktionsrückgaben solltest du dann in der main in einem Print ausgeben.
Aber als erstes sollten deine SFR richtig zugewiesen sein. Sonst kommt da nie was an und natürlich muss auch hardwaremäßig an P0.5 was wackeln. Hast du das mal überprüft? Portseitig muss man da ja nichts weiter einstellen, wenn ich mich recht erinnere. Nur der Crossbar sollte passen. Das musst du aber alleine Überprüfen. Ich kann nur immer wieder betonen: Datenblatt lesen!
PS: es kann sein, dass es eine Funktion getkey() bereits gibt. Wenn ja dann sieh bitte dort mal nach, welche Register die genommen haben, das geht meist am schnellsten
sast
-
Hallo
Ja die SFR hab ich schon kontrolliert. Das passt. Ich hab jetzt auch einfach für RI gleich RI0 geschrieben, dann brauch ich die Definition am Anfang ja nicht. SBUF0 passt auch mit 0x99.
Hab das Datenblatt schon gelesen. ;-) Das Problem liegt glaube ich eher in der Programmierung mit C.
Wie gebe ich die Funktionsrückgabe in main aus? Einfach mit printf(c); ?
Die Rückgabe ist doch c oder? In b_ steht ja "return (c);".
Pin 0.5 hab ich mit dem Oszi kontrolliert. Der wackelt.
Danke schonmal!
Grüße!
Bean
-
Genau
Code:
...
unsigned char c;
...
while(1)
{
c = b_getkey();
printf("%c\n", c);//oder putchar(c);
}
...
Du musst dir nur verinnerlichen, dass das c aus der Funktion b_getkey() nicht das ist, welches global gilt. Deshalb hab ich es noch mal explizit in die Codetags mit aufgenommen.
sast
-
Hmm wenn ich das so mache, bekomme ich einen Feher: "illegal pointer conversion". :-(
Dachte eigentlich auch so müsste das funktionieren... :-(
Grüße Bean
-
Ja weil printf() als erstes Argument einen FormatString erwartet. Habs oben angepasst.
sast
PS: Falls du mit der Keil Software C51 arbeitest, gibts auch schon die _getkey() Funktion, die genau das selbe macht wie mein b_getkey().
Code:
_getkey
Summary: #include <stdio.h>
char _getkey (void);
Description: The _getkey function waits for a character to be received
from the serial port.
NOTE
This routine is implementation-specific, and its function may
deviate from that described above. Source is included for
the _getkey and putchar functions which may be modified to
provide character level I/O for any hardware device. Refer
to “Customization Files” on page 150 for more information.
Return Value: The _getkey routine returns the received character.
-
Also mit:
Code:
while(1)
{
c= nb_getkey ();
putchar(c);
}
Bekomme ich wenn ich über das Terminal etwas sende auch etwas zurück. Aber meistens Leerzeichen oder anderen Datenmüll...
Aber das ist ja schonmal ein Anfang...
Ich verwende nicht den Keil, sondern die original IDE von SiLabs. Als Compiler hab ich den Keil aber eingebunden.
Was noch komisch ist, ist dass der Controller wohl ständig noch irgendwas sendet. Ich hab eine LED an Tx und die leuchtet eigentlich durchgehend.
Ich weiß aber nicht was das noch sein könnte... :-(
Grüße!
Bean
-
Wenn du ständig putchar() aufrufst muss er ja auch was senden. Wie ich oben schon gesagt hatte, ist nb_getkey() nichtblockierend. Nutze doch einfach mal die stdio.h Funktion _getkey. Die ist blockierend und dein putchar() sendet nur noch wenn der RX auch was bekommt.
Wie hast du denn die LED angeschlossen? An TX und VCC?
sast
-
Naja die LED ist irgendwie in meinem Interface zwischen USB und RS232 angeschlossen. Wie weiß ich nicht.
das mit _getkey versuch ich jetzt mal noch.
Danke schonmal!
Grüße!
Bean
-
Wie?
Du kannst mit dem Oszi ein Signal messen, aber was auf der anderen Seite an der LED liegt kannst du nicht messen?
Verwirrt ich bin ;o)
sast