Email: Password: Remember Me | Create Account (Free)

Back to Subject List

Old thread has been locked -- no new posts accepted in this thread
???
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

List of 20 messages in thread
TopicAuthorDate
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      

Back to Subject List