|
Author
|
Topic: Using motor controller with C8051F120 (communication with UART0)
|
trc4000 Member
|
posted July 12, 2010 11:42 PM
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
hijust 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
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
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
hiI 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
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
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
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
The serial tranmission does not work without TI ..............
IP: Logged |
trc4000 Member
|
posted July 21, 2010 09:56 PM
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
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
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
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
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
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
if i use polling or interrupt by itself its not working???
IP: Logged |
trc4000 Member
|
posted July 23, 2010 01:44 AM
Polling only does not work:while (!TI0); TI0 = 0; SBUF0 = MOTOR0FORWARDPACKET;
IP: Logged |
trc4000 Member
|
posted July 23, 2010 01:57 AM
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
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
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
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
doesn't the TI act as a checking flag, do i need an extra flaghow would i do that????
IP: Logged |
erikm Member
|
posted July 25, 2010 06:59 PM
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
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
the interrupt is writing to the SBUF
IP: Logged |
trc4000 Member
|
posted July 26, 2010 02:12 AM
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
even if i use a buffer, interrupts are occuring too quickly.
IP: Logged |
trc4000 Member
|
posted July 26, 2010 08:43 PM
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
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
Sorry for all the problems but we FINALLY got it working! Thanks for all your advice. Really appreciate it!
IP: Logged |