MCU User Forum
  UART0 - 2 devices at once

Post New Topic  Post A Reply
profile | register | preferences | faq | search

UBBFriend: Email This Page to Someone! next newest topic | next oldest topic
Author Topic:   UART0 - 2 devices at once
trc4000
Member
posted August 31, 2010 08:24 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
how do we configure 2 devices connected on the same UART0 port. Such as setting the prriotorites and preventing conflicts???

IP: Logged

trc4000
Member
posted August 31, 2010 08:25 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
Sorry this for the C8051F120 development board.

IP: Logged

Scotty
Member
posted September 01, 2010 12:37 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

how do we configure 2 devices connected on the same UART0 port. Such as setting the prriotorites and preventing conflicts???
Usually a UART is connected to only one device. Since you didn't specify which devices are connected, I can only give general information. For connecting two or more device to a UART there are several ways:
1) The 8051 standard UART is capable of multiprocessor communication. This is done with 9-Bit communication, where the 9th bit indicates if a adress or data is transmitted. The UART will ignore data packets (and therefore their interrupts) until a adress packet is received. The ISR checks if the adress matches and enables data packet receiving.
2) RS485 2-wire interface: This approach needs a external RS485 driver on both sides and a additional port pin for direction control. Each member has its own bus adress. A protocol is used where each transfer belongs to a bus adress. There can be multiple masters if needed. All bus members are in receive mode and transfer data only when the master request it. If multiple masters are used, special RS485 transceivers should be used to avoid electrical bus errors when two or more masters initiate a transfer at the same time. It must be ensured that only the adressed device sends data. Since the Tx pins are connected together you may not enable push-pull without series resistor for current limit or a diode from each Tx pin.
3) F120 supports two UARTs, why don't you use the second one?
4) Use a external switch and select the connection with a GPIO. For example, two 74LVC2G241 may fit. I'd choose this option if the connected devices are not allowed to receive the data which is for the other device.
5) Connect F120 Tx to the Rx pin of the two devices. Connect a diode from each device Tx pin (Cathode) to the F120 Rx pin (Anode).
6) If one of the devices uses a slow baudrate you can implement a software UART.

Regards,

Scotty

IP: Logged

erikm
Member
posted September 01, 2010 06:10 AM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
how do we configure 2 devices connected on the same UART0 port. Such as setting the prriotorites and preventing conflicts???
You can't unless you implement a master-slave protocol.

Erik

IP: Logged

trc4000
Member
posted September 01, 2010 10:01 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
ok thanks for the insightful information.

the C8051F120, does have an extra uart (known as UART1). However i am unable to establish any communication on this bit 1.1 (To receive data from an RFID reader). Seems to work only on uart0. Hence i was wondering whether its possible to connect 2 devices at once on uart0.

I would like to use an interrupt based approach to read RFID tags via uart1.
Not sure about the intialization bit.........


//------------------------------------------------------------------------------------// PORT_Init//------------------------------------------------------------------------------------//// Configure the Crossbar and GPIO ports//void PORT_Init (void){ char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page SFRPAGE = CONFIG_PAGE; // Set SFR page //XBR0 = 0x04; // Enable UART0 // XBR1 = 0x00;//XBR0 = 0x37; // UART1 on P1.0 and P1.1//XBR2 |= 0xC4; // UART1 on P1.0 and P1.1; crossbar started // XBR2 = 0x40; // Enable crossbar and weak pull-up XBR0 = 0x00; XBR1 = 0x00; XBR2 = 0x44; // Enable crossbar and weak pull-up // Enable UART1 P0MDOUT |= 0x01; // P1MDOUT |= 0x01; // Set TX pin to push-pull P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull//P1MDIN = 0x01; SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}

void UART1_Init (void){ char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page SFRPAGE = UART1_PAGE; SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RX SFRPAGE = TIMER01_PAGE; TMOD &= ~0xF0; TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload if (SYSCLK/BAUDRATE/2/256 < 1) { TH1 = -(SYSCLK/BAUDRATE/2); CKCON |= 0x10; // T1M = 1; SCA1:0 = xx } else if (SYSCLK/BAUDRATE/2/256 < 4) { TH1 = -(SYSCLK/BAUDRATE/2/4); CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x01; // T1M = 0; SCA1:0 = 01 } else if (SYSCLK/BAUDRATE/2/256 < 12) { TH1 = -(SYSCLK/BAUDRATE/2/12); CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00 } else { TH1 = -(SYSCLK/BAUDRATE/2/48); CKCON &= ~0x13; // Clear all T1 related bits CKCON |= 0x02; // T1M = 0; SCA1:0 = 10 } TL1 = TH1; // Initialize Timer1 TR1 = 1; // Start Timer1 SFRPAGE = UART1_PAGE; TI1 = 1; // Indicate TX1 ready SFRPAGE = SFRPAGE_SAVE; // Restore SFR page}

IP: Logged

trc4000
Member
posted September 01, 2010 10:07 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
sorry about the bad code post before.
i have fixed it now....

void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page


XBR0 = 0x00;
XBR1 = 0x00;
XBR2 = 0x44; // Enable crossbar and weak pull-up
// Enable UART1

P0MDOUT |= 0x01;
// P1MDOUT |= 0x01; // Set TX pin to push-pull
P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
//P1MDIN = 0x01;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}

void UART1_Init (void){
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = UART1_PAGE;
SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RX
SFRPAGE = TIMER01_PAGE;
TMOD &= ~0xF0;
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
if (SYSCLK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSCLK/BAUDRATE/2);
CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
}
else if (SYSCLK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSCLK/BAUDRATE/2/4);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x01; // T1M = 0; SCA1:0 = 01
}
else if (SYSCLK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSCLK/BAUDRATE/2/12);
CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00
}
else { TH1 = -(SYSCLK/BAUDRATE/2/48);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x02; // T1M = 0; SCA1:0 = 10
}
TL1 = TH1; // Initialize Timer1
TR1 = 1; // Start Timer1
SFRPAGE = UART1_PAGE;
TI1 = 1; // Indicate TX1 ready
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}

IP: Logged

Scotty
Member
posted September 02, 2010 12:26 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

However i am unable to establish any communication on this bit 1.1 (To receive data from an RFID reader). Seems to work only on uart0.
Provide more information. What is not working with UART1? Not sending? Not receiving?

Regards,

Scotty

IP: Logged

trc4000
Member
posted September 02, 2010 01:40 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
i am unable to receive RFUD TAG numbers via bit P1^1. I assuming this due to incorrect intialisation of Port 1 to be used for UART1 communication.

IP: Logged

Scotty
Member
posted September 02, 2010 05:12 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

i am unable to receive RFUD TAG numbers via bit P1^1. I assuming this due to incorrect intialisation of Port 1 to be used for UART1 communication.
Yes, because if you enable UART1 only, it will be placed on P0, not P1.
1) show your complete code
2) is UART0 connected to PC?
3) Does the UART1 example provided in examples folder of current SiLabs IDE installation work?

For 2), if answer is yes, then disconnect the RFID reader, short TX1 and RX1 together. Write a small software where incoming data on UART0 is forwarded to UART1 and vice versa. Using a terminal program on PC side this should give a echo and is a test for Rx/Tx.

If UART0 is not connected to a PC, then simply make a loop where a value (e.g.0x55) is continously transmitted via UART1 and check the pin.
If transmission is okay, then you have to check why receiving is not possible. This can be done by shorting RX1/TX1 together. If the incoming data is the same as the transmitted data you can light up a LED or something similar.
Then, when you've checked the UART itself, you can check why nothing is received from the RFID reader.

Regards,

Scotty

[This message has been edited by Scotty (edited September 02, 2010).]

IP: Logged

trc4000
Member
posted September 15, 2010 07:30 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
the RFID reader works on P0^1 for read when uart 0 is not used (only uart 1 enabled).

When i use uart 0 and uart 1 together, uart1 RX should be at P1^1 . However i recieve no serial data through this pin, when reading SBUF1.

here is my code


//------------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------------
// SFR declarations
#include
#include
//#include

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------
sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 TMR2 = 0xcc; // Timer2
//--------------------------------------------------
sfr16 RCAP3 = 0xCA; // Timer3 reload value
sfr16 TMR3 = 0xCC; // Timer3 counter----------------------------------
// Global VARIABLES
//------------------------------------------------------------------------------------
unsigned int time=0,counter=0,testcount=0,sendtimer=0,RightTimeout=0,LeftTimeout=0;
unsigned char currentright=0,speed=0,counterleft=0,counterright=0,speedleft=0;
unsigned char speedright=0,irfloor=0,PCstate,state,motionl;
xdata unsigned char lnew_count=0, rnew_count=0,distance=0;
xdata double pos_x=0,pos_y=0,angle=0;
xdata char LeftCount=0,RightCount=0;
unsigned int temp=0;

static char dis_left_old, dis_left,l_rev;
static char dis_right_old, dis_right, r_rev, dis_base;
unsigned int ex0_isr_counter = 0, ex1_isr_counter=0;
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define BAUDRATE 9600//38400 // Baud rate of UART in bps
#define BAUDRATE2 9600 // Baud rate of UART in bps
// SYSTEMCLOCK = System clock frequency in Hz
#define SYSTEMCLOCK (22118400L * 9 / 4)
#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

//#define SYSCLK 24500000 // Clock speed in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit SWITCH = P3^7; // Push-button switch on board
//sbit test = P3^6;
//sbit INT1 = P3^3;
//sbit INT0 = P1^6;
sbit left_ir = P3^1;
sbit right_ir = P3^0;
sbit front_ir = P3^3;
int i;
int flag = 0;

#define UART_BUFFERSIZE 14
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
static char Byte =0;
unsigned char card1[UART_BUFFERSIZE] = {02,50,57,48,48,57,52,48,66,52,54,70,48,03};
//unsigned char card2[UART_BUFFERSIZE] = {02,50,53,48,48,65,67,49,53,55,65,69,54,03};
//unsigned char card3[UART_BUFFERSIZE] = {0 ,53,53,03 };
//unsigned char card4[UART_BUFFERSIZE] = {02,50,53,48,48,65,67,49,69,66,66,50,67,03};
//unsigned char card5[UART_BUFFERSIZE] = {02,50,53,48,48,65,66,67,68,67,48,56,51,03};
//unsigned char card6[UART_BUFFERSIZE] = {02,50,53,48,48,65,67,49,67,56,52,49,49,03};
//unsigned char card7[UART_BUFFERSIZE] = {02,50,57,48,48,57,52,49,57,50,50,56,54,03};
//unsigned char card8[UART_BUFFERSIZE] = {02,50,57,48,48,57,51,69,57,70,70,65,67,03};
//unsigned char card9[UART_BUFFERSIZE] = {02,50,57,48,48,57,52,49,54,69,65,52,49,03};
//unsigned char card10[UART_BUFFERSIZE] = {02,50,55,48,48,51,57,66,50,48,49,65,68,03};
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void PORT_Init (void);
//void Timer3_Init (int counts);
void Timer2_ISR (void);
//void tempo(void);
void OSCILLATOR_Init (void);
void UART0_Init (void);
void UART1_Init (void);
void motor0Forward(unsigned int speed);
void sendByte(char byteToSend);
void Ext_Interrupt_Init (void); // Configure External Interrupts (/INT0
// and /INT1)

void motor1Forward(unsigned int speed);
void motor0Reverse(unsigned int speed);
void motor1Reverse(unsigned int speed);
void motor0Coast();
void motor1Coast();
void stopBothMotors();
void stopMotor0();
void stopMotor1();

void ReverseRight();
void ReverseLeft();
void wallfollow();
// OTHER VARIABLES

//unsigned char gone = 0;

#define INITIALPACKET 0xAA
#define MOTOR0FORWARDPACKET 0x88
#define MOTOR0FORWARDFASTPACKET 0x89
#define MOTOR0REVERSEPACKET 0x8A
#define MOTOR0REVERSEFASTPACKET 0x8B

#define MOTOR1FORWARDPACKET 0x8C
#define MOTOR1FORWARDFASTPACKET 0x8D
#define MOTOR1REVERSEPACKET 0x8E
#define MOTOR1REVERSEFASTPACKET 0x8F

#define MOTOR0COASTPACKET 0x86
#define MOTOR1COASTPACKET 0x87
#define FWVERSIONPACKET 0x81
#define ERRORPACKET 0x82
#define GETCONFIG 0x83
#define SETCONFIG 0x84

//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
// disable watchdog timer
WDTCN = 0xde;
WDTCN = 0xad;

SFRPAGE = CONFIG_PAGE; // Switch to configuration page
OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO
Ext_Interrupt_Init(); // Initialize External Interrupts

UART0_Init (); // Initialize UART0
UART1_Init (); // Initialize UART1
// SFRPAGE = TMR3_PAGE; // Switch to Timer 3 page
// prepare the pin
//left_ir = 0;
//make it an input pin
//left_ir = 1;

//if (left_ir == 1) {

// Timer3_Init (SYSCLK / 12 / 10); // Init Timer3 to generate interrupts
// at a 10 Hz rate.
//TCON = 0x00; // Stop Timer0; Clear TF0;
//TCON = 0x05; // /INT 0 and /INT 1 are falling edge
// triggered
// IE |= 0x85;

//IT0 = 1; // Configure interrupt 0 for falling edge on /INT0 (P3.2)
//EX0 = 1; // Enable EX0 Interrupt
EA = 1; // Enable Global Interrupt Flag
// IE = 0xA0;
// EIE1=0x08;
// EIP1=0x08;
SFRPAGE = UART0_PAGE;
sendByte(INITIALPACKET);
//SFRPAGE = LEGACY_PAGE; // Page to sit in for now
// MoveForwardRight();
//motor0Forward(127);
//motor1Forward(127);
// motor1Forward(27);
// temp=0;
motor0Reverse(57);
motor1Reverse(57);

while(1) {

//wallfollow();
if (UART_Buffer[10,11] == card1[10,11]) {
LED = ~LED;
stopBothMotors();
}

// while(left_ir == 0 && front_ir==0 )
// {
// stopMotor1();

// ex0_isr_counter = 0;
// motor0Reverse(57);

// }

// if (ex0_isr_counter>205) //411
// {

// motor1Reverse(57);
// ex0_isr_counter = 0;
// }

// if (ex0_isr_counter>411)
//if (front_ir==1)
// {
//stopBothMotors();
// stopBothMotors();
//ex0_isr_counter = 0;
//temp = 0;
// }
//lnew_count = temp;
//if (!test)
//{
//while (!test)
//{
//}
//ex0_isr_counter++;
//}
//lnew_count=ex0_isr_counter;


// time++;


//Left Speed & Distance Calculation

//speedleft = lnew_count/time;//time; //interrupts per sample time (we assume 10ms)
// l_rev=speedleft/224; //revolutions per sample time
//l_rev=lnew_count/224;
// dis_left =22/lnew_count; //left wheel distance in cm
//dis_left = (22/224)*lnew_count;
// dis_l_average = (dis_left+dis_lef_old)/2;

// if ((dis_left>(dis_l_average/2)))
// {
// dis_left = dis_left_old;
// }


//dis_right = 0;

//Pose Calculations

//distance=dis_right+dis_left/2;
//dis_base=16; //distance between the two wheels in cm

//angle =((dis_left-dis_right)/dis_base)*(360/(2*3.1457)); //angle in radians
//pos_x = distance*cos(angle);
//pos_y = distance*sin(angle);

//if (angle>90)
//{
//stopBothMotors();
//temp=0;
//}


}//}
}


//void ex0_isr (void) interrupt 2
//{
//ex0_isr_counter++; // Increment the count
//LED = !LED;
//}
//void tempo(void) interrupt 2
//{
// if (test==0){
///temp++;
//test=1;
//}
//if (temp>265){
//stopBothMotors();
//temp = 0;
//}
//}
void wallfollow()
{
while (flag == 0){
//motor1Forward(127);
while (left_ir == 1)
{
stopMotor0();
motor1Reverse(57);
}

if (left_ir == 0)
{
motor0Reverse(57);
motor1Reverse(57);
}
}


while(left_ir == 0 && front_ir==0 )
{
flag == 1;
stopMotor1();
//stopBothMotors();
ex0_isr_counter = 0;
motor0Reverse(57);

//ReverseRight();

//stopBothMotors();
//stopMotor1();
//motor0Reverse(27);

}

if (ex0_isr_counter>190) //411
{

//motor0Reverse(27);
motor1Reverse(57);
ex0_isr_counter = 0;
flag = 0;
}

}
//-----------------------------------------------------------------------------
// OSCILLATOR_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function initializes the system clock to use the PLL as its clock
// source, where the PLL multiplies the external 22.1184MHz crystal by 9/4.
//
//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
int i; // Software timer

char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

OSCICN = 0x80; //0x83 // Set internal oscillator to run
// at its slowest frequency

CLKSEL = 0x00; // Select the internal osc. as
// the SYSTEMCLOCK source

// Initialize external crystal oscillator to use 22.1184 MHz crystal

OSCXCN = 0x67; // Enable external crystal osc.
for (i=0; i < 256; i++); // Wait at least 1ms

while (!(OSCXCN & 0x80)); // Wait for crystal osc to settle

SFRPAGE = LEGACY_PAGE;
FLSCL |= 0x30; // Initially set FLASH read timing for
// 100MHz SYSTEMCLOCK (most conservative
// setting)
if (SYSTEMCLOCK <= 25000000) {
// Set FLASH read timing for <=25MHz
FLSCL &= ~0x30;
} else if (SYSTEMCLOCK <= 50000000) {
// Set FLASH read timing for <=50MHz
FLSCL &= ~0x20;
} else if (SYSTEMCLOCK <= 75000000) {
// Set FLASH read timing for <=75MHz
FLSCL &= ~0x10;
} else { // set FLASH read timing for <=100MHz
FLSCL &= ~0x00;
}

// Start PLL for 50MHz operation
SFRPAGE = PLL0_PAGE;
PLL0CN = 0x04; // Select EXTOSC as clk source
PLL0CN |= 0x01; // Enable PLL power
PLL0DIV = 0x04; // Divide by 4
PLL0FLT &= ~0x0f;
PLL0FLT |= 0x0f; // Set Loop Filt for (22/4)MHz input clock
PLL0FLT &= ~0x30; // Set ICO for 30-60MHz
PLL0FLT |= 0x10;

PLL0MUL = 0x09; // Multiply by 9

// wait at least 5us
for (i = 0; i < 256; i++) ;

PLL0CN |= 0x02; // Enable PLL

while (PLL0CN & 0x10 == 0x00); // Wait for PLL to lock

SFRPAGE = CONFIG_PAGE;

CLKSEL = 0x02; // Select PLL as SYSTEMCLOCK source

SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}

//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

// XBR0 = 0x34; // Enable UART0
// XBR1 = 0x40;
// XBR2 = 0x01; // Enable crossbar and weak pull-up

XBR0 = 0x05; // Enable SDA and SCL
XBR1 = 0x14; // Route INT0 to port
XBR2 = 0x44; // Enable crsbr weak p-u
//P0MDOUT |= 0x11; // Set TX1 pin to p-p
//P1MDIN |= 0xE3;
//P1MDOUT |= 0x40;

// P0MDOUT |= 0x0C; // Set TX pin to push-pull
//P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
//P2MDOUT |=0x00;
// P1MDIN =0x40;


//XBR0 = 0x04; // Enable UART0
// XBR1 = 0x00;
// XBR2 = 0x40; // Enable crossbar and weak pull-up

P0MDOUT |= 0x01; // Set TX pin to push-pull
P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull

//P2 |= 0xFF;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// Ext_Interrupt_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures and enables /INT0 and /INT1 (External Interrupts)
// as negative edge-triggered.
//
//-----------------------------------------------------------------------------
void Ext_Interrupt_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = TIMER01_PAGE;

TCON = 0x05; // /INT 0 and /INT 1 are falling edge
// triggered

EX0 = 1; // Enable /INT0 interrupts
EX1 = 1; // Enable /INT1 interrupts

SFRPAGE = SFRPAGE_SAVE;
}

//-----------------------------------------------------------------------------
// UART1_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the UART1 using Timer1, for and 8-N-1.
//
//-----------------------------------------------------------------------------
void UART1_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = UART1_PAGE;
SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RX

SFRPAGE = TIMER01_PAGE;
TMOD &= ~0xF0;
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload


if (SYSTEMCLOCK/BAUDRATE/2/256 < 1) {
TH1 = -(SYSTEMCLOCK/BAUDRATE/2);
CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
} else if (SYSTEMCLOCK/BAUDRATE/2/256 < 4) {
TH1 = -(SYSTEMCLOCK/BAUDRATE/2/4);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x01; // T1M = 0; SCA1:0 = 01
} else if (SYSTEMCLOCK/BAUDRATE/2/256 < 12) {
TH1 = -(SYSTEMCLOCK/BAUDRATE/2/12);
CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00
} else {
TH1 = -(SYSTEMCLOCK/BAUDRATE/2/48);
CKCON &= ~0x13; // Clear all T1 related bits
CKCON |= 0x02; // T1M = 0; SCA1:0 = 10
}

TL1 = TH1; // init Timer1
TR1 = 1; // START Timer1
// TX_Ready = 1; // Flag showing that UART can transmit
EIE2 = 0x40; // Enable UART1 interrupts

SFRPAGE = UART1_PAGE;
EIP2 = 0x40; // Make UART high priority

SFRPAGE = SFRPAGE_SAVE; // Restore SFR page

}
//-----------------------------------------------------------------------------
// UART0_Init Variable baud rate, Timer 2, 8-N-1
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure UART0 for operation at 8-N-1 using Timer2 as
// baud rate source.
//
//-----------------------------------------------------------------------------
void UART0_Init (void)
{
char SFRPAGE_SAVE;

SFRPAGE_SAVE = SFRPAGE; // Preserve SFRPAGE

SFRPAGE = TMR2_PAGE;

TMR2CN = 0x00; // Timer in 16-bit auto-reload up timer
// mode
TMR2CF = 0x08; // SYSCLK is time base; no output;
// up count only
RCAP2 = - ((long) SYSTEMCLOCK/BAUDRATE/16);
TMR2 = RCAP2;
TR2= 1; // Start Timer2

SFRPAGE = UART0_PAGE;

SCON0 = 0x50; // 8-bit variable baud rate;
// 9th bit ignored; RX enabled
// clear all flags
SSTA0 = 0x15; // Clear all flags; enable baud rate
// doubler (not relevant for these
// timers);
// Use Timer2 as RX and TX baud rate
// source;

//ES0 = 1;
//IP |= 0x10;
TI0 = 1; // Indicate TX0 ready
// TX_Ready =1;
SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by using SYSCLK/12 as its time base.
//
//


//------------------------------------------------------------------------------------
// Interrupt Service Routines
//------------------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// /INT0 ISR
//-----------------------------------------------------------------------------
//
// Whenever a negative edge appears on P0.0, the LED is toggled.
// The interrupt pending flag is automatically cleared by vectoring to the ISR
//
//-----------------------------------------------------------------------------
void INT0_ISR (void) interrupt 0
{


LED = !LED;
ex0_isr_counter++;

}

//-----------------------------------------------------------------------------
// /INT1 ISR
//-----------------------------------------------------------------------------
//
// Whenever a negative edge appears on P0.1, the LED is toggled.
// The interrupt pending flag is automatically cleared by vectoring to the ISR
//
//-----------------------------------------------------------------------------
void INT1_ISR (void) interrupt 2
{


LED = !LED;
ex1_isr_counter++; // Increment the count

}

//-----------------------------------------------------------------------------
// UART1_Interrupt
//-----------------------------------------------------------------------------
//
// This routine is invoked whenever a character is entered or displayed on the
// Hyperterminal.
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void UART1_Interrupt (void) interrupt 20
{
SFRPAGE = UART0_PAGE;

if (RI1 == 1)
{
// reset = ~reset;
if( UART_Buffer_Size == 0) { // If new word is entered
UART_Input_First = 0; }

RI1 = 0; // Clear interrupt flag

Byte = SBUF1; // Read a character from UART

if (UART_Buffer_Size < UART_BUFFERSIZE)
{
UART_Buffer[UART_Input_First] = Byte; // Store in array

UART_Buffer_Size++; // Update array's size

UART_Input_First++; // Update counter
}

else
UART_Buffer_Size = 0; // Set the array size to 0
}

}

//------------------------------------------------------------------------------------
// Timer3_ISR
//------------------------------------------------------------------------------------
// This routine changes the state of the LED whenever Timer3 overflows.
//
// NOTE: The SFRPAGE register will automatically be switched to the Timer 3 Page
// When an interrupt occurs. SFRPAGE will return to its previous setting on exit
// from this routine.
//
void Timer2_ISR (void) interrupt 5
{
char SFRPAGE_SAVE = SFRPAGE;

static char dis_left_old, dis_left,l_rev;
static char dis_right_old, dis_right, r_rev, dis_base;

SFRPAGE = TMR2_PAGE;

time++;
LeftTimeout++;
RightTimeout++;

//Left Speed & Distance Calculation

if (lnew_count==0)
{
speedleft=0;
dis_left_old =0;
}
else
{
speedleft = lnew_count/time; //interrupts per sample time (we assume 10ms)
l_rev=speedleft/224; //revolutions per sample time
dis_left =l_rev*22; //left wheel distance in cm

// dis_l_average = (dis_left+dis_lef_old)/2;

// if ((dis_left>(dis_l_average/2)))
// {
// dis_left = dis_left_old;
// }

dis_left_old = dis_left;

}

//right speed and distance calculation
if (rnew_count==0)
{
speedright=0;
dis_right_old=0;
}
else
{
speedright = rnew_count/time; //interrupts per sample time (10ms)
r_rev = speedright/224;
dis_right = r_rev*22;

// dis_r_average = (dis_right+dis_right_old)/2;

// if ((dis_right>(dis_r_average/2)))
// {
// dis_right=dis_right_old;
// }
dis_right_old=dis_right;
}

speed = (speedright+speedleft)/2;

//Pose Calculations

distance=dis_right+dis_left/2;
dis_base=16; //distance between the two wheels in cm

angle =((dis_right-dis_left)/dis_base)*(360/(2*3.1457)); //angle in radians
pos_x = distance*cos(angle);
pos_y = distance*sin(angle);
//counters

//time++;// multiple of 10ms
TF2=0;
SFRPAGE=SFRPAGE_SAVE;
}

//-------------------------------------------------------------------------------------------------
//PROGRAMMABLE COUNTER ARRAY
//--------------------------------------------------------------------------------------------------

void PCA_ISR(void) interrupt 9
{
char SFRPAGE_SAVE = SFRPAGE;
// unsigned int l_new, r_new;
static unsigned int lold_count,rold_count,l_average,r_average;
CF=0;
SFRPAGE = PCA0_PAGE;

if (CCF5==1) //left interrupt enabled
{
//CCF5=0; //left interrupt reset

LeftCount++; //PCA Interrupt counter
lnew_count=LeftCount;
l_average=(lnew_count+lold_count)/2; //Averaging
if ((lnew_count>(lnew_count+l_average))||(lnew_count<(lnew_count-l_average)))
{
lnew_count=lold_count;
}
lold_count=lnew_count;


LeftTimeout=0;

}

if (CCF3==1) //Right interrupt enabled
{
CCF3=0; //Right interrupt reset

RightCount++; //PCA Interrupt counter
rnew_count=RightCount;
r_average=(rnew_count+rold_count)/2; //Averaging
if ((rnew_count>(rnew_count+r_average))||(rnew_count<(rnew_count-r_average)))
{
rnew_count=rold_count;
}
rold_count=rnew_count;

RightTimeout=0;

}

SFRPAGE=SFRPAGE_SAVE;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void motor0Forward(unsigned int speed)
{

if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
// while (gone==1){
// }
sendByte(speed-127);

}
else
{
sendByte(MOTOR0FORWARDPACKET);
// while (gone==1){
// }
sendByte(speed);
}
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------


void motor1Forward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR1FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR1FORWARDPACKET);
sendByte(speed);
}
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void motor0Reverse(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0REVERSEFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0REVERSEPACKET);
sendByte(speed);
}
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void motor1Reverse(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR1REVERSEFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR1REVERSEPACKET);
sendByte(speed);
}
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void motor0Coast()
{
sendByte(MOTOR0COASTPACKET);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void motor1Coast()
{
sendByte(MOTOR1COASTPACKET);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void stopBothMotors()
{
stopMotor0();
stopMotor1();
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void stopMotor0()
{
motor0Forward(0);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void stopMotor1()
{
motor1Forward(0);
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void ReverseRight()
{
stopMotor1();
//stopBothMotors();
motor0Reverse(27);
// ex0_isr_counter = 0;

}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

void ReverseLeft()
{

if (ex1_isr_counter>411)
{
stopBothMotors();
motor0Forward(27);
ex1_isr_counter = 0;
//temp = 0;
}

}

//-----------------------------------------------0------------------------------
//-----------------------------------------------------------------------------

void sendByte(char byteToSend)
{

//if (flag == 1) //TI0 == 1
///{
//gone = 0;
//flag = 0;
//TI0 = 0;
//if (TX_Ready == 1) // && (UART_Buffer_Size != 0) && (Byte == 13)
// {
// LED = ~LED;
// TI0 = 1;

// TI0 = 1; // Set transmit flag to 1
// flag = 1;
//while (gone==1){
//}
//gone = 0;
// if (gone!= 1)

{
while (!TI0);
TI0 = 0;
SBUF0 = byteToSend;
}
// SBUF0 = byteToSend;


//TI0 = 0;

// TX_Ready = 0; // Set the flag to zero
// gone = 1;
// TI0 = 1;
// }


// TX_Ready = 1; // gone = 1;
// TX_Ready = 1; // Indicate transmission complete


//Byte = byteToSend; // Transmit to motorcontroller
}

IP: Logged

Scotty
Member
posted September 16, 2010 12:18 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

When i use uart 0 and uart 1 together, uart1 RX should be at P1^1 . However i recieve no serial data through this pin, when reading SBUF1.
As far as I can see you won't get UART1 to P1.x with your current XBRn-configuration.

Regards,

Scotty

IP: Logged

trc4000
Member
posted September 16, 2010 12:40 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
what pin will uart 1 be then???

IP: Logged

Scotty
Member
posted September 16, 2010 06:34 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

what pin will uart 1 be then???
Aw, come on...
1) Read the crossbar chapter of datasheet to understand what you're doing
2) use the ConfigurationWizard (downloadable at SiLabs website) -> in the port config dialog you will see which port assignments are done.

Without checking it now, I'd say if you only use SMBus and UART1 it will be P0.2/P0.3.

Regards,

Scotty

IP: Logged

teresap989
New Member
posted September 16, 2010 10:10 PM     Click Here to See the Profile for teresap989   Click Here to Email teresap989     Edit/Delete Message
Thank you so much for the post. It's really informative!


__________________
[url=http://moviesonlineworld.com]watch free movies online[/url]

IP: Logged

Andy Peters
New Member
posted September 24, 2010 04:29 PM     Click Here to See the Profile for Andy Peters   Click Here to Email Andy Peters     Edit/Delete Message
The likely problem with UART1 not working is that you have to, in addition to setting the crossbar control correctly (enable the UART1 on the crossbar), you have to make sure that TX1 is an output and RX1 is an input!

IP: Logged

All times are CT (US)

next newest topic | next oldest topic

Administrative Options: Close Topic | Archive/Move | Delete Topic
Post New Topic  Post A Reply
Hop to:

Contact Us | MCU User Forum

Have you seen our MCU Knowledge Base?


Ultimate Bulletin Board 5.47b