Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // Non-blocking simple software serial send example
- // written for maple rev5, using hardware timer.
- // Author: J.Heinrich 09-11-2011, www.heisystec.com
- //... some times 3 ARM CortexM3 USART's arn't enough... ;-)
- // This code is provided as is under the GNU public license.
- uint8 LCDtransmitPin= 14; //5V tolerant on Maple rev5
- HardwareTimer timerLCD(2); //initializing hardware timer instance
- volatile int LCDbitcnt = 9; //starts with -1 on the stop bit
- volatile int LCDwritePt = -1;//writing index on output buffer
- volatile int LCDreadPt = -1;//reading index of output buffer
- volatile char LCDoutbuf[128]; //Software serial output buffer
- void setup(){
- LCDbegin(38600);
- }
- void loop(){
- char s[] = "Hello World";
- LCDprint(s);
- delay(1000); //Take care not to overfill the output buffer,
- //do not send more than %buffersize% chars than can be send with
- //current baud rate by time.
- //NONBLOCKING (fire and forget...):
- //There are NO delay() function calls in the sending routine.
- //After putting chars into the output buffer by LCDprint(),
- //the maple hardware timer will do the rest.
- //At a baud rate 38600 this yields about 1800 processor cycles more each bit(!)
- //available for other stuff - compared with a software serial timing with
- //delay(BitPeriod) for each bit. MAPLE 74MHz ROCKS!
- //Means: each byte, you win about 15.000 proc cycles.
- }
- void LCDbegin(int baud){
- pinMode(LCDtransmitPin, OUTPUT);//NOTE: pin must be pulled up by 10kOhm to +3,3V externally
- //in order to avoid noise output during boot-up or flashing the maple
- LCDbaudRate = baud;
- LCDbitPeriod = 1000000 / LCDbaudRate; //[µs] Binary modulation, bit rate = baud rate
- digitalWrite(LCDtransmitPin, HIGH); //prepare start bit...
- //preparing the maple hardware timer======:
- timerLCD.pause();
- timerLCD.setChannel1Mode(TIMER_OUTPUT_COMPARE);
- timerLCD.setCompare(TIMER_CH1, 1); // Interrupt 1 count after each update
- timerLCD.setPeriod(LCDbitPeriod); // in microseconds
- timerLCD.attachCompare1Interrupt(LCDnextBit); //interrupt handler attached
- timerLCD.refresh();//resetting the timer counter
- timerLCD.resume(); //runs endlessly, waiting for bytes in the send buffer
- }
- //Print a string i.e. array of char =============:
- void LCDprint(const char *s){
- while (*s)
- LCDprint(*s++);
- }
- //some basic print routine for separate char/byte =============:
- void LCDprint(uint8 b){
- if (LCDwritePt==127){LCDwritePt=0;} //increment write pointer
- else {LCDwritePt++;}
- LCDoutbuf[LCDwritePt] = b; //new byte to send-buffer,
- //send-timer runs indefinitely, fetches new bytes, and sends them
- }
- //timer interrupt routine, beeing called infinitely each bit period =:
- //Concerning communication speed, we loose one bit period each byte,
- //but we need one more bit cycle to fetch the next byte,
- //case: LCDbitcnt=9.
- //This gives the receiver about 26 µsec @38600 baud to do something else...
- void LCDnextBit(){
- switch(LCDbitcnt){
- case -1:
- digitalWrite(LCDtransmitPin, LOW); //send start bit
- LCDbitcnt++;
- break;
- case 0: //do for all 8 data bits the same stuff:
- case 1:
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- if (bitRead(LCDoutbuf[LCDreadPt],LCDbitcnt)==1){
- digitalWrite(LCDtransmitPin,HIGH); // send 1
- }
- else{
- digitalWrite(LCDtransmitPin,LOW); // send 0
- }
- LCDbitcnt++; //increment bit counter
- break;
- case 8:
- digitalWrite(LCDtransmitPin, HIGH); //send stop bit
- LCDbitcnt++; //increment bit counter
- break;
- case 9:
- if (LCDreadPt!=LCDwritePt){//something new in output buffer
- if (LCDreadPt==127){LCDreadPt=0;}
- else {LCDreadPt++;} //if 127, reset to zero
- LCDbitcnt = -1; //send start bit on next timer
- }
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement