??? 05/21/09 18:36 Read: times |
#165534 - Baud rate Responding to: ???'s previous message |
Currently I’m having the same problem with changing the baud rate. I have a Si Lab board with C8051 which is connected to the Industrial PC in which I receive can frames from uC, currently it’s working with baud rate 1MHz but I’m trying and trying to change it to work with 250kHz baud rate but without any results. I’ve already tried adding T2CON, T2MOD and SCON and changing RCAP2 but it didn’t help at all. I would be grateful if someone would tell me where am I doing mistake and how to fix it.
#include <c8051f040.h> // SFR declarations #include <stdio.h> //adding I/0 libraries /////////////////////////////////////////////////////////////////////////// // CAN Protocol Register Index for CAN0ADR, from TABLE 18.1 of the // C8051F040 datasheet /////////////////////////////////////////////////////////////////////////// #define CANCTRL 0x00 //Control Register #define CANSTAT 0x01 //Status register #define ERRCNT 0x02 //Error Counter Register #define BITREG 0x03 //Bit Timing Register #define INTREG 0x04 //Interrupt Low Byte Register #define CANTSTR 0x05 //Test register #define BRPEXT 0x06 //BRP Extension Register /////////////////////////////////////////////////////////////////////////////IF1 Interface Registers /////////////////////////////////////////////////////////////////////////// #define IF1CMDRQST 0x08 //IF1 Command Rest Register #define IF1CMDMSK 0x09 //IF1 Command Mask Register #define IF1MSK1 0x0A //IF1 Mask1 Register #define IF1MSK2 0x0B //IF1 Mask2 Register #define IF1ARB1 0x0C //IF1 Arbitration 1 Register #define IF1ARB2 0x0D //IF1 Arbitration 2 Register #define IF1MSGC 0x0E //IF1 Message Control Register #define IF1DATA1 0x0F //IF1 Data A1 Register #define IF1DATA2 0x10 //IF1 Data A2 Register #define IF1DATB1 0x11 //IF1 Data B1 Register #define IF1DATB2 0x12 //IF1 Data B2 Register /////////////////////////////////////////////////////////////////////////// //IF2 Interface Registers /////////////////////////////////////////////////////////////////////////// #define IF2CMDRQST 0x20 //IF2 Command Rest Register #define IF2CMDMSK 0x21 //IF2 Command Mask Register #define IF2MSK1 0x22 //IF2 Mask1 Register #define IF2MSK2 0x23 //IF2 Mask2 Register #define IF2ARB1 0x24 //IF2 Arbitration 1 Register #define IF2ARB2 0x25 //IF2 Arbitration 2 Register #define IF2MSGC 0x26 //IF2 Message Control Register #define IF2DATA1 0x27 //IF2 Data A1 Register #define IF2DATA2 0x28 //IF2 Data A2 Register #define IF2DATB1 0x29 //IF2 Data B1 Register #define IF2DATB2 0x2A //IF2 Data B2 Register /////////////////////////////////////////////////////////////////////////// //Message Handler Registers /////////////////////////////////////////////////////////////////////////// #define TRANSREQ1 0x40 //Transmission Rest1 Register #define TRANSREQ2 0x41 //Transmission Rest2 Register #define NEWDAT1 0x48 //New Data 1 Register #define NEWDAT2 0x49 //New Data 2 Register #define INTPEND1 0x50 //Interrupt Pending 1 Register #define INTPEND2 0x51 //Interrupt Pending 2 Register #define MSGVAL1 0x58 //Message Valid 1 Register #define MSGVAL2 0x59 //Message Valid 2 Register /////////////////////////////////////////////////////////////////////////// //ADC0 definitions /////////////////////////////////////////////////////////////////////////// #define V_REF 3 #define BIT4 0x01 << 4 #define BIT5 0x01 << 5 #define BIT7 0x01 << 7 /////////////////////////////////////////////////////////////////////////// //TIMER Registers and definitions /////////////////////////////////////////////////////////////////////////// #define SYSCLK // 24500000 // Internal oscillator frequency in Hz sfr16 DP = 0x82; // data pointer sfr16 RCAP2 = 0xCA; // Timer2 reload/capture value sfr16 RCAP3 = 0xCA; // Timer3 reload/capture value sfr16 RCAP4 = 0xCA; // Timer4 reload/capture value sfr16 TMR2 = 0xCC; // Timer2 counter/timer sfr16 TMR3 = 0xCC; // Timer3 counter/timer sfr16 TMR4 = 0xCC; // Timer4 counter/timer /////////////////////////////////////////////////////////////////////////// //Global Variables /////////////////////////////////////////////////////////////////////////// char MsgNum; char status; int i; int buttonstate =0x00; sfr16 CAN0DAT = 0xD8; int potencjometrl; int potencjometrh; int potencjometr; int candacl; int candach; /////////////////////////////////////////////////////////////////////////// // Function PROTOTYPES /////////////////////////////////////////////////////////////////////////// // Initialize Message Object void clear_msg_objects (void); void init_msg_object_TX (char MsgNum); void init_msg_object_RX (char MsgNum); void start_CAN (void); void transmit_data(char MsgNum); void receive_data (char MsgNum); void external_osc (void); void config_IO (void); void ADC0(void); void wait_ms (int ms); void dac(void); /////////////////////////////////////////////////////////////////////////// // MAIN Routine /////////////////////////////////////////////////////////////////////////// void main (void) { // disable watchdog timer WDTCN = 0xde; WDTCN = 0xad; //configure Port I/O config_IO(); // switch to external oscillator external_osc(); // Clear CAN RAM clear_msg_objects(); // Initialize message object to transmit data init_msg_object_TX (0x02); // Initialize message object to receive data init_msg_object_RX (0x01); // Enable CAN interrupts in CIP-51 EIE2 = 0x20; //Function call to start CAN start_CAN(); //Global enable 8051 interrupts EA = 1; //Loop and wait for interrupts while (1) { ADC0(); potencjometrl=ADC0L; potencjometrh=ADC0H; wait_ms (20); transmit_data(0x02); } } /////////////////////////////////////////////////////////////////////////// // Set up C8051F040 /////////////////////////////////////////////////////////////////////////// void wait_ms (int ms) { char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page SFRPAGE = TMR2_PAGE; TMR2CN = 0x00; // Stop Timer3; Clear TF3; TMR2CF = 0x00; // use SYSCLK/12 as timebase RCAP2 = -(SYSCLK/1000/12); // Timer 2 overflows at 1 kHz TMR2 = RCAP2; ET2 = 0; // Disable Timer 2 interrupts TR2 = 1; // Start Timer 2 while(ms){ TF2 = 0; while(!TF2); // wait until timer overflows ms--; dac(); } TR2 = 0; // Stop Timer 2 SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE } // Switch to external oscillator void dac(void) { REF0CN = 0x03; // Enable DAC Bias Generator, Internal Ref Buffer SFRPAGE=DAC0_PAGE; DAC0CN = 0x87; // Enable DAC 0, Update on Write to IDA0H, 2.0mA current DAC0L = candach; DAC0H = candacl; } void external_osc (void) { int n; // local variable used in delay FOR loop. SFRPAGE = CONFIG_PAGE; // switch to config page to config oscillator OSCXCN = 0x77; // start external oscillator; 22.1 MHz Crystal // system clock is 22.1 MHz / 2 = 11.05 MHz for (n=0;n<255;n++); // delay about 1ms while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize CLKSEL |= 0x01; // switch to external oscillator } void config_IO (void) { SFRPAGE = CONFIG_PAGE; //Port SFR's on Configuration page XBR3 = 0x80; // Configure CAN TX pin (CTX) as push-pull digital // output P0MDOUT = 0xFF; // Configure P1.6 as push-pull to drive LED P1MDIN = 0xFF; XBR2 = 0x40; // Enable Crossbar/low ports buttonstate = P1; } void ADC0(void) { SFRPAGE = ADC0CN; REF0CN = 0x03; /* Set voltage reference to "internal" */ ADC0CF = 0xF8; /* Set analog amp gain to 1.0 */ ADC0CN |= BIT7; /* Set AD1EN to activate the ADC */ /* Start first sample */ ADC0CN &= (0xFF ^ BIT5); /* Clear AD1INT flag */ ADC0CN |= BIT4; /* Set AD1BUSY flag, this starts conversion */ if(ADC0CN & BIT5) { ADC0CN &= (0xFF ^ BIT5); /* Clear AD1INT flag */ ADC0CN |= BIT4; /* Set AD1BUSY flag, this starts conversion */ } } /////////////////////////////////////////////////////////////////////////// //CAN Functions /////////////////////////////////////////////////////////////////////////// //Clear Message Objects void clear_msg_objects (void) { SFRPAGE = CAN0_PAGE; CAN0ADR = IF1CMDMSK; // Point to Command Mask Register 1 CAN0DATL = 0xFF; // Set direction to WRITE all IF registers to // Msg Obj for (i=1;i<33;i++) { CAN0ADR = IF1CMDRQST; // Write blank (reset) IF registers to each msg //obj CAN0DATL = i; } } //Initialize Message Object for RX void init_msg_object_RX (char MsgNum) { SFRPAGE = CAN0_PAGE; CAN0ADR = IF1CMDMSK; // Point to Command Mask 1 CAN0DAT = 0x00F8; // Set to WRITE, and alter all Msg Obj except ID // MASK // and data bits CAN0ADR = IF1ARB1; // Point to arbitration1 register CAN0DAT = 0x0000; // Set arbitration1 ID to "0" CAN0DAT = 0x8004; // Arb2 high byte:Set MsgVal bit, no extended ID, // Dir = RECEIVE CAN0DAT = 0x0480; // Msg Cntrl: set RXIE, remote frame function // disabled CAN0ADR = IF1CMDRQST; // Point to Command Request reg. CAN0DATL = MsgNum; // Select Msg Obj passed into function parameter // list // --initiates write to Msg Obj // 3-6 CAN clock cycles to move IF register contents to the Msg Obj in // CAN RAM } //Initialize Message Object for TX void init_msg_object_TX (char MsgNum) { SFRPAGE = CAN0_PAGE; CAN0ADR = IF1CMDMSK; // Point to Command Mask 1 CAN0DAT = 0x00F3; // Set to WRITE, & alter all Msg Obj except ID MASK // bits CAN0ADR = IF1ARB1; // Point to arbitration1 register CAN0DAT = 0x0000; // Set arbitration1 ID to highest priority CAN0DAT = 0xA055; // Autoincrement to Arb2 high byte: // Set MsgVal bit, no extended ID, Dir = WRITE CAN0DAT = 0x0086; // Msg Cntrl: DLC = 3, remote frame function not // enabled CAN0ADR = IF1CMDRQST; // Point to Command Request reg. CAN0DAT = MsgNum; // Select Msg Obj passed into function parameter // list // --initiates write to Msg Obj // 3-6 CAN clock cycles to move IF reg contents to the Msg Obj in CAN // RAM. } //Start CAN void start_CAN (void) { /* Calculation of the CAN bit timing : System clock f_sys = 22.1184 MHz/2 = 11.0592 MHz. System clock period t_sys = 1/f_sys = 90.422454 ns. CAN time quantum tq = t_sys (at BRP = 0) Desired bit rate is 1 MBit/s, desired bit time is 1000 ns. Actual bit time = 11 tq = 996.65ns ~ 1000 ns Actual bit rate is 1.005381818 MBit/s = Desired bit rate+0.5381% CAN bus length = 10 m, with 5 ns/m signal delay time. Propagation delay time : 2*(transceiver loop delay + bus line delay) = 400 ns (maximum loop delay between CAN nodes) Prop_Seg = 5 tq = 452 ns ( >= 400 ns). Sync_Seg = 1 tq Phase_seg1 + Phase_Seg2 = (11-6) tq = 5 tq Phase_seg1 <= Phase_Seg2, => Phase_seg1 = 2 tq and Phase_Seg2 = 3 tq SJW = (min(Phase_Seg1, 4) tq = 2 tq TSEG1 = (Prop_Seg + Phase_Seg1 - 1) = 6 TSEG2 = (Phase_Seg2 - 1) = 2 SJW_p = (SJW - 1) = 1 Bit Timing Register = BRP + SJW_p*0x0040 = TSEG1*0x0100 + TSEG2*0x1000 = 2640 Clock tolerance df : A: df < min(Phase_Seg1, Phase_Seg2) / (2 * (13*bit_time - Phase_Seg2)) B: df < SJW / (20 * bit_time) A: df < 2/(2*(13*11-3)) = 1/(141-3) = 1/138 = 0.7246% B: df < 2/(20*11) = 1/110 = 0.9091% Actual clock tolerance is 0.7246% - 0.5381% = 0.1865% (no problem for quartz) */ SFRPAGE = CAN0_PAGE; CAN0CN |= 0x41; // Configuration Change Enable CCE and INIT CAN0ADR = BITREG ; // Point to Bit Timing register CAN0DAT = 0x2640; // see above CAN0ADR = IF1CMDMSK; // Point to Command Mask 1 CAN0DAT = 0x0087; // Config for TX : WRITE to CAN RAM, write data // bytes, // set TXrqst/NewDat, clr IntPnd // RX-IF2 operation may interrupt TX-IF1 operation CAN0ADR = IF2CMDMSK; // Point to Command Mask 2 CAN0DATL = 0x1F; // Config for RX : READ CAN RAM, read data bytes, // clr NewDat and IntPnd CAN0CN |= 0x06; // Global Int. Enable IE and SIE CAN0CN &= ~0x41; // Clear CCE and INIT bits, starts CAN state // machine } //Transmit CAN frame to turn other node's LED ON void transmit_data (char MsgNum) { SFRPAGE = CAN0_PAGE; // IF1 already set up for TX CAN0ADR = IF1CMDMSK; // Point to Command Mask 1 CAN0DAT = 0x0087; // Config to WRITE to CAN RAM, write data bytes, // set TXrqst/NewDat, Clr IntPnd CAN0ADR = IF1DATA1; // Point to 1st byte of Data Field CAN0DATH = P0; //Transmit: diods state, CAN0DATL = P1; // bottom state, CAN0DATH = potencjometrh; // potnecjometer high bits, CAN0DATL = potencjometrl>>4; // potencjometer low bits, CAN0DATH = potencjometrl&0x0F; buttonstate = P1; CAN0ADR = IF1CMDRQST; // Point to Command Request Reg. CAN0DATL = MsgNum; // Move new data for TX to Msg Obj "MsgNum" } // Receive Data from the IF2 buffer void receive_data (char MsgNum) { char virtual_button; SFRPAGE = CAN0_PAGE; // IF1 already set up for RX CAN0ADR = IF2CMDRQST;// Point to Command Request Reg. CAN0DATL = MsgNum; // Move new data for RX from Msg Obj "MsgNum" // Move new data to a CAN0ADR = IF2DATA1; // Point to 1st byte of Data Field virtual_button = CAN0DATL; P0=virtual_button; CAN0ADR = IF2DATA2; // Point to 1st byte of Data Field candach = CAN0DATH; candacl = CAN0DATL; } //////////////////////////////////////////////////////////////////////////////// //Interrupt Service Routine //////////////////////////////////////////////////////////////////////////////// void ISRname (void) interrupt 19 { status = CAN0STA; if ((status&0x10) != 0) { // RxOk is set, interrupt caused by reception CAN0STA = (CAN0STA&0xEF)|0x07; // Reset RxOk, set LEC to NoChange /* read message number from CAN INTREG */ receive_data (0x01); // Up to now, we have only one RX message } if ((status&0x08) != 0) { // TxOk is set, interrupt caused by transmision CAN0STA = (CAN0STA&0xF7)|0x07; // Reset TxOk, set LEC to NoChange } if (((status&0x07) != 0)&&((status&0x07) != 7)) { // Error interrupt, LEC changed /* error handling ? */ CAN0STA = CAN0STA|0x07; // Set LEC to NoChange } } Marco |
Topic | Author | Date |
How to change baudrate from 9600 to 19200 | 01/01/70 00:00 | |
as usual | 01/01/70 00:00 | |
This isn't a free consultancy service. | 01/01/70 00:00 | |
We need an obvious link to the KEIL.COM baudrate calculator | 01/01/70 00:00 | |
FAQ | 01/01/70 00:00 | |
Depends on clock speed! | 01/01/70 00:00 | |
SIO_POLL_0.5 | 01/01/70 00:00 | |
T2 boundrate generator 19200bps @11.0592MHz | 01/01/70 00:00 | |
the above is true IF ..... | 01/01/70 00:00 | |
ADuC812 DATASHEET PAGE 37 | 01/01/70 00:00 | |
incomplete or worthless | 01/01/70 00:00 | |
It's an incomplete quote - Datasheet is OK | 01/01/70 00:00 | |
baud rate | 01/01/70 00:00 | |
He's using ADuc812 | 01/01/70 00:00 | |
double baud rate | 01/01/70 00:00 | |
Baud rate | 01/01/70 00:00 | |
have you tried the config program? | 01/01/70 00:00 | |
The config program ? | 01/01/70 00:00 | |
ConfigWizard... | 01/01/70 00:00 | |
Cofig Wizard![]() | 01/01/70 00:00 |