Advertisement
HDS

nonblocking Software Serial Maple CortexM3

HDS
Nov 11th, 2011
417
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.05 KB | None | 0 0
  1. // Non-blocking simple software serial send example
  2. // written for maple rev5, using hardware timer.
  3. // Author: J.Heinrich 09-11-2011, www.heisystec.com
  4. //... some times 3 ARM CortexM3 USART's arn't enough... ;-)
  5. // This code is provided as is under the GNU public license.
  6.  
  7. uint8 LCDtransmitPin= 14;   //5V tolerant on Maple rev5
  8. HardwareTimer timerLCD(2);  //initializing hardware timer instance
  9.  
  10. volatile int   LCDbitcnt  =  9; //starts with -1 on the stop bit
  11. volatile int   LCDwritePt =  -1;//writing index on output buffer
  12. volatile int   LCDreadPt  =  -1;//reading index of output buffer
  13. volatile char  LCDoutbuf[128];  //Software serial output buffer
  14.  
  15. void setup(){
  16.     LCDbegin(38600);
  17. }
  18.  
  19. void loop(){
  20.     char s[] = "Hello World";
  21.     LCDprint(s);
  22.     delay(1000); //Take care not to overfill the output buffer,
  23.     //do not send more than %buffersize% chars than can be send with
  24.     //current baud rate by time.
  25.     //NONBLOCKING (fire and forget...):
  26.     //There are NO delay() function calls in the sending routine.
  27.     //After putting chars into the output buffer by LCDprint(),
  28.     //the maple hardware timer will do the rest.
  29.     //At a baud rate 38600 this yields about 1800 processor cycles more each bit(!)
  30.     //available for other stuff - compared with a software serial timing with
  31.     //delay(BitPeriod) for each bit. MAPLE 74MHz ROCKS!
  32.     //Means: each byte, you win about 15.000 proc cycles.
  33. }
  34.  
  35.  
  36. void LCDbegin(int baud){   
  37.     pinMode(LCDtransmitPin, OUTPUT);//NOTE: pin must be pulled up by 10kOhm to +3,3V externally
  38.     //in order to avoid noise output during boot-up or flashing the maple
  39.     LCDbaudRate = baud;            
  40.     LCDbitPeriod = 1000000 / LCDbaudRate; //[µs] Binary modulation, bit rate = baud rate
  41.     digitalWrite(LCDtransmitPin, HIGH); //prepare start bit...
  42.    
  43.     //preparing the maple hardware timer======:
  44.     timerLCD.pause();
  45.     timerLCD.setChannel1Mode(TIMER_OUTPUT_COMPARE);
  46.     timerLCD.setCompare(TIMER_CH1, 1);  // Interrupt 1 count after each update
  47.     timerLCD.setPeriod(LCDbitPeriod);   // in microseconds
  48.     timerLCD.attachCompare1Interrupt(LCDnextBit); //interrupt handler attached
  49.     timerLCD.refresh();//resetting the timer counter
  50.     timerLCD.resume(); //runs endlessly, waiting for bytes in the send buffer
  51. }
  52.  
  53. //Print a string i.e. array of char =============:
  54. void LCDprint(const char *s){
  55.   while (*s)
  56.     LCDprint(*s++);
  57. }
  58.  
  59. //some basic print routine for separate char/byte =============:
  60. void LCDprint(uint8 b){
  61.    if (LCDwritePt==127){LCDwritePt=0;} //increment write pointer
  62.    else {LCDwritePt++;}
  63.    LCDoutbuf[LCDwritePt] = b; //new byte to send-buffer,
  64.    //send-timer runs indefinitely, fetches new bytes, and sends them
  65. }
  66.  
  67. //timer interrupt routine, beeing called infinitely each bit period =:
  68. //Concerning communication speed, we loose one bit period each byte,
  69. //but we need one more bit cycle to fetch the next byte,
  70. //case: LCDbitcnt=9.
  71. //This gives the receiver about 26 µsec @38600 baud to do something else...
  72. void LCDnextBit(){
  73.     switch(LCDbitcnt){
  74.         case -1:
  75.             digitalWrite(LCDtransmitPin, LOW); //send start bit
  76.             LCDbitcnt++;
  77.         break;
  78.         case 0: //do for all 8 data bits the same stuff:
  79.         case 1:
  80.         case 2:
  81.         case 3:
  82.         case 4:
  83.         case 5:
  84.         case 6:
  85.         case 7:
  86.             if (bitRead(LCDoutbuf[LCDreadPt],LCDbitcnt)==1){
  87.                 digitalWrite(LCDtransmitPin,HIGH); // send 1
  88.             }
  89.             else{
  90.                 digitalWrite(LCDtransmitPin,LOW); // send 0
  91.             }
  92.             LCDbitcnt++; //increment bit counter
  93.         break;
  94.         case 8:
  95.             digitalWrite(LCDtransmitPin, HIGH); //send stop bit
  96.             LCDbitcnt++; //increment bit counter          
  97.         break;
  98.         case 9:            
  99.             if (LCDreadPt!=LCDwritePt){//something new in output buffer
  100.                 if (LCDreadPt==127){LCDreadPt=0;}
  101.                 else {LCDreadPt++;}         //if 127, reset to zero
  102.                 LCDbitcnt  = -1;  //send start bit on next timer
  103.             }    
  104.         break;
  105.     }
  106. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement