Menu

RS232 Baud Rate, Clock questions

Help
2009-08-17
2013-05-30
  • Nobody/Anonymous

    Hi,

    I have a 16f688 working perfectly at 4800 baud, but need to get the speed up, as soon as i wind it up, i just get errors, have tried it with and without MAX chip, can someone point me in the right direction, i have to be honest i dont understand the clock speed, timing, baud issues at all!

    Thanks in advance. Code that is working below, oh and feel free to tidy up my nasty code!

        #chip 16F688, 8
        #config Osc = Int   
       
        #define SendAHigh Set PORTc.4 ON
        #define SendALow Set PORTc.4 OFF
       
    Dir PORTc.4 Out        'Set TX pin to out for Serial Use
    dir porta.0 In

    InitSer 1, r4800, 1, 8, 1, none, invert     'initialise serial and baud rate

    Do

    sendBattery(ReadAD10(an0))   
       
    Wait 25 ms

    Loop

    sub SendBattery(data1 as word)

    if data1 > 0 and data1 < 256 then
    msb=0
    lsb=data1
    end if

    if data1 > 255 and data1 < 512 then
    msb=1
    lsb=data1 - 256
    end if

    if data1 > 511 and data1 < 768 then
    msb=2
    lsb= data1 - 512
    end if

    if data1 > 767 and data1 < 1024 then
    msb=3
    lsb= data1 - 768
    end if

    if data1 =1024 then
    msb=4
    lsb=0
    end if

    SerSend(1, 95)   
    SerSend(1, 3)   
    SerSend(1, lsb)   
    SerSend(1, msb)   
    checksum = 98+lsb+msb
    SerSend(1, checksum)       'checksum

    end sub

     
    • Nobody/Anonymous

      I don't know if your chip have it, but... have you tried hardware usart?

      I'm using it at 57600 baud without any problem.

       
    • Nobody/Anonymous

      yep it has hardware usart on it

       
    • Nobody/Anonymous

      Ok... then to use it you should have last update (0.9 12/8/2009), and use this way:

      #define USART_BAUD_RATE 9600 '........or the value you want
      #define USART_BLOCKING
      InitUsart

      Dim data as word

      data = ReadAD10(an0)

      HSerSend (data) '..........Send low byte
      HSerSend (data_H) '......Send High byte

       
    • Nobody/Anonymous

      Hi,

      Nope that doesnt work, where is the documentation for USART, doesnt show in the help? I have this, and nothing happens.

         #chip 16F688, 8
          #config Osc = Int   
         
      #define USART_BAUD_RATE 4800 '........or the value you want
      #define USART_BLOCKING
      InitUsart

      Dim data55 as word

      data55 = ReadAD10(an0)

      Do

      HSerSend (data55) '..........Send low byte
      HSerSend (data55_H) '......Send High byte

      'HSerSend (95)   
      'HSerSend (3)
      'HSerSend (data55)
      'HSerSend (data55_H)   
      'checksum = 98+data55
      'HSerSend (checksum)    'checksum

      wait 25 ms

      Loop

       
    • Nobody/Anonymous

      Sorry... i forgot:  you should use the proper pins and configure them as inputs.

      16F688 use RC4 for TX and RC5 for RX, the you should conect this pins lo serial line.

      You also have to configure these two pins as inputs as indicated in datasheet (Note:The USART control will automatically reconfigure the pin from input to output as needed)

       
    • Nobody/Anonymous

      i have done that, configured the pins that is and still nothing happens, its weird, the PIC appears to crash, i have to power cycle it to be able to even flash it again.

      Does anyone have a simple bit of code that is know to work on a 16F688 with USART, so i can test.

      Thanks

       
    • Nobody/Anonymous

      Ok... this work for me, i have not an 16F88, i tried with 16F876A, for this code to work you need install last update (0.9 12/8/2009).

      _________________________________________________________________

      #chip 16F876a, 20       'modelo de pic y velocidad de reloj

      #config HS_OSC, WDT_OFF, PWRTE_ON, BODEN_OFF, LVP_OFF, CPD_OFF, WRT_OFF, DEBUG_OFF, CP_OFF

      #define USART_BAUD_RATE 57600 '........or the value you want 
      #define USART_BLOCKING 
      InitUsart 

      dir PORTC.7 in
      dir PORTC.6 in

      Do

      HSerSend 65 ' "A" ascii
      HSerSend 66 ' "B" ascii

      wait 25 ms

      Loop

      _________________________________________________________________

      Received in PC:
      ABABABABABABAB..............

       
    • Nobody/Anonymous

      I have the latest update (i think, how do i double check?) right, i am compiling this code and nothing is happening on the PIC, what else can i check?

      #chip 16F688 , 20
      #config Osc = Int

      #define USART_BAUD_RATE 4800 '........or the value you want 
      #define USART_BLOCKING 
      InitUsart 

      dir PORTC.4 in
      dir PORTC.5 in

      Do 

      HSerSend 65 ' "A" ascii
      HSerSend 66 ' "B" ascii

      wait 25 ms 

      Loop 

       
    • Nobody/Anonymous

      The chip Mhz is too high for this device's internal osc.  Also, the config for the internal osc is not quite right.  You can always check the xxFxxxx.dat file for the types of config setups possible.

      #chip 16F688 , 8 
      #config Osc = INTOSCIO

       
    • Nobody/Anonymous

      still nothing happening, if i compile this, it works, so its not a hardware problem:-

        #chip 16F688, 8
        #config Osc = Int   
         
          #define SendAHigh Set PORTc.4 ON
          #define SendALow Set PORTc.4 OFF
         
      Dir PORTc.4 Out        'Set TX pin to out for Serial Use

      InitSer 1, r4800, 1, 8, 1, none, invert     'initialise serial and baud rate

      Do

           SerSend(1, 22)    'send channel number 20-51
           SerSend(1, 30)    'Data1
           SerSend(1, 30)    'Data2   
         
      Wait 10 ms
      Loop

      What else can i check? How do i check i have the right USART library and versions?
      I am actually happy with my above code, except i cant get it working over 4800, as i increase it nothing happens, anyone got any ideas?

       
    • kent_twt4

      kent_twt4 - 2009-09-11

      If you have a 20Mhz crystal, throw one on, it will probably be just what the doctor ordered.  As stated in earlier post, it seems to work.

      It has been a while since trying either the SerSend or HserSend for that matter.  As you increase the baud rate speed, the bit wait delays become more of a factor, especially with internal oscillators.

      Here is a rehash of an earlier post on the alternate serial routine (found in the contributors section), and tested on the 16f688.  The bit rate delay for the 57,600 baud comms turned out to be 12 us, instead of the ideal 17 us, due to the 8 Mhz clock and code overhead.  Try that or some number close to that for the baud define, or check out an another baud rate to your liking.

      'Chip model 
      #chip 16f688,8
      #config _INTRC_OSC_NOCLKOUT
      #config MCLR = On
      Ser_Init
      #define LED PortC.0 
      dir LED out
      dir PortA.0 in
      dir PortA.2 in
      dim potValue as word

      start:
      Set LED On
      wait 1 s
      Set LED off
      wait 1 s
      Set LED On
      wait 1 s
      Set LED off
      wait 1 s
      Do
      ;Pic waits for signal from terminal/computer
      RCV_RS232 ;Return value is RxByte
      'Bin2ascii RxByte ;echo back received string/ascii value
      XMIT_RS232 RxByte ;echo back decimal value
      If RxByte = 113 Then goto getA2D ;ascii/keyboard "q"
      Loop
      getA2D:
      Do
      'XMIT_RS232 ReadAD(AN0)
      'potValue = ReadAD10(AN0)
      potValue = ReadAD10(AN2)
      bin2ascii potValue  ;sendout ascii value
      XMIT_RS232 10
      XMIT_RS232 13
      wait 10 ms
      Loop
      goto start

      Sub Ser_Init
      ;The higher the baud rate, in relation to clock speed,
      ;then higher the baud rate adjustment from ideal (subtraction)
      ;There is no baud rate adjustment calculation due to overhead.

      ;try 115200 delay value 
      ;#define baud 5
      ;#define halfbaud 4  ;place Read of SerRx in middle of bit
      ;********************************************************* 
      ;try 57600 delay value, ideal wait is 17 us  
      #define baud 12
      #define halfbaud 6     ;place Read of SerRx in middle of bit
      ;********************************************************* 
      ;try 38400 delay value 
      ;#define baud 26
      ;#define halfbaud 13     ;place Read of SerRx in middle of bit 
      ;try 19200 delay value 
      ;#define baud 49
      ;#define halfbaud 24 ;place Read of SerRx in middle of bit  
      ;slight adjustment was required for 9600bps delay value 
      ;#define baud 103
      ;#define halfbaud 52 ;place Read of SerRx in middle of bit 
      #define SerTxHigh Set PortC.4 On
      #define SerTxLow Set PortC.4 Off
      #define SerRx PortC.5
      dir PortC.5 in ;Rx
      dir PortC.4 out ;Tx 
      SerTxHigh ;Initial RS232 idle state
      end sub 

      Sub RCV_RS232
      RxWait:
      IF SerRx On Then goto RCV_RS232 ;wait for start bit 
      wait halfbaud us ;do half bit time delay
      If SerRx On Then goto RxWait
      RxByte = 0
      For RxBit = 1 to 8 ;set up to read 8 bits
      wait baud us 
      Rotate RxByte Right
      If SerRx On then Set RxByte.7 1
      If SerRx Off Then Set RxByte.7 0
      Next
      wait baud us
      End sub

      sub XMIT_PRINT (PrintData$) 
      PrintLen = PrintData(0) 
      if PrintLen = 0 then exit sub 
      'Write Data 
      for SysPrintTemp = 1 to PrintLen 
      XMIT_RS232(PrintData(SysPrintTemp)) 
      next 
      end sub 

      Sub XMIT_RS232(Xmit_Byte)#NR 
      SerTxLow
      wait baud us 
      For cntr = 1 to 8 
      Rotate Xmit_Byte Right 
      If Status.C ON Then SerTxHigh
      If Status.C Off Then SerTxLow
      wait baud us
      Next 
      SerTxHigh
      wait baud us 
      end sub 

      sub Bin2ascii(LCDValue as word )#NR
      dim LCDValueTemp as word 
      SERDECMIL = 0
      SERMIL = 0
      SERCEN = 0 
      SERDEC = 0 
      SERUN = 0 
      LCDValueTemp = 0 
      IF LCDValue >= 10000 then
      LCDValueTemp = LCDValue / 10000
      SERDECMIL = LCDValueTemp + 48
      Xmit_RS232(SERDECMIL) 'SerSend (1,SERDECMIL)
      LCDValue = LCDValue - LCDValueTemp * 10000
      End if
      If LCDValueTemp > 0 Or LCDValue >= 1000 Then
      LCDValueTemp = LCDValue / 1000
      SERMIL = LCDValueTemp + 48
      Xmit_RS232(SERMIL) 'SerSend (1,SERMIL)
      LCDValue = LCDValue - LCDValueTemp * 1000 
      End if
      IF LCDValueTemp > 0 OR LCDValue >= 100 then 
      LCDValueTemp = LCDValue / 100
      SERCEN = LCDValueTemp + 48 
      Xmit_RS232(SerCen) 'SerSend (1,SERCEN) 
      LCDValue = LCDValue - LCDValueTemp * 100 
      end if 
      IF LCDValueTemp > 0 OR LCDValue >= 10 then 
      LCDValueTemp = LCDValue / 10 
      SERDEC = LCDValueTemp + 48 
      Xmit_RS232(Serdec) 'SerSend (1,SERDEC) 
      LCDValue = LCDValue - LCDValueTemp * 10 
      end if 
      SERUN = LCDValue + 48 
      Xmit_RS232(Serun) 'SerSend (1,SERUN) 
      end sub

       

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.