Quantcast
Channel: MCS Electronics Forum
Viewing all articles
Browse latest Browse all 20577

BASCOM-AVR : Buffered serial in handling ASCII STX and ETX [solved] : REPLY

$
0
0
Hi Ian, It's indeed a RFID reader module, but comes from Itead Studio. May be the very same as yours :) Two years ago I wrote a routine called My_buffered_serial_in to fix another problem: I didn't preserve R23 in the (all) interrupt routines and the AVR was a modern one with extended IO :oops: That caused a lot of headaches, because most of the time it DID work. Bascom magic ;) Since I tested My_buffered_serial_in thoroughly, I simply implemented it in the current program. And it works fine :) I haven't written the checksum routine yet. I'd be delighted to use your code for that. Thanks ! Nard PS For those who could use my routine: Initialize: [code:1:1bd0a2e909]'################## Serial communication ################# 'Using compiler default is another option, but this works even when the default settings are odd Config Com1 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 Config Serialout = Buffered , Size = 45 'No more Config Serialin = Buffered , Size = 40 , Bytematch = 3 since Input requires a CR LF, see Help on Config Input 'Thanks to laborratte and Evert @ Bascom forum 'Using my own BufferedSerialIn routine, since it has been thoroughly tested. And can handle ETX :P 'MySerialIn variables: Dim My_si_terminator As Byte 'define here on what ASCII-value the MySerialInFlag must be set My_si_terminator = 3 '<ETX> 'My_si_status has a triple function: bit7 is used as readyflag, bit6 as overrunflag and pointer uses the other bits Dim My_si_status As Byte My_si_readyf Alias My_si_status.7 My_si_overrunf Alias My_si_status.6 Dim My_si_buffer As String * 40 'length of inputbuffer, max 62 Dim My_si_bufsize As Byte My_si_bufsize = 40 Dim Buffered_input_str As String * 40 'the workcopy Dim Length As Byte On Urxc My_si_handler Nosave Enable Urxc 'End of ################## Serial communication #################[/code:1:1bd0a2e909] Note: Don't forget to [b:1bd0a2e909]enable Global interrupts[/b:1bd0a2e909] ! Interrupt handler: [code:1:1bd0a2e909]'My buffered Serial In handler My_si_handler: $asm push xl in xl,sreg push xl push xh push zl push zh push r25 ' push r23 'Just for AVR's with extended IO 'Overrun can occur when: '1. the string was already terminated, and new characters pop in before the string is handled by main (and bits are cleared) '2. there was no terminator yet, but the buffer is full lds r25,{My_si_status} 'get the pointer including the flags bst r25,7 'move readyflag to T brtc test_for_overrun 'if set, the entered string was already .... '.... ready-flag already set, so there is an overrun bld r25,6 'doing this will cause a brach to si_handler_exit Test_for_overrun: bst r25,6 'overrunbit to T brtc We_are_fine 'if bit6 is set (overrun), then ignore further received characters andi r25,192 'Clear pointer but preserve flags sts {My_si_status},r25 rjmp si_handler_exit We_are_fine: Loadadr My_si_buffer , Z 'get the startaddress of the buffer add zl,r25 'add pointer to zl; we know that bit6 and 7 are 0 brcc z_holds_buffer_pointer inc zh 'carry set? Then inc zh Z_holds_buffer_pointer: in xh,udr 'read UART data register st z,xh 'store data from UDR in buffer lds xl,{My_si_terminator} cp xl,xh 'was this the terminator ? brne no_terminator 'nope ... more to come Close_buffer: 'that was the terminator, so put a 0 as string-end-marker in the next location 'set My_si_readyf (bit7 of My_si_status) clr xh 'mark end of string with 0 st z,xh 'and store in buffer sbr r25,128 'set bit7==readyflag andi r25,192 'Clear pointer but preserve flags sts {My_si_status},r25 rjmp Si_handler_exit 'we're done, so exit No_terminator: 'now check if the buffersize has been reached lds xh,{My_si_bufsize} cp r25,xh breq buffer_full inc r25 sts {My_si_status},r25 rjmp Si_handler_exit Buffer_full: sbr r25,64 'set bit6==overrunflag rjmp close_buffer Si_handler_exit: ' pop r23 'Just for AVR's with extended IO pop r25 pop zh pop zl pop xh pop xl Out Sreg , Xl pop xl $end Asm Return[/code:1:1bd0a2e909] And in the Main Loop you use it like this: [code:1:1bd0a2e909]'RFID message handler 'Recover from comm error If My_si_overrunf = 1 Then Disable Interrupts Reset Ucsrb.rxen 'to clear errorflags, a possible RxC-flag and flush the buffer My_si_buffer = "" My_si_status = 0 Set Ucsrb.rxen Enable Interrupts End If 'This the the normal operation-block: a command or question has come in If My_si_readyf = 1 And My_si_overrunf = 0 Then Disable Interrupts Buffered_input_str = My_si_buffer 'make a copy to work with My_si_status = 0 'and be ready for the next command Enable Interrupts Length = Len(buffered_input_str) Decr Length If Length > 127 Then Length = 0 'Length is a byte, and if 0, the Decr sets bit7 and we don't want that 'and here the rest of the handler Buffered_input_str = Mid(buffered_input_str , 2 , Length) 'strip the STX at the start of the message #if My_debug.1 = 1 Print Buffered_input_str #endif 'Blip the fiber twice Set Red_fibre Set Grn_fibre Waitms 300 Reset Red_fibre Reset Grn_fibre Waitms 300 Set Red_fibre Set Grn_fibre Waitms 300 Reset Red_fibre Reset Grn_fibre End If[/code:1:1bd0a2e909] Enjoy !

Viewing all articles
Browse latest Browse all 20577

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>