MCU User Forum
  Using motor controller with C8051F120 (communication with UART0)

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:   Using motor controller with C8051F120 (communication with UART0)
trc4000
Member
posted July 12, 2010 11:42 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
Hey Everyone! I've got a Pololu Qik 2s9v1 Dual Serial Motor Controller which I'm trying to interface with my C8051F120 microcontroller board.

I'm pretty sure I have all my bit assignments right (not using the reset or error pins at this point). I'm trying to get it to communicate through the UART0 port but its just not happening!

The code we're using is below. Any help would be greatly appreciated!

//------------------------------------------------------------------------------------
// F12x_Blinky.c
//------------------------------------------------------------------------------------
// Copyright (C) 2007 Silicon Laboratories, Inc.
//
// AUTH: BD
// DATE: 1 JUL 2002
//
// This program flashes the green LED on the C8051F120 target board about five times
// a second using the interrupt handler for Timer3.
// Target: C8051F12x
//
// Tool chain: KEIL Eval 'c'
//

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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 RCAP3 = 0xCA; // Timer3 reload value
sfr16 TMR3 = 0xCC; // Timer3 counter

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit left_ir = P1^1;
sbit right_ir = P1^0;
sbit front_ir = P1^3;
char send_byte;
unsigned short new_cmd_send; //-- set each time new
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void Init_Clock(void); //-- initialize the clock to use external
// crystal oscillator
void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm
void Timer3_Init (unsigned int counts);
void Timer3_ISR (void); //-- ISR for Timer 3
void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {

// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts
WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;
Init_Clock();
PORT_Init();
// Timer3_Init(SYSCLK / 12 / 10);
Init_UART0();
// EA = 1; //-- enable global interrupts

while(1) {

// EA = 0;
MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
// EA = 1; //-- enable interrupts


}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;
//send the packet

SBUF0 = byteToSend;
SFRPAGE = SFRPAGE_SAVE;
}

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

void Init_Clock(void)
{

OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
//because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110

//-- wait till XTLVLD pin is set
while ( !(OSCXCN & 0x80) );
OSCICN = 0x88; //-- 1000 1000b
//-- Bit 2 : Internal Osc. disabled (IOSCEN = 0)
//-- Bit 3 : Uses External Oscillator as System Clock
//(CLKSL = 1)
//-- Bit 7 : Missing Clock Detector Enabled (MSCLKE = 1)
}

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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
// P1MDIN = 0x40;
XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x00;
// XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p
// P1MDOUT |= 0x40; //-- Enable P1.6 (LED) as push-
// pull output
}

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

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

void Init_UART0(void)
{
//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON |= 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xB8; //Baud rate = 9600 //0xF4; //-- Baud rate = 115200
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)
TCON &= 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON |= 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //-- UART0 Mode 1, Logic level of stop
// bit ignored and Receive enabled

//-- enable UART0 interrupt
IE |= 0x10;
IP |= 0x10; //-- set to high priority level

TI0= 1; //-- clear the receive interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------

//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by using SYSCLK/12 as its time base.
//
//
void Timer3_Init (unsigned int counts)
{
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
// use SYSCLK/12 as timebase
RCAP3 = -counts; // Init reload values
TMR3RL = -counts; //-- Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 |= 0x01; //-- enable Timer3 interrupts
// EIE2 |= 0x01; // enable Timer3 interrupts
TMR3CN |= 0x04; //-- start Timer3 by setting TR3
// (TMR3CN.2) to 1 }
TR3 = 1; // start Timer3
}

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

//------------------------------------------------------------------------------------
// 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 Timer3_ISR (void) interrupt 14
{
TMR3CN &= ~(0x80); //-- clear TF3

TF3 = 0; // clear TF3

LED = ~LED; // change state of LED

}

//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
new_cmd_send=1;
}
}

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

IP: Logged

Scotty
Member
posted July 13, 2010 12:44 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

I'm trying to get it to communicate through the UART0 port but its just not happening!
Be more precisely! No UARTs output, no motor reaction, etc... ?

The code we're using is below.
I didn't check for the defined values for the motor, but your main-loop / UART transmission worth for optimising it.
Think of what you're doing: you're writing to SBUF without checking if the UART is busy... Now, what do you expect what would happen?

Regards,

Scotty

[This message has been edited by Scotty (edited July 13, 2010).]

IP: Logged

trc4000
Member
posted July 13, 2010 01:46 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
I have updated the code with a flag to check whether the UART is free before updating SBUF now in the code.

Still not sure how to optimise the main loop.

Currently i am unable to send any bytes via serial tranmission to the Serial motor controller board!!!

Here is the current updated code:

//------------------------------------------------------------------------------------
// F12x_Blinky.c
//------------------------------------------------------------------------------------
// Copyright (C) 2007 Silicon Laboratories, Inc.
//
// AUTH: BD
// DATE: 1 JUL 2002
//
// This program flashes the green LED on the C8051F120 target board about five times
// a second using the interrupt handler for Timer3.
// Target: C8051F12x
//
// Tool chain: KEIL Eval 'c'
//

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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 RCAP3 = 0xCA; // Timer3 reload value
sfr16 TMR3 = 0xCC; // Timer3 counter

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit left_ir = P1^1;
sbit right_ir = P1^0;
sbit front_ir = P1^3;
char send_byte;
unsigned short new_cmd_send; //-- set each time new
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void Init_Clock(void); //-- initialize the clock to use external
// crystal oscillator
void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm
void Timer3_Init (unsigned int counts);
void Timer3_ISR (void); //-- ISR for Timer 3
void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {
EA =0;
Init_Clock();
PORT_Init();
// Timer3_Init(SYSCLK / 12 / 10);
Init_UART0();
// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts
WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;

EA = 1; //-- enable global interrupts

while(1) {

EA = 0;
MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
EA = 1; //-- enable interrupts


}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;
if ( TI0 == 1) //-- interrupt caused by sent byte
{
//send the packet

SBUF0 = byteToSend;
TI0 = 0; //-- clear the flag
}
SFRPAGE = SFRPAGE_SAVE;
}

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

void Init_Clock(void)
{

OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
//because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110

//-- wait till XTLVLD pin is set
while ( !(OSCXCN & 0x80) );
OSCICN = 0x88; //-- 1000 1000b
//-- Bit 2 : Internal Osc. disabled (IOSCEN = 0)
//-- Bit 3 : Uses External Oscillator as System Clock
//(CLKSL = 1)
//-- Bit 7 : Missing Clock Detector Enabled (MSCLKE = 1)
}

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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
XBR2 = 0x40; // Enable crossbar and weak pull-ups
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
// P1MDIN = 0x40;
// XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x08;
XBR2 = 0x04; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p
P1MDOUT |= 0x02; //-- Enable P1.6 (LED) as push-
// pull output
}

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

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

void Init_UART0(void)
{
//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON |= 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xB8; //Baud rate = 9600 //0xF4; //-- Baud rate = 115200
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)
TCON &= 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON |= 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //-- UART0 Mode 1, Logic level of stop
// bit ignored and Receive enabled

//-- enable UART0 interrupt
IE |= 0x10;
IP |= 0x10; //-- set to high priority level

TI0= 0; //-- clear the receive interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------

//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by using SYSCLK/12 as its time base.
//
//
void Timer3_Init (unsigned int counts)
{
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
// use SYSCLK/12 as timebase
RCAP3 = -counts; // Init reload values
TMR3RL = -counts; //-- Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 |= 0x01; //-- enable Timer3 interrupts
// EIE2 |= 0x01; // enable Timer3 interrupts
TMR3CN |= 0x04; //-- start Timer3 by setting TR3
// (TMR3CN.2) to 1 }
TR3 = 1; // start Timer3
}

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

//------------------------------------------------------------------------------------
// 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 Timer3_ISR (void) interrupt 14
{
TMR3CN &= ~(0x80); //-- clear TF3

TF3 = 0; // clear TF3

LED = ~LED; // change state of LED

}

//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
new_cmd_send=1;
}
}

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

IP: Logged

erikm
Member
posted July 13, 2010 07:27 AM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
void UART0_ISR(void) interrupt 4
{
//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
new_cmd_send=1;
}
}

1) please change all tabs to spaces and use pre and /pre (emclosed in < and > when posting code.
2) the above has a glaring error, if you can not see it in one minute or less it is "bible time'

Erik

here are the links to "the bible"
Chapter 1 - 80C51 Family Architecture:
http://www.nxp.com/acrobat_download2/various/80C51_FAM_ARCH_1.pdf


Chapter 2 - 80C51 Family Programmer’s Guide and Instruction Set:
http://www.nxp.com/acrobat_download2/various/80C51_FAM_PROG_GUIDE_1.pdf


Chapter 3 - 80C51 Family Hardware Description:
http://www.nxp.com/acrobat_download2/various/80C51_FAM_HARDWARE_1.pdf

IP: Logged

trc4000
Member
posted July 14, 2010 10:59 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
I have just completed reading the bible suggested and have a better understanding.

However after modifying the visible errors, i am still unable to send any bytes to the motor controller via UART on Bit P0.0 (C8051F120 development board).

Here is the updated code:

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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 RCAP3 = 0xCA; // Timer3 reload value
sfr16 TMR3 = 0xCC; // Timer3 counter

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit left_ir = P1^1;
sbit right_ir = P1^0;
sbit front_ir = P1^3;
char send_byte;
unsigned short new_cmd_send; //-- set each time new
//RAM
bit gone;
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
void Init_Clock(void); //-- initialize the clock to use external
// crystal oscillator
void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm
void Timer3_Init (unsigned int counts);
void Timer3_ISR (void); //-- ISR for Timer 3
void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {
// EA =0;
Init_Clock();
PORT_Init();
// Timer3_Init(SYSCLK / 12 / 10);
Init_UART0();
// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts
WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;

// EA = 1; //-- enable global interrupts

while(1) {

EA = 0;
ES0 = 0;
ET2 = 0;
MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
EA = 1; //-- enable interrupts
ES0 = 1;
ET2 = 1;

}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;
LED = 1;
SFRPAGE = UART0_PAGE;
if ( gone == 1) //-- interrupt caused by sent byte
{
//send the packet

SBUF0 = byteToSend;
gone = 0; //-- clear the flag
}
SFRPAGE = SFRPAGE_SAVE;
LED = 0;
}

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

void Init_Clock(void)
{

OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
//because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110

//-- wait till XTLVLD pin is set
while ( !(OSCXCN & 0x80) );
OSCICN = 0x88; //-- 1000 1000b
//-- Bit 2 : Internal Osc. disabled (IOSCEN = 0)
//-- Bit 3 : Uses External Oscillator as System Clock
//(CLKSL = 1)
//-- Bit 7 : Missing Clock Detector Enabled (MSCLKE = 1)
}

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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
// XBR2 = 0x40; // Enable crossbar and weak pull-ups
P1MDOUT |= 0x40; // enable P1.6 (LED) as push-pull output
// P1MDIN = 0x40;
XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x08;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p
P1MDOUT |= 0x02; //-- Enable P1.6 (LED) as push-
// pull output
}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;


//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON = 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xB8; //Baud rate = 9600 //0xF4; //-- Baud rate = 115200
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)
TCON &= 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON = 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //-- UART0 Mode 1, Logic level of stop
// bit ignored and transmit enabled

//-- enable UART0 interrupt
IE = 0x10;
IP = 0x10; / /-- set to high priority level

TI0= 1; //-- clear the transmit interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------

//------------------------------------------------------------------------------------
// Timer3_Init
//------------------------------------------------------------------------------------
//
// Configure Timer3 to auto-reload and generate an interrupt at interval
// specified by using SYSCLK/12 as its time base.
//
//
void Timer3_Init (unsigned int counts)
{
TMR3CN = 0x00; // Stop Timer3; Clear TF3;
// use SYSCLK/12 as timebase
RCAP3 = -counts; // Init reload values
TMR3RL = -counts; //-- Init reload values
TMR3 = 0xffff; // set to reload immediately
EIE2 |= 0x01; //-- enable Timer3 interrupts
// EIE2 |= 0x01; // enable Timer3 interrupts
TMR3CN |= 0x04; //-- start Timer3 by setting TR3
// (TMR3CN.2) to 1 }
TR3 = 1; // start Timer3
}

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

//------------------------------------------------------------------------------------
// 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 Timer3_ISR (void) interrupt 14
{
TMR3CN &= ~(0x80); //-- clear TF3

TF3 = 0; // clear TF3

LED = ~LED; // change state of LED

}

//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;

//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
//send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
gone =1;
new_cmd_send=1;
}
SFRPAGE = SFRPAGE_SAVE;

}

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

IP: Logged

Scotty
Member
posted July 15, 2010 12:41 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

I have just completed reading the bible suggested and have a better understanding.
Good

However after modifying the visible errors,...
I still found some "errors":
Oscillator frequency:
// Global CONSTANTS
#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz
...
OSCXCN = 0x67; //-- 0110 0111b
//-- External Osc Freq Control Bits (XFCN2-0) set to 111
//because crystal frequency > 6.7 MHz
//-- Crystal Oscillator Mode (XOSCMD2-0) set to 110

Now, what's true? SYSCLK is 3.0625MHz or SYSCLK > 6.7MHz? The comments doesn't fit to what you're doing... So it's at least confusing for one who wants to help

Internal Oscillator control:
OSCICN = 0x88; //-- 1000 1000b
//-- Bit 2 : Internal Osc. disabled (IOSCEN = 0)
//-- Bit 3 : Uses External Oscillator as System Clock
//(CLKSL = 1)
//-- Bit 7 : Missing Clock Detector Enabled (MSCLKE = 1)

Again, the comments doesn't fit. And you don't touch the registers which may fit to the comments.

Port initialisation:
P1MDOUT |= 0x02; //-- Enable P1.6 (LED) as push-
// pull output

Again... It will modify P1.1, but not P1.6.

For the UART initialisation, I skipped calculating if you're using the correct reload values for baudrate generation, because I don't know which frequency is really used.

//-- enable UART0 interrupt
IE = 0x10;
IP = 0x10; / /-- set to high priority level

TI0= 1; //-- clear the transmit interrupt flag;
// ready to receive more

Not good. Why do you enable UART interrupt and set the transmit interrupt flag?
TI is usually set when UART handling is done via polling, but not in interrupt driven approaches.

while(1) {

EA = 0;
ES0 = 0;
ET2 = 0;
MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
EA = 1; //-- enable interrupts
ES0 = 1;
ET2 = 1;

}//}
}

This will mess it up totally. As I wrote above: THINK of what you're doing:
Your main loop enables/disables interrupts at will, and your ISR doesn't have a receive handler (even if no receiption could occur it should have one).
And the SendByte() function does not check if a transmission is in progress, so it may confuse the UART, because you write to SBUF before the current byte has been sent.
Use your bit variable "gone": in SendByte() function wait until it is set (by Tx ISR), then clear it and write to SBUF. This approach needs "gone" to be set in initialisation.

...i am still unable to send any bytes to the motor controller via UART on Bit P0.0 (C8051F120 development board).
This means the UART doesn't output anything?
Make a temporary test:
- Enable interrupts before going into main-loop
- comment out anything in the main-loop
- insert SendByte('U'); into main-loop

This will permanently send the value 0x55 to the UART, which could be measured with a oscilloscope. This test ensures that a) UART is set up properly and b) the timing is correct.

Regards,

Scotty

[This message has been edited by Scotty (edited July 15, 2010).]

IP: Logged

trc4000
Member
posted July 15, 2010 01:59 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
hi scotty,
thankyou for your suggestions
we have tried implementing your suggestions and then tested on an oscilliscope to see whether the UART output was working. We currently able to see no output from bit 0.0 (C8051F120).

Here is the updated code:

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit left_ir = P1^1;
sbit right_ir = P1^0;
sbit front_ir = P1^3;
char send_byte;
unsigned short new_cmd_send; //-- set each time new
//RAM
bit gone;
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
//void Init_Clock(void); //-- initialize the clock to use external
// crystal oscillator
void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm

void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;
PORT_Init();
Init_UART0();
// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts

EA = 1; //-- enable global interrupts
ES0 = 1;

while(1) {

// EA = 0;
// ES0 = 0;
sendByte('U');
// MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
// EA = 1; //-- enable interrupts
// ES0 = 1;


}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;
LED = 1;
SFRPAGE = UART0_PAGE;
if ( gone == 1) //-- interrupt caused by sent byte
{
//send the packet

SBUF0 = byteToSend;
gone = 0; //-- clear the flag
}
SFRPAGE = SFRPAGE_SAVE;
LED = 0;
}

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


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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
// XBR2 = 0x40; // Enable crossbar and weak pull-ups

// P1MDIN = 0x40;
XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x08;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p
// P1MDOUT |= 0x02; //-- Enable P1.1 (LED) as push-
// pull output
}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;


//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON = 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xFA; //Baud rate = 9600 //0xF4;
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)

TCON = 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON = 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //for 8bit mode //-- UART0 Mode 1, Logic level of stop
// bit ignored and transmit enabled

//-- enable UART0 interrupt
IE = 0x10;
IP = 0x10; //-- set to high priority level

TI0= 0; //-- clear the transmit interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------


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


//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;

//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
//send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
gone =1;
new_cmd_send=1;
}
SFRPAGE = SFRPAGE_SAVE;

}

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

IP: Logged

Scotty
Member
posted July 15, 2010 03:46 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

your LED is still defined as P1.6
You changed the comment in PORT_Init() function to P1.1 as LED output, which now fits to the comment, but the problem still exists. Which port is the LED connected to?

We currently able to see no output from bit 0.0 (C8051F120).
Hm...
- Is there also no output if the port is disconnected from the motor controller?
- J6, J8, J9 and J10 on the F120DK are also open?

Regards,

Scotty

IP: Logged

vanmierlo
Member
posted July 15, 2010 04:12 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
How do you think gone is initialized? Did you even try to single step to see where and why it hangs?

And why do you refuse to put your code in < pre > and < /pre > so we can read it?

IP: Logged

Scotty
Member
posted July 15, 2010 05:05 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
How do you think gone is initialized?
Good point, I mentioned it in my pre-last answer, but didn't check it when I wrote my last answer.

Regards,

Scotty

IP: Logged

trc4000
Member
posted July 15, 2010 11:56 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
I have placed the code in < pre > so its readable.

Yes i have tried to disconnect the jumper pins J6, J8, J9 and J10. Currently on the oscilliscope i can only see a constant logic high voltage from bit 0.0

Also i am not using any LED, that section is commented out.

On Stepping through the code 'gone' is always equal to zero. It is never intialised to 1. Further TI0 is always equal to zero aswell. So gone is not updated to 1.

Isn't TIO the status of the bit 0.0 and 0.1 on Port 0???


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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92; // Timer3 reload value
sfr16 RCAP3 = 0xCA; // Timer3 reload value
sfr16 TMR3 = 0xCC; // Timer3 counter

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------

#define SYSCLK 3062500 // approximate SYSCLK frequency in Hz

sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
sbit left_ir = P1^1;
sbit right_ir = P1^0;
sbit front_ir = P1^3;
char send_byte;
unsigned short new_cmd_send; //-- set each time new
//RAM
bit gone;
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------
//void Init_Clock(void); //-- initialize the clock to use external
// crystal oscillator
void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm

void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;
PORT_Init();
Init_UART0();
// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts

EA = 1; //-- enable global interrupts
ES0 = 1;

while(1) {

// EA = 0;
// ES0 = 0;
sendByte('U');
// MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
// EA = 1; //-- enable interrupts
// ES0 = 1;


}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;
if ( gone == 1) //-- interrupt caused by sent byte
{
//send the packet

SBUF0 = byteToSend;
gone = 0; //-- clear the flag
}
SFRPAGE = SFRPAGE_SAVE;
}

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


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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
// XBR2 = 0x40; // Enable crossbar and weak pull-ups

// P1MDIN = 0x40;
XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x08;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p

}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;


//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON = 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xFA; //Baud rate = 9600 //0xF4;
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)

TCON = 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON = 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //for 8bit mode //-- UART0 Mode 1, Logic level of stop
// bit ignored and transmit enabled

//-- enable UART0 interrupt
IE = 0x10;
IP = 0x10; //-- set to high priority level

TI0= 0; //-- clear the transmit interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------


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


//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;

//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
//send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
gone =1;
new_cmd_send=1;
}
SFRPAGE = SFRPAGE_SAVE;

}

//--------------------------------------------------------------
//-------------------------------------------------------------- >

Hopefully this makes it easier to read the code.

IP: Logged

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

On Stepping through the code 'gone' is always equal to zero.
Why do you wonder? You don't read our answers carefully:

Scotty, posted July 15, 2010 12:41 AM:
...
This approach needs "gone" to be set in initialisation.

That's why I always say: think of what you're doing

void sendByte(unsigned int byteToSend) {
...
if ( gone == 1) {...}
...
}
Scotty, posted July 15, 2010 12:41 AM:
...
Use your bit variable "gone": in SendByte() function wait until it is set (by Tx ISR), then clear it and write to SBUF.

I bolded it in my original post also, I didn't seem to come through:
You MUST wait for "gone" to be set, otherwise you will loose bytes:
while(!gone);
gone = 0;

Isn't TIO the status of the bit 0.0 and 0.1 on Port 0???
If you mean TI0 (zero), yes, it is, but only for P0.0 (TxD). It is set by hardware on end of a transmission.

Regards,

Scotty

[This message has been edited by Scotty (edited July 16, 2010).]

IP: Logged

trc4000
Member
posted July 16, 2010 01:14 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
ok i have ammended the code as per your suggestion to wait for gone to change state before updating the tranmitt buffer.

However i am still unable to recieve any serial trannsimmion output from bit 0.0 on the oscilliscope.

What else could be the problem??? Hmmm.....

Updated Code:

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

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------


//RAM
bit gone;
// command is received
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void PORT_Init (void);


void Init_UART0(void); //-- configure and initialize the UART0
// serial comm

void UART0_ISR(void); //-- ISR for UART0
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);
// Bytes used to talk to the motor controller

#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) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE; //-- disable watchdog timer
WDTCN = 0xAD;
PORT_Init();
Init_UART0();
// send_byte = 2;
// new_cmd_send = 0;
// EA = 0; //-- disable global interrupts

EA = 1; //-- enable global interrupts
ES0 = 1;

while(1) {

// EA = 0;
// ES0 = 0;
sendByte('U');
// MotorForward(56);
// Timer3_Init(SYSCLK / 12 / 10);
// EA = 1; //-- enable interrupts
// ES0 = 1;


}//}
}


//--------------------------------------------------------------
//--------------------------------------------------------------
void MotorForward(unsigned int speed)
{
if ( speed > 127 )
{
sendByte(MOTOR0FORWARDFASTPACKET);
sendByte(speed-127);
}
else
{
sendByte(MOTOR0FORWARDPACKET);
sendByte(speed);
}
}
//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = UART0_PAGE;

if ( gone == 1) //-- interrupt caused by sent byte
{
while(!gone);
{
}
gone = 0; //-- clear the flag
//send the packet

SBUF0 = byteToSend;


}
SFRPAGE = SFRPAGE_SAVE;

}

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


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


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
// XBR2 = 0x40; // Enable crossbar and weak pull-ups

// P1MDIN = 0x40;
XBR0 = 0x04; //-- Enable UART0
XBR1 = 0x08;
XBR2 = 0x40; //-- Enable Crossbar and weak pull-ups
// (globally)
P0MDOUT |= 0x01; //-- Enable TX0 as a push-pull o/p

}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;


//-- set up Timer 1 to generate the baude rate (115200)
//for UART0
CKCON = 0x10; //-- T1M=1; Timer 1 uses the system clock
// 22.11845 MHz
TMOD = 0x20; //-- Timer 1 in Mode 2 (8-bit auto-
// reload)
TH1 = 0xFA; //Baud rate = 9600 //0xF4;
TR1 = 1; //-- start Timer 1 (TCON.6 = 1)

TCON = 0xCF; //-- Timer 1 overflows used for receive &
// transmit clock (RCLK0=0, TCLK0=0)

//-- Set up the UART0
PCON = 0x80; //-- SMOD0=1 (UART0 baud rate divide-by-2
// disabled)
SCON0 = 0x50; //for 8bit mode //-- UART0 Mode 1, Logic level of stop
// bit ignored and transmit enabled

//-- enable UART0 interrupt
IE = 0x10;
IP = 0x10; //-- set to high priority level

TI0= 0; //-- clear the transmit interrupt flag;
// ready to receive more
}
//--------------------------------------------------------------
//--------------------------------------------------------------


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


//--------------------------------------------------------------
//--------------------------------------------------------------
void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;

//-- pending flags RI0 (SCON0.0) and TI0(SCON0.1)
if ( TI0 == 1) //-- interrupt caused by sent byte
{
//send_byte = SBUF0; //-- read the input buffer
TI0 = 0; //-- clear the flag
gone =1;

}
SFRPAGE = SFRPAGE_SAVE;

}

//--------------------------------------------------------------
//-------------------------------------------------------------- >

IP: Logged

Scotty
Member
posted July 16, 2010 01:42 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

ok i have ammended the code as per your suggestion to wait for gone to change state before updating the tranmitt buffer.
But poorly... Kick off the if-statement, the while-statement will do the same.
Again, think...

However i am still unable to recieve any serial trannsimmion output from bit 0.0 on the oscilliscope.
Of course, because you still have not initialised "gone"... So SBUF0 will never be written...

Regards,

Scotty

IP: Logged

trc4000
Member
posted July 16, 2010 01:51 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
ahhhhh k got it now, so now no if statment is required.

i have now intialised gone..... but still no output from bit 0.0 on the oscilliscope....

IP: Logged

Scotty
Member
posted July 16, 2010 03:00 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

ahhhhh k got it now, so now no if statment is required.
Yes The while-statement will block further program execution until "gone" is set via the ISR, which occurs when a byte is sent via UART.
Your first approach checked "gone", but continued without sending data if gone has not been set, therefore the bytes are skipped until UART is ready again.

i have now intialised gone..... but still no output from bit 0.0 on the oscilliscope....
Okay, now we can go deeper into it.
Can you debug if the ISR is called? E.g. by LED or debug interface (preferred). Also check if the timer 1 for baudrate generation is really running. If I'm correct the SiLabs IDE is capable to show UART and baudrate settings.

Regards,

Scotty

IP: Logged

erikm
Member
posted July 16, 2010 04:26 AM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
instead of trying to fix "the world" take it one step at a time.

cut (NOT comment) out all code not related to transmitting characters and post it as formatted code (using pre and /pre).

Erik

IP: Logged

vanmierlo
Member
posted July 16, 2010 04:27 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
I have placed the code in < pre > so its readable.

No you haven't. I don't see it in edit view of your post. The symptom that your code is still not indented should have warned you.

IP: Logged

trc4000
Member
posted July 18, 2010 11:20 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
i have removed the non relevant sections of the code to make it easier to reade.

I don't see any option to measure the baud rate in silicon labs IDE???

i am trying to debug with the onboard LED, no success yet.................

[code]

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

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------


//RAM
bit gone = 0;
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void PORT_Init (void);


void Init_UART0(void);

void UART0_ISR(void);
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);

//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE;
WDTCN = 0xAD;
PORT_Init();
Init_UART0();

EA = 1;
ES0 = 1;

while(1) {


sendByte('U'); //trying to view this output the oscilliscope



}
}

//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = UART0_PAGE;


while(!gone);
{
}
gone = 0;
LED = ~LED;

SBUF0 = byteToSend;



SFRPAGE = SFRPAGE_SAVE;

}


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------

//
void PORT_Init (void)
{


XBR0 = 0x04;
XBR1 = 0x08;
XBR2 = 0x40;

P0MDOUT = 0x01;

}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;



CKCON = 0x10;
TMOD = 0x20;
TH1 = 0xFA;
TR1 = 1;

TCON = 0xCF;

PCON = 0x80;
SCON0 = 0x50;

IE = 0x10;
IP = 0x10;

TI0= 0;
}

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


void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;


if ( TI0 == 1)
{

TI0 = 0;
gone =1;

}
SFRPAGE = SFRPAGE_SAVE;

}

//--------------------------------------------------------------
//--------------------------------------------------------------
[/code]

Any insight.................

IP: Logged

trc4000
Member
posted July 18, 2010 11:56 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
code slightly fixed, no output visible on oscilliscope yet!!!


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

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------


//RAM
bit gone = 1;
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void PORT_Init (void);


void Init_UART0(void);

void UART0_ISR(void);
void MotorForward(unsigned int speed);
void sendByte(unsigned int byteToSend);

//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE;
WDTCN = 0xAD;
PORT_Init();
Init_UART0();

EA = 1;
ES0 = 1;

while(1) {


sendByte('U'); //trying to view this output the oscilliscope



}
}

//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(unsigned int byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = UART0_PAGE;


while(!gone);
{
}
gone = 0;
LED = ~LED;

SBUF0 = byteToSend;



SFRPAGE = SFRPAGE_SAVE;

}


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------

//
void PORT_Init (void)
{


XBR0 = 0x04;
XBR1 = 0x08;
XBR2 = 0x40;

P0MDOUT = 0x01;
P1MDOUT = 0x40; //
}

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

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

void Init_UART0(void)
{
SFRPAGE = UART0_PAGE;



CKCON = 0x10;
TMOD = 0x20;
TH1 = 0xFA;
TR1 = 1;

TCON = 0xCF;

PCON = 0x80;
SCON0 = 0x50;

IE = 0x10;
IP = 0x10;

TI0= 0;
}

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


void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;


if ( TI0 == 1)
{

TI0 = 0;
gone =1;

}
SFRPAGE = SFRPAGE_SAVE;

}

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

IP: Logged

Scotty
Member
posted July 19, 2010 12:20 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

I don't see any option to measure the baud rate in silicon labs IDE???
There isn't one. But it should be possible to get the current settings of the relevant registers to check if they're all properly configured.

void sendByte(unsigned int byteToSend) {...}
Why do you use a int? The UART is only capable of sending 8-bit values.

code slightly fixed, no output visible on oscilliscope yet!!!
Strange... What happens if you use the UART examples included in the SiLabs IDE?

Regards,

Scotty

IP: Logged

trc4000
Member
posted July 19, 2010 12:29 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
i am using int, as i have tried char aswell and still not difference at this stage.

IP: Logged

trc4000
Member
posted July 19, 2010 12:55 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
i have just tried the example program using telenet, i am able to communicate with the C8051F120 .
so why wouldn't my situation work.....

IP: Logged

trc4000
Member
posted July 19, 2010 01:18 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
Intereseting the c8051F120 is recieving on port 1.1, however no change in transmission on 1.0 when connected to a pc and characters are sent from a telenet software

IP: Logged

Scotty
Member
posted July 19, 2010 01:43 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

...using telenet, i am able to communicate with the C8051F120 .
In both directions?

Intereseting the c8051F120 is recieving on port 1.1, however no change in transmission on 1.0 when connected to a pc and characters are sent from a telenet software
You're confusing me... You're referring to P1.0/P1.1, but your last posted code used UART0, which is P0.0/P0.1.

i am using int, as i have tried char aswell and still not difference at this stage
The difference will be to save some clock cycles. And using char will save you in future

One question: In your port initialisation you're setting XBR1 to 0x08, which routes timer 1 enable input to a port pin. As I can see you're not using the T1 enable I want to know why you enable it and what happens if you comment it out.

Regards,

Scotty

IP: Logged

trc4000
Member
posted July 19, 2010 08:31 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
No affect if i commenting out XBR1 = 0x08. still no output from port 0.0 on the oscilliscope.

Previous post, was a typo mistake, should be 0.0 instead of 1.0 etc.

current state of code

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

//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------


//RAM
bit gone = 1;
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void PORT_Init (void);


void Init_UART0(void);

void UART0_ISR(void);
void MotorForward(unsigned int speed);
void sendByte(char byteToSend);

//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {
EA = 0;
ES0 = 0;

WDTCN = 0xDE;
WDTCN = 0xAD;
PORT_Init();
Init_UART0();

EA = 1;
ES0 = 1;
ET1 = 1;

while(1) {


sendByte('U'); //trying to view this output the oscilliscope



}
}

//--------------------------------------------------------------
//--------------------------------------------------------------
void sendByte(char byteToSend)
{
char SFRPAGE_SAVE = SFRPAGE;

SFRPAGE = UART0_PAGE;


while(!gone);
{
}
gone = 0;
LED = ~LED;

SBUF0 = byteToSend;



SFRPAGE = SFRPAGE_SAVE;

}


//------------------------------------------------------------------------------------
// PORT_Init
//------------------------------------------------------------------------------------

//
void PORT_Init (void)
{


XBR0 = 0x04;
// XBR1 = 0x00; commented out
XBR2 = 0x40;

P0MDOUT = 0x01;
P1MDOUT = 0x40;
}

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

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

void Init_UART0(void)
{

SFRPAGE = UART0_PAGE;



CKCON = 0x10;
TMOD = 0x20;
TH1 = 0xFA;
TR1 = 1;

TCON = 0xCF;

PCON = 0x80;
SCON0 = 0x50;

IE = 0x10;
IP = 0x10;

TI0= 0;
}

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


void UART0_ISR(void) interrupt 4
{
char SFRPAGE_SAVE = SFRPAGE;
SFRPAGE = UART0_PAGE;


if ( TI0 == 1)
{

TI0 = 0;
gone =1;

}
SFRPAGE = SFRPAGE_SAVE;

}

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

IP: Logged

trc4000
Member
posted July 19, 2010 09:27 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
An attempt to use timer 2 instead of timer 1 on the c8051F120.

No visible output on the oscilliscope.

however on bit 0.1 (the recieve pin) i do see some output. But no change in bit 0.0



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

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 TMR2 = 0xcc; // Timer2
//------------------------------------------------------------------------------------
// Global CONSTANTS
//------------------------------------------------------------------------------------
#define BAUDRATE 115200 // Baud rate of UART in bps

// SYSTEMCLOCK = System clock frequency in Hz
#define SYSTEMCLOCK (22118400L * 9 / 4)

//RAM
unsigned char gone = 1;
unsigned char buffer = 0;
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
static char Byte;
//------------------------------------------------------------------------------------
// Function PROTOTYPES
//------------------------------------------------------------------------------------

void PORT_Init (void);

void OSCILLATOR_Init (void);
void Init_UART0(void);

void UART0_ISR(void);
void MotorForward(unsigned int speed);
void sendByte(char byteToSend);


//------------------------------------------------------------------------------------
// MAIN Routine
//------------------------------------------------------------------------------------
void main (void) {

WDTCN = 0xDE;
WDTCN = 0xAD;
OSCILLATOR_Init ();
PORT_Init();
Init_UART0();

EA = 1;


SFRPAGE = UART0_PAGE;
while(1) {


if((gone == 1) && (buffer != 0))
{
gone = 0; // Set the flag to zero
TI0 = 1; // Set transmit flag to 1
}

}
}

//-----------------------------------------------------------------------------
void OSCILLATOR_Init (void)
{
int i; // Software timer

char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

OSCICN = 0x80; // 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
//------------------------------------------------------------------------------------

//
void PORT_Init (void)
{

char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

XBR0 = 0x04;
XBR1 = 0x00;
XBR2 = 0x40;

P0MDOUT = 0x01;
P1MDOUT = 0x40;

SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}

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

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

void Init_UART0(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;

SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}

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


void UART0_ISR(void) interrupt 4
{
SFRPAGE = UART0_PAGE;



if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag

if (buffer != 1) // If buffer not empty
{

// Store a character in the variable byte
Byte = 'U';

SBUF0 = Byte; // Transmit
buffer--; // Decrease array size

}
else
{
buffer = 0; // Set the array size to 0
gone = 1; // Indicate transmission complete
}
}

}

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

IP: Logged

trc4000
Member
posted July 20, 2010 12:31 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
hi

just a confirmation i am able to successfully test the following code. However while testing i see no output on the bit 0.0 and 0.1 when a transmission and recieving occurs.

Could this mean that the recieving and transmission bit pin is incorrect????

//-----------------------------------------------------------------------------
// F12x_UART0_Interrupt.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This program demonstrates how to configure the C8051F120 to write to and read
// from the UART interface. The program reads a word using the UART0 interrupts
// and outputs that word to the screen, with all characters in uppercase
//
// How To Test:
//
// 1) Download code to a 'F12x device that is connected to a UART transceiver
// 2) Verify jumpers J6 and J9 are populated on the 'F12x TB.
// 3) Connect serial cable from the transceiver to a PC
// 4) On the PC, open HyperTerminal (or any other terminal program) and connect
// to the COM port at and 8-N-1
// 5) Download and execute code on an 'F12x target board.
// 6) Type up to 64 characters into the Terminal and press Enter. The MCU
// will then print back the characters that were typed
//
//
// Target: C8051F12x
// Tool chain: Keil C51 7.50 / Keil EVAL C51
// Command Line: None
//
// Release 1.0
// -Initial Revision (SM)
// -11 JULY 2007
//


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include // SFR declarations
#include

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 TMR2 = 0xcc; // Timer2

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define BAUDRATE 9600 // Baud rate of UART in bps

// SYSTEMCLOCK = System clock frequency in Hz
#define SYSTEMCLOCK (22118400L * 9 / 4)

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);
void PORT_Init (void);
void UART0_Init (void);

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

#define UART_BUFFERSIZE 64
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
unsigned char TX_Ready =1;
static char Byte;

//-----------------------------------------------------------------------------
// main() Routine
//-----------------------------------------------------------------------------

void main (void)
{

SFRPAGE = CONFIG_PAGE;

WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;

OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO

UART0_Init (); // Initialize UART0

EA = 1;

SFRPAGE = UART0_PAGE;

while (1)
{
// If the complete word has been entered via the terminal followed
// by carriage return
if((TX_Ready == 1) && (UART_Buffer_Size != 0) && (Byte == 13))
{
TX_Ready = 0; // Set the flag to zero
TI0 = 1; // Set transmit flag to 1
}
}
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// 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; // 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
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0 digital push-pull UART TX
// P0.1 digital open-drain UART RX
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

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

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;

SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}


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

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

void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;

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

RI0 = 0; // Clear interrupt flag

Byte = SBUF0; // 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
}
}

if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag

if (UART_Buffer_Size != 1) // If buffer not empty
{
// If a new word is being output
if ( UART_Buffer_Size == UART_Input_First ) {
UART_Output_First = 0; }

// Store a character in the variable byte
Byte = UART_Buffer[UART_Output_First];

if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
Byte -= 32; }

SBUF0 = Byte; // Transmit to Hyperterminal

UART_Output_First++; // Update counter

UART_Buffer_Size--; // Decrease array size

}
else
{
UART_Buffer_Size = 0; // Set the array size to 0
TX_Ready = 1; // Indicate transmission complete
}
}
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

IP: Logged

trc4000
Member
posted July 20, 2010 12:34 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
i can surely confirm that the serial UART0 port is working as i can communicate with the PC via RS232, however why is it that i cannot read of bit 0.0 and 0.1 on oscilliscope?????

IP: Logged

Scotty
Member
posted July 20, 2010 12:52 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

i can surely confirm that the serial UART0 port is working as i can communicate with the PC via RS232, ...
Good

...however why is it that i cannot read of bit 0.0 and 0.1 on oscilliscope?????
Not good. You can see the idle voltage of the UART? if not, maybe the channel is on AC or GND? The oscilloscope is connected to GND and the voltage/div and time/div settings are correct?

Regards,

Scotty

IP: Logged

trc4000
Member
posted July 21, 2010 02:00 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
hi

I am now able to establish a serial communication with the motorcontroller.
However i am unable to send any meaningful signals to the serial motor controller board.

The problem is that characters sent are being overwritten by the next set of character on the transmission bit 0.0

Seems to be a logic error, can anyone identiy the problem in this code???

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


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include // SFR declarations
#include

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 TMR2 = 0xcc; // Timer2

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define BAUDRATE 9600 // Baud rate of UART in bps

// SYSTEMCLOCK = System clock frequency in Hz
#define SYSTEMCLOCK (22118400L * 9 / 4)
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
int flag;

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void motorForward(unsigned int speed);
void sendByte(char byteToSend);

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

#define UART_BUFFERSIZE 64
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
unsigned char TX_Ready =1;
static char Byte;
bit gone = 1;

#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)
{

SFRPAGE = CONFIG_PAGE;

WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;

OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO

UART0_Init (); // Initialize UART0
flag = 0;
sendByte(INITIALPACKET);
EA = 1;

SFRPAGE = UART0_PAGE;


while (1)
{

// If the complete word has been entered via the terminal followed
// by carriage return
if((TX_Ready == 1) ) // && (UART_Buffer_Size != 0) && (Byte == 13)
{
LED = ~LED;
TX_Ready = 0; // Set the flag to zero
TI0 = 1; // Set transmit flag to 1
motorForward(250);
}
}
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// 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; // 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
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0 digital push-pull UART TX
// P0.1 digital open-drain UART RX
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

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

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;

SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}


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

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

void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;


if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
gone = 0;
//if (UART_Buffer_Size != 1) // If buffer not empty //UART_Buffer_Size != 1 &&
// {
// If a new word is being output
// if ( UART_Buffer_Size == UART_Input_First) {
// UART_Output_First = 0; }

// Store a character in the variable byte
// Byte = UART_Buffer[UART_Output_First];

//if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
// Byte -= 32; }

// SBUF0 = Byte;

// UART_Output_First++; // Update counter

// UART_Buffer_Size--; // Decrease array size

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

// }
}
}

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

void motorForward(unsigned int speed)
{

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

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

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

void sendByte(char byteToSend)
{

if (TI0 == 0)
{
SBUF0 = byteToSend;
TX_Ready = 1; // Indicate transmission complete

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

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

IP: Logged

Scotty
Member
posted July 21, 2010 06:27 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

Seems to be a logic error, can anyone identiy the problem in this code???
Did a short look on the code, the answer is yes. Again, if interrupts are used, the only methods modifying the interrupt flags are the interrupt service routines. You set TI0 in your main loop, causing the transmit interrupt to be called. And you can only use interrupt or polling method, but not both together at the same time as you do with sendByte() function!

When posting code please replace all tabs with spaces and place the code between < pre > and < /pre > (without spaces).

Regards,

Scotty

IP: Logged

vanmierlo
Member
posted July 21, 2010 12:35 PM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
Scotty,

I do not fully agree. One must either write to SBUF or set TI to initiate a transmit sequence. But before you do so, you must ensure that there is no other transmission still busy.

What you cannot do is poll TI in both the main loop and use the interrupt like the OP is doing. Even worse, he's writing SBUF when it indicates it is not ready.

Maarten

IP: Logged

Scotty
Member
posted July 21, 2010 12:54 PM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi vanmierlo,

I do not fully agree. One must either write to SBUF or set TI to initiate a transmit sequence.
That's why I explicitely refered to the interrupt flags. I agree that eiter SBUF or TI must be modified to initiate transmission. It depends on the driver implementation which approach is used, however in my opinion a beginner should modify SBUF rather than TI flag to learn how interrupts work. Experienced users like us will use TI flag to initiate transmission and leave SBUF handling totally to the ISR.

But before you do so, you must ensure that there is no other transmission still busy.
That's why I said a beginner should use SBUF. Modifying TI without understanding that TI will cause interrupts will crash. So using SBUF will keep undesired interrupts away.

What you cannot do is poll TI in both the main loop and use the interrupt like the OP is doing. Even worse, he's writing SBUF when it indicates it is not ready.
Yes, I don't know how the people get these codes, however for me it's always satisfying if I can get them to understand how it works...

Regards,

Scotty

[This message has been edited by Scotty (edited July 21, 2010).]

IP: Logged

trc4000
Member
posted July 21, 2010 09:41 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
The serial tranmission does not work without TI ..............

IP: Logged

trc4000
Member
posted July 21, 2010 09:56 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
still cannot establish a proper connection with the serial motor controller......


//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include // SFR declarations
#include

//-----------------------------------------------------------------------------
// 16-bit SFR Definitions for 'F12x
//-----------------------------------------------------------------------------

sfr16 RCAP2 = 0xca; // Timer2 capture/reload
sfr16 TMR2 = 0xcc; // Timer2

//-----------------------------------------------------------------------------
// Global Constants
//-----------------------------------------------------------------------------

#define BAUDRATE 9600 // Baud rate of UART in bps

// SYSTEMCLOCK = System clock frequency in Hz
#define SYSTEMCLOCK (22118400L * 9 / 4)
sbit LED = P1^6; // green LED: '1' = ON; '0' = OFF
int flag;

//-----------------------------------------------------------------------------
// Function Prototypes
//-----------------------------------------------------------------------------

void OSCILLATOR_Init (void);
void PORT_Init (void);
void UART0_Init (void);
void motorForward(unsigned int speed);
void sendByte(char byteToSend);

//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------

#define UART_BUFFERSIZE 64
unsigned char UART_Buffer[UART_BUFFERSIZE];
unsigned char UART_Buffer_Size = 0;
unsigned char UART_Input_First = 0;
unsigned char UART_Output_First = 0;
unsigned char TX_Ready =1;
static char Byte;
bit 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)
{

SFRPAGE = CONFIG_PAGE;

WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;

OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO

UART0_Init (); // Initialize UART0
// flag = 1;
// TI0 = 1;
EA = 1;
sendByte(INITIALPACKET);
// TI0 = 0;
// flag = 0;
// EA = 1;

SFRPAGE = UART0_PAGE;


while (1)
{

// if((TX_Ready == 1) ) // && (UART_Buffer_Size != 0) && (Byte == 13)
// {
// LED = ~LED;
// TX_Ready = 0; // Set the flag to zero
// TI0 = 1; // Set transmit flag to 1
// flag = 1;
motorForward(226);
// }
}
}

//-----------------------------------------------------------------------------
// Initialization Subroutines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// 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; // 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
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This function configures the crossbar and GPIO ports.
//
// P0.0 digital push-pull UART TX
// P0.1 digital open-drain UART RX
//-----------------------------------------------------------------------------
void PORT_Init (void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page

SFRPAGE = CONFIG_PAGE; // Set SFR page

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

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;

SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
}


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

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

void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;


if (TI0 == 1) // Check if transmit flag is set //TI0 == 1
{
TI0 = 0; // Clear interrupt flag
// gone = 0;
//if (UART_Buffer_Size != 1) // If buffer not empty //UART_Buffer_Size != 1 &&
// {
// If a new word is being output
// if ( UART_Buffer_Size == UART_Input_First) {
// UART_Output_First = 0; }

// Store a character in the variable byte
// Byte = UART_Buffer[UART_Output_First];
LED = ~LED;
//if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
// Byte -= 32; }
SBUF0 = Byte;

// UART_Output_First++; // Update counter

// UART_Buffer_Size--; // Decrease array size

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

TX_Ready = 1; // Indicate transmission complete

// }
}
}

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

void motorForward(unsigned int speed)
{

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

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

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

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; // Set transmit flag to 1
// flag = 1;
Byte = byteToSend;
TX_Ready = 0; // Set the flag to zero
TI0 = 1;
// gone = 1;
// TX_Ready = 1; // Indicate transmission complete

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

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------

IP: Logged

trc4000
Member
posted July 22, 2010 12:42 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
I would like to transmit 10bits (8 bits of data, 1 start bit and 1 stop bit). How would i modify my current code to do this?????

IP: Logged

Scotty
Member
posted July 22, 2010 07:45 AM     Click Here to See the Profile for Scotty     Edit/Delete Message
Hi trc4000,

still cannot establish a proper connection with the serial motor controller......
You still haven't understood what we wrote above: USING POLLING AND INTERRUPTS AT THE SAME TIME IS NOT POSSIBLE AND WILL DEFINITELY LEAD TO CRASHES!

I would like to transmit 10bits (8 bits of data, 1 start bit and 1 stop bit). How would i modify my current code to do this?????
According to your code comments you haven't to do because it is already 8-N-1 -> 8 data bits, No parity bits and one stop bits. Why do you think you're not transceiving 10 bits already?

Are you still sure that you know what you're doing?
Maybe it might be better to put it all away half an hour and take a beer to get the head free =)

Regards,

Scotty

IP: Logged

erikm
Member
posted July 22, 2010 09:17 AM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
When posting code between pre and /pre you must first convert tabs to spaces.

How would i modify my current code to do this
get ALL handling of TI and RI out of the main it should ONLY be in the ISR. Some do allow ONE setting of TI in the main to start the transmission.

Erik

[This message has been edited by erikm (edited July 22, 2010).]

IP: Logged

trc4000
Member
posted July 22, 2010 05:57 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
k sought of confused now.

Then the interrupt would only be called if the TI0 is set.

Removing TI from the main loop may result in data being overwritten in the char Byte which is being transmitted.

IP: Logged

trc4000
Member
posted July 22, 2010 06:00 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
k sought of confused now.

If i remove TI0 from the main loop, then the character byte will be overwritten before it is transmitted to SBUF (If the interrupt flag TI is not set).

IP: Logged

trc4000
Member
posted July 22, 2010 09:02 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
if i use polling or interrupt by itself its not working???

IP: Logged

trc4000
Member
posted July 23, 2010 01:44 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
Polling only does not work:

while (!TI0);
TI0 = 0;
SBUF0 = MOTOR0FORWARDPACKET;

IP: Logged

trc4000
Member
posted July 23, 2010 01:57 AM     Click Here to See the Profile for trc4000     Edit/Delete Message

updated code, still no luck.......

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

//-----------------------------------------------------------------------------
// UART0_Interrupt
//-----------------------------------------------------------------------------
//
//
//-----------------------------------------------------------------------------

void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;

if (TI0 ==1) // Check if transmit flag is set //TI0 == 1
{

TI0 = 0; // Clear interrupt flag

// gone = 0;
//if (UART_Buffer_Size != 1) // If buffer not empty //UART_Buffer_Size != 1 &&
// {
// If a new word is being output
// if ( UART_Buffer_Size == UART_Input_First) {
// UART_Output_First = 0; }

// Store a character in the variable byte
// Byte = UART_Buffer[UART_Output_First];

//if ((Byte >= 0x61) && (Byte <= 0x7A)) { // If upper case letter
// LED = ~LED;
// Byte -= 32; }
// TI0 == 1;
//while (TI0==1){
SBUF0 = Byte;
// }

//gone = 1;

// UART_Output_First++; // Update counter

// UART_Buffer_Size--; // Decrease array size

// }
// else
// {
// UART_Buffer_Size = 0; // Set the array size to 0
gone =0;
TX_Ready = 1; // Indicate transmission complete


// }
}
}

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

void motorForward(unsigned int speed)
{

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

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

//-----------------------------------------------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)
{
Byte = 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

vanmierlo
Member
posted July 23, 2010 04:44 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
When posting code between pre and /pre you must first convert tabs to spaces.

Which part of this advise did you not understand?

IP: Logged

trc4000
Member
posted July 24, 2010 04:53 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
not to use polling and interrupts same time. As if i don't use the TI flag i cannot establish the serial communication.

Still not sure how to fix the crashing.

IP: Logged

erikm
Member
posted July 24, 2010 06:03 PM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
The one and only possible use of TI (and RI) outside the ISR (when an UART ISR exist) is the setting of the TI flag to start a transmit.

This, of course, requires a check for "previous message completed"

Erik

IP: Logged

trc4000
Member
posted July 25, 2010 05:27 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
doesn't the TI act as a checking flag, do i need an extra flag

how would i do that????

IP: Logged

erikm
Member
posted July 25, 2010 06:59 PM     Click Here to See the Profile for erikm   Click Here to Email erikm     Edit/Delete Message
doesn't the TI act as a checking flag, do i need an extra flag
how would i do that????

If you have the UART interrupt enabled and do not reset TI/RI in the ISR, the ISR will keep getting accessed ISR - one main instruction - ISR - one main instruction - ISR ......

If you are using a message buffer the checking for transmit complete will be "is the message buffer empty?"

Erik

IP: Logged

vanmierlo
Member
posted July 26, 2010 01:32 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
Yes, you need an extra flag. It's called TX_Ready in your code. It must be set in the ISR when the message buffer is empty and the last byte has been sent. If you have no buffer (buffersize = 0) then you must set it after each byte is sent.

This is your ISR stripped of commented out lines:


void UART0_Interrupt (void) interrupt 4
{
SFRPAGE = UART0_PAGE;
if (TI0 == 1) // Check if transmit flag is set
{
TI0 = 0; // Clear interrupt flag
gone = 0;
TX_Ready = 1; // Indicate transmission complete
}
}

And this is sendByte:


void sendByte(char byteToSend)
{
if (TX_Ready == 1)
{
if (gone != 1)
{
Byte = byteToSend;
TX_Ready = 0; // Set the flag to zero
TI0 = 1;
}
}
}

Which code is writing to SBUF ?
Also follow the line of events on paper and see why it will fail.

[This message has been edited by vanmierlo (edited July 26, 2010).]

IP: Logged

trc4000
Member
posted July 26, 2010 02:03 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
the interrupt is writing to the SBUF

IP: Logged

trc4000
Member
posted July 26, 2010 02:12 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
currently the interrupt is being called continously resulting in overwritten in bytes on the output.

I am not using a buffer, so how can i check the status where the last byte was transmitted

IP: Logged

trc4000
Member
posted July 26, 2010 02:34 AM     Click Here to See the Profile for trc4000     Edit/Delete Message
even if i use a buffer, interrupts are occuring too quickly.

IP: Logged

trc4000
Member
posted July 26, 2010 08:43 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
even direct polling in the main loop without an interrupt causes same issue....


SFRPAGE = CONFIG_PAGE;

WDTCN = 0xDE; // Disable watchdog timer
WDTCN = 0xAD;

OSCILLATOR_Init (); // Initialize oscillator
PORT_Init (); // Initialize crossbar and GPIO

UART0_Init (); // Initialize UART0
// flag = 1;
// TI0 = 1;
// EA = 1;
// sendByte(INITIALPACKET);
// TI0 = 0;
// flag = 0;
// EA = 1;

SFRPAGE = UART0_PAGE;

//sendByte(INITIALPACKET);
///while (!TI0);
//TI0 = 0;


// SBUF0 = INITIALPACKET;

while (1)
{

// if((TX_Ready == 1) ) // && (UART_Buffer_Size != 0) && (Byte == 13)
// {
// LED = ~LED;
// TX_Ready = 0; // Set the flag to zero
// TI0 = 1; // Set transmit flag to 1
// flag = 1;
// sendByte(INITIALPACKET);

//motorForward(158);
{
while (!TI0);
TI0 = 0;
SBUF0 = 0xAA;
// Output CR
}

{
while (!TI0); // Wait for transmit complete
TI0 = 0;

SBUF0 = 0x88;
// Send character
}

{
while (!TI0);
TI0 = 0;
SBUF0 = 0x7F;
// Output CR
}

//while (!TI0);
//TI0 = 0;
// SBUF0 = MOTOR0FORWARDPACKET;

// while (!TI0); // Wait for transmit complete
// TI0 = 0;
// SBUF0 = 1; // }
}
}

IP: Logged

vanmierlo
Member
posted July 27, 2010 04:44 AM     Click Here to See the Profile for vanmierlo   Click Here to Email vanmierlo     Edit/Delete Message
I stop answering you. You refuse to listen/read. The interrupt is NOT writing to SBUF. There isn't even any mention of SBUF in my stripped version of YOUR code. I only stripped the code that you already commented out.

I'm also no longer willing to read your badly formatted code.

IP: Logged

trc4000
Member
posted July 27, 2010 11:51 PM     Click Here to See the Profile for trc4000     Edit/Delete Message
Sorry for all the problems but we FINALLY got it working! Thanks for all your advice. Really appreciate it!

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