📜 ⬆️ ⬇️

We write and parsim assembly language MCS-51, as in BASIC

Good day, dear.

In my free time I like programming microcontrollers, in assembler. For the time being, I mostly mess around with all sorts of PIC (12,16) and AVR, but I don’t disdain the MCS-51 either, especially since I actually started with them. My level is “forever beginner”. This type of LED already know how to blink, even on a timer.

Now I have set myself the task of writing a program for interacting with the GSM SIM900 module. To do this, you must be able to send something to the UART, and take something from there.

According to the competent for the whole thing, 2 ring buffers are put on: at the reception, and at the transfer. It seems like a classic of the genre, nothing new can be invented. But I am such a person that I do not like crutches, but at the same time I love bicycles. I wanted to invent my own. So:
')
1. I do not have a multi-tasking system, presuppose sending 1 command to the module, then waiting for 1 response. This means that sending can already be done not on interrupts, but simply in the main loop. We can do without a send buffer.

2. The answer from the module suits me only one (although if you check for example the signal level, this is no longer the case), and I expect what it should be. Therefore, I decided to do without the buffer and parse too, right in the main loop.

3. And so that everything is comfortable and beautiful, arrange the whole thing in macros.

The basis of my code was an example from the article “MK for beginners” from the magazine “Radio Amateur”, No. 3 for 2008.

First, "print":

; : ,    ;  : String,Destiny_ ;  :  ;       , : ; Print 'First string',UART ;   UART ; Print 'Second string',LCD ;   LCD UART equ 0 LCD equ 1 Print macro String;,Destiny_ ; String -   , Destiny_ -  : Display  UART mov destiny,#Destiny_ call Output ;           .      1   db String,0Dh,0Ah,0 endm Print_data segment data rseg Print_data destiny: ds 1 Print_code segment code rseg Print_code Output: ;  ,    pop DPH ;     DPTR  , pop DPL ;      Loop_Output: clr A movc A, @A+DPTR ;      inc DPTR ;     jnz Output_Symbol ;    ,   jmp @A+DPTR ;   Output_Symbol: ;------         UART ------------------------- push ACC ;   ,      mov A, Destiny jz Out_UART ;     Out_LCD: pop ACC ;     call Out_2_LCD ;    jmp Loop_Output ;    Out_UART: pop ACC ;     jnb TI, $ ;     clr TI ;   ,    mov SBUF, A ;   jmp Loop_Output ;    

In comparison with the original, I just added the ability to output to several "destination points".

Seeing how it came out simply and beautifully, I decided to do parsing in a similar way. Here's what happened:

 ; : ,    ;  : String,Label,waiting_value ;  : jmp  Label     String ;       , : ; Parsing 'First string',UART_Error,1000 ;    UART   1000 ,   ,    UART_Error ; Parsing 'Second string',UART_Error,0 ;    UART,    ,    UART_Error,      -   Parsing macro String,Label,waiting_value ; String -   , Label -      , waiting_value -       *100  ( 11,0592 MHz) mov parsing_delay,#waiting_value ;    - 100 ,  - 25,5  call Intput ;           .      1   db String,0Dh,0Ah,0 jbc parsing_error,Label ;     endm Parsing_data segment data rseg Parsing_data parsing_delay: ds 3 Parsing_bit segment bit rseg Parsing_bit parsing_error: dbit 1 Parsing_code segment code rseg Parsing_code Intput: ;  ,    clr RI ;     ,       ,      pop DPH ;     DPTR  , pop DPL ;    1   Loop_Intput: clr A movc A, @A+DPTR ;      inc DPTR ;     jnz Wait ;    ,  jmp @A+DPTR ;     .  DPTR      ,     Wait: ;          push ACC ;     mov A, parsing_delay jz Always_Wait ;    = 0,      mov parsing_delay+2,#0 mov parsing_delay+1,#90 ;     11,0592  Loop_Wait: jb RI, Stop_Wait ;   ,   djnz parsing_delay+2,Loop_Wait jb RI, Stop_Wait djnz parsing_delay+1,Loop_Wait jb RI, Stop_Wait mov parsing_delay+1,#90 ;     11,0592  djnz parsing_delay,Loop_Wait ;     pop ACC ;    ,   jmp Error_Intput ;      Always_Wait: jnb RI, $ ;    Stop_Wait: mov parsing_delay,SBUF ;            clr RI pop ACC ;     cjne A,parsing_delay,Error_Intput ;   1    ,      jmp Loop_Intput ;     Error_Intput: ;    ,     clr A movc A, @A+DPTR inc DPTR jnz Error_Intput ;    setb parsing_error ;     jmp @A+DPTR ;     .  DPTR      ,     

Quartz 11.0592 MHz allows you to “print” and parse lines at 57600 bps right in the main loop without any gaps in characters. With quartz at 22.1184 MHz, it is expected that it will be possible to do the same at a speed of 115200 bps.

Source: https://habr.com/ru/post/337168/


All Articles