sidartha
Newbie level 2
I am trying to code a sotware uart and a hardware uart for the 8051C410..
the hardware uart is for communicating with the pc an software uart for an attached sensor..
however though the hardware uart works fine the software uart does not..
i have attached the code and was hoping someone here could help me..
[/code]
//#pragma large
#include <c8051f410.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SYSCLK 24500000/8
#define BAUDRATE 9600
#define TIME_COUNT SYSCLK/9600/12 // PCA counts for one bit-time.
#define TH_TIME_COUNT TIME_COUNT*3/2 // 3/2 bit-time, PCA/ SWUART
//----------------------------------------------------------------------------------------------
sbit SW_TX = P2^6;
sbit SW_RX = P1^0;
bit SM_BUSY;
bit SRI; // SW_UART Receive Complete Indicator
bit STI; // SW_UART Transmit Complete Indicator
bit STXBSY; // SW_UART TX Busy flag
bit SREN; // SW_UART RX Enable
bit SES; // SW_UART User-level Interrupt Support
char TDR; // SW_UART TX Data Register
char RDR; // SW_UART RX Data Register
//----------------------------------------------------------------------------------------------
//FUNCTION PROTOTYPE
//----------------------------------------------------------------------------------------------
void init_uart0 (void);
void SYSCLK_Init (void);
void PORT_Init (void);
void enable_intr(void);
void init_swuart(void);
void WriteSwuart (char *ptr);
//----------------------------------------------------------------------------------------------
// MAIN Routine
//----------------------------------------------------------------------------------------------
void main (void) {
xdata char str[100];
int i=0,n=0;
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
PCA0MD =0X00;
PORT_Init (); // Initialize crossbar and GPIO
SYSCLK_Init (); // Initialize system clock to
init_uart0 ();
init_swuart();
enable_intr();
STI=1;
while(1)
{
sprintf (str,"hello %d\r",n++);
WriteSwuart (str);
}
}
//----------------------------------------------------------------------------------------------
void WriteSwuart (char *ptr){
bit transmit=1;
while(transmit){
if(STI){
STI=0;
TDR = *ptr;
if(*ptr=='\r') transmit=0;
CCF1=1;
ptr++;
}
}
}
//----------------------------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN = 0x84;
}
//----------------------------------------------------------------------------------------------
void PORT_Init (void)
{
P0SKIP = 0xCF;
XBR0 = 0x01; // uart0, spi, smbus selected
XBR1 = 0x41; // Enable crossbar and weak pull-ups
P1MDOUT |= 0xFF;
P2MDOUT |= 0xFF;
RE=0;
P0MDIN = ~0x08;
}
//----------------------------------------------------------------------------------------------
void init_uart0 (void)
{
SCON0 = 0x10;
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0X0B;
CKCON |= 0X08;
TL1=TH1;
TMOD&= ~0XF0;
TMOD |= 0X20;
TR1=1;
TI0=1;
}
//----------------------------------------------------------------------------------------------
void enable_intr(void) {
SREN = 0; // disable SW_UART Receiver
CR = 1; // Start PCA counter.
EIE1|=0x10;
EIE1 |= 0x81; // SPI, SMBus interrupt enable
EIP1 |=0x01;
EX0 =1;
IT0 =1;
ET2 =1;
ES0=1;
EA=1;
}
//----------------------------------------------------------------------------------------------
void init_swuart(void){
PCA0CPM0 = 0x10; // Module0 in negative capture mode;
// module 0 interrupt disabled.
PCA0CPM1 = 0x48; // Module 1 in software timer mode;
// module1 interrupt disabled.
PCA0CN = 0; // Leave PCA disabled
PCA0MD |= 0x00; // PCA timebase = SYSCLK/4; PCA counter
// interrupt disabled.
CCF0 = 0; // Clear pending PCA module 0 and
CCF1 = 0; // module 1 capture/compare interrupts.
SRI = 0; // Clear Receive complete flag.
STI = 0; // Clear Transmit complete flag.
SW_TX = 1; // TX line initially high.
STXBSY = 0; // Clear SW_UART Busy flag
PCA0CPM0 |= 0x01; // Enable module 0 (receive)interrupts.
PCA0CPM1 |= 0x01; // Enable module 1(transmit)interrupts.
}
//----------------------------------------------------------------------------------------------
//Software UART////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------------
void PCA_ISR(void) interrupt 11 {
static char SUTXST = 0;
static char SURXST = 0;
static unsigned char RXSHIFT;
unsigned int PCA_TEMP;
if (CCF0){
CCF0 = 0;
switch (SURXST){
case 0:
if (SREN & ~SW_RX){
PCA_TEMP = (PCA0CPH0 << 8 ) ;
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TH_TIME_COUNT;
PCA0CPL0 = PCA_TEMP;
PCA0CPH0 = (PCA_TEMP >> 8 ) ;
PCA0CPM0 = 0x49;
SURXST++;
}
break;
case 1: case 2: case 3: case 4: case 5: case 6:case 7: case 8:
RXSHIFT = RXSHIFT >> 1;
if (SW_RX)
RXSHIFT |= 0x80;
PCA_TEMP = (PCA0CPH0 << 8 ) ;
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TIME_COUNT;
PCA0CPL0 = PCA_TEMP;
PCA0CPH0 = (PCA_TEMP >> 8 ) ;
SURXST++;
break;
case 9:
RDR = RXSHIFT;
SRI = 1;
PCA0CPM0 = 0x11;
SURXST = 0;
break;
}
}
// Check Transmit interrupt; service if CCF1 is set.
else if (CCF1){
CCF1 = 0;
switch (SUTXST){
case 0:
SW_TX = 0;
PCA_TEMP = PCA0L;
PCA_TEMP |= (PCA0H << 8 ) ;
PCA_TEMP += TIME_COUNT;
PCA0CPL1 = PCA_TEMP;
PCA0CPH1 = (PCA_TEMP >> 8 ) ;
PCA0CPM1 |= 0x48;
SUTXST++;
break;
case 1:case 2:case 3:case 4: case 5:case 6: case 7:case 8: case 9:
SW_TX = (TDR & 0x01);
TDR >>= 1;
TDR |= 0x80;
PCA_TEMP = (PCA0CPH1 << 8 ) ;
PCA_TEMP |= PCA0CPL1;
PCA_TEMP += TIME_COUNT;
PCA0CPL1 = PCA_TEMP;
PCA0CPH1 = (PCA_TEMP >> 8 ) ;
SUTXST++;
break;
case 10:
STI = 1;
SUTXST = 0;
SW_TX = 1;
PCA0CPM1 = 0x01;
STXBSY = 0;
break;
}
}
}
the hardware uart is for communicating with the pc an software uart for an attached sensor..
however though the hardware uart works fine the software uart does not..
i have attached the code and was hoping someone here could help me..
[/code]
//#pragma large
#include <c8051f410.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SYSCLK 24500000/8
#define BAUDRATE 9600
#define TIME_COUNT SYSCLK/9600/12 // PCA counts for one bit-time.
#define TH_TIME_COUNT TIME_COUNT*3/2 // 3/2 bit-time, PCA/ SWUART
//----------------------------------------------------------------------------------------------
sbit SW_TX = P2^6;
sbit SW_RX = P1^0;
bit SM_BUSY;
bit SRI; // SW_UART Receive Complete Indicator
bit STI; // SW_UART Transmit Complete Indicator
bit STXBSY; // SW_UART TX Busy flag
bit SREN; // SW_UART RX Enable
bit SES; // SW_UART User-level Interrupt Support
char TDR; // SW_UART TX Data Register
char RDR; // SW_UART RX Data Register
//----------------------------------------------------------------------------------------------
//FUNCTION PROTOTYPE
//----------------------------------------------------------------------------------------------
void init_uart0 (void);
void SYSCLK_Init (void);
void PORT_Init (void);
void enable_intr(void);
void init_swuart(void);
void WriteSwuart (char *ptr);
//----------------------------------------------------------------------------------------------
// MAIN Routine
//----------------------------------------------------------------------------------------------
void main (void) {
xdata char str[100];
int i=0,n=0;
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
PCA0MD =0X00;
PORT_Init (); // Initialize crossbar and GPIO
SYSCLK_Init (); // Initialize system clock to
init_uart0 ();
init_swuart();
enable_intr();
STI=1;
while(1)
{
sprintf (str,"hello %d\r",n++);
WriteSwuart (str);
}
}
//----------------------------------------------------------------------------------------------
void WriteSwuart (char *ptr){
bit transmit=1;
while(transmit){
if(STI){
STI=0;
TDR = *ptr;
if(*ptr=='\r') transmit=0;
CCF1=1;
ptr++;
}
}
}
//----------------------------------------------------------------------------------------------
void SYSCLK_Init (void)
{
OSCICN = 0x84;
}
//----------------------------------------------------------------------------------------------
void PORT_Init (void)
{
P0SKIP = 0xCF;
XBR0 = 0x01; // uart0, spi, smbus selected
XBR1 = 0x41; // Enable crossbar and weak pull-ups
P1MDOUT |= 0xFF;
P2MDOUT |= 0xFF;
RE=0;
P0MDIN = ~0x08;
}
//----------------------------------------------------------------------------------------------
void init_uart0 (void)
{
SCON0 = 0x10;
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON &= ~0X0B;
CKCON |= 0X08;
TL1=TH1;
TMOD&= ~0XF0;
TMOD |= 0X20;
TR1=1;
TI0=1;
}
//----------------------------------------------------------------------------------------------
void enable_intr(void) {
SREN = 0; // disable SW_UART Receiver
CR = 1; // Start PCA counter.
EIE1|=0x10;
EIE1 |= 0x81; // SPI, SMBus interrupt enable
EIP1 |=0x01;
EX0 =1;
IT0 =1;
ET2 =1;
ES0=1;
EA=1;
}
//----------------------------------------------------------------------------------------------
void init_swuart(void){
PCA0CPM0 = 0x10; // Module0 in negative capture mode;
// module 0 interrupt disabled.
PCA0CPM1 = 0x48; // Module 1 in software timer mode;
// module1 interrupt disabled.
PCA0CN = 0; // Leave PCA disabled
PCA0MD |= 0x00; // PCA timebase = SYSCLK/4; PCA counter
// interrupt disabled.
CCF0 = 0; // Clear pending PCA module 0 and
CCF1 = 0; // module 1 capture/compare interrupts.
SRI = 0; // Clear Receive complete flag.
STI = 0; // Clear Transmit complete flag.
SW_TX = 1; // TX line initially high.
STXBSY = 0; // Clear SW_UART Busy flag
PCA0CPM0 |= 0x01; // Enable module 0 (receive)interrupts.
PCA0CPM1 |= 0x01; // Enable module 1(transmit)interrupts.
}
//----------------------------------------------------------------------------------------------
//Software UART////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------------------------
void PCA_ISR(void) interrupt 11 {
static char SUTXST = 0;
static char SURXST = 0;
static unsigned char RXSHIFT;
unsigned int PCA_TEMP;
if (CCF0){
CCF0 = 0;
switch (SURXST){
case 0:
if (SREN & ~SW_RX){
PCA_TEMP = (PCA0CPH0 << 8 ) ;
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TH_TIME_COUNT;
PCA0CPL0 = PCA_TEMP;
PCA0CPH0 = (PCA_TEMP >> 8 ) ;
PCA0CPM0 = 0x49;
SURXST++;
}
break;
case 1: case 2: case 3: case 4: case 5: case 6:case 7: case 8:
RXSHIFT = RXSHIFT >> 1;
if (SW_RX)
RXSHIFT |= 0x80;
PCA_TEMP = (PCA0CPH0 << 8 ) ;
PCA_TEMP |= PCA0CPL0;
PCA_TEMP += TIME_COUNT;
PCA0CPL0 = PCA_TEMP;
PCA0CPH0 = (PCA_TEMP >> 8 ) ;
SURXST++;
break;
case 9:
RDR = RXSHIFT;
SRI = 1;
PCA0CPM0 = 0x11;
SURXST = 0;
break;
}
}
// Check Transmit interrupt; service if CCF1 is set.
else if (CCF1){
CCF1 = 0;
switch (SUTXST){
case 0:
SW_TX = 0;
PCA_TEMP = PCA0L;
PCA_TEMP |= (PCA0H << 8 ) ;
PCA_TEMP += TIME_COUNT;
PCA0CPL1 = PCA_TEMP;
PCA0CPH1 = (PCA_TEMP >> 8 ) ;
PCA0CPM1 |= 0x48;
SUTXST++;
break;
case 1:case 2:case 3:case 4: case 5:case 6: case 7:case 8: case 9:
SW_TX = (TDR & 0x01);
TDR >>= 1;
TDR |= 0x80;
PCA_TEMP = (PCA0CPH1 << 8 ) ;
PCA_TEMP |= PCA0CPL1;
PCA_TEMP += TIME_COUNT;
PCA0CPL1 = PCA_TEMP;
PCA0CPH1 = (PCA_TEMP >> 8 ) ;
SUTXST++;
break;
case 10:
STI = 1;
SUTXST = 0;
SW_TX = 1;
PCA0CPM1 = 0x01;
STXBSY = 0;
break;
}
}
}