网站导航: 首页 > 设计参考 > 正文 文章搜索
PIC 单片机模拟异步串行通讯UART源程序
 
文章编号:
081209170719
文章分类: 单片机 PIC
点 击:
...
关 键 词: 模拟串口
文章来源:
网络
摘 要:

用TMR0实现定时查询。任何带中断的PIC上都可以实现。可用此法扩展多个串口。
 

 
  1. ;|--------------------------------------------------------------|  
  2. ;|  Implement duplex USART base on normal I/O pin               |  
  3. ;|  Using TIMER0 interrupt for bit timing                       |  
  4. ;|  Tested on PIC16F83 running at 4MHz                          |  
  5. ;|  Written by Paul Zhang, Microchip Tech Inc                   |  
  6. ;|  6 Aug, 2000                                                 |  
  7. ;|  All rights reserved                                         |  
  8. ;|--------------------------------------------------------------|  
  9.   
  10.     errorlevel    -302    ;no bank warning  
  11.     errorlevel    -301    ;no default file warning  
  12.        
  13.     list      p=16F83    ;define processor  
  14.     #include <p16F83.inc>    ;  
  15.   
  16.     __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC   
  17.     ;code protect         =    OFF  
  18.     ;watchdog         =    OFF  
  19.     ;power-up delay timer     =    ON  
  20.     ;oscillator mode     =    XT  
  21.   
  22. ;===============================  
  23. ;define RAM variables  
  24.     cblock    0x0c        ;GPR start from 0x0c  
  25. w_temp                ;W context saving during interrupt  
  26. status_temp            ;STATUS context saving during interrupt  
  27. pclath_temp            ;PCLATH context saving during interrupt  
  28.   
  29. USART_F                ;containing flags for USART  
  30. RX_BUFF                ;USART received data buffer  
  31. TX_BUFF                ;USART transmitting data buffer  
  32. RX_SLICE            ;RX bit-timing control  
  33. TX_SLICE            ;TX bit-timing control  
  34. RX_bcnt                ;RX received bit counting  
  35. TX_bcnt                ;TX transmitting bit counting  
  36. RX_STA                ;RX STATE-MACHINE controller  
  37. TX_STA                ;TX STATE-MACHINE controller  
  38.     endc   
  39.   
  40. ;===============================  
  41. ;pre-definition for readability  
  42. #define    RX_PIN    PORTA,2        ;assign RX pin  
  43. #define    TX_PIN    PORTA,3        ;assign TX pin  
  44. #define    TXEN    USART_F,0    ;USART transmit enable  
  45. #define    TXBUSY    USART_F,1    ;USRAT transmit is in progress  
  46. #define    RXBF    USART_F,2    ;USART receive buff full  
  47. #define    RXBUSY    USART_F,3    ;USART receive is in progress  
  48. #define    RX_ERR    USART_F,4    ;USART receive error  
  49. #define    TX_ERR    USART_F,5    ;USART transmit error  
  50.   
  51. ;===============================  
  52. ;define constant  
  53. #define    OSC_FREQ    .4000    ;oscillator frequency in KHz  
  54. #define    BAUDRATE    .2400   
  55. #define TMR0CONST    .118    ;256-OSC_FREQ*1000/4/(BAUDRATE*3) + 2  
  56.   
  57. ;===============================  
  58. ;for my personal style  
  59. #define    skp0    btfsc   
  60. #define    skp1    btfss   
  61.   
  62. ;**********************************************************************  
  63.         ORG     0x000   
  64.         clrwdt   
  65.           goto    MAIN        ; go to beginning of program  
  66.   
  67.   
  68. ;=======================================  
  69. ;Interrupt service routine  
  70.         ORG     0x004        ; interrupt vector location  
  71.   
  72.         movwf   w_temp        ; save off current W register contents  
  73.         movf    STATUS,w    ; move status register into W register  
  74.         banksel    status_temp   
  75.         movwf    status_temp    ; save off contents of STATUS register  
  76.         movf    PCLATH,w   
  77.         movwf    pclath_temp    ; save off contents of PCLATH  
  78.   
  79.         banksel    INTCON        ;select bank  
  80.         skp0    INTCON,T0IF    ;test for TMR0 interrupt  
  81.         goto    tmr0IntStart    ;do TMR0 ISR  
  82.         ;here test for any other interrupt source  
  83.         goto    int_end   
  84.   
  85. tmr0IntStart                ;TIMER0 interrupt service  
  86.         bcf    INTCON,T0IF    ;clear T0IF  
  87.            
  88.         ;====== start of RX =======  
  89.         movlw    high($)   
  90.         movwf    PCLATH        ;set PCLATH before PCL change  
  91.         movf    RX_STA,w    ;get the state value for RX  
  92.         andlw    0x03        ;for safeguard purpose  
  93.         addwf    PCL,f        ;switch to STATE  
  94.         goto    rxStartChk    ;check for START bit  
  95.         goto    rxReceiveBit    ;receive DATA bit  
  96.         goto    rxIdle        ;wait for idle  
  97.         goto    rxEnd        ;do nothing  
  98. rxStartChk    ;check for START bit  
  99.         skp0    RX_PIN        ;test RX pin for START bit  
  100.         goto    rxEnd        ;not found  
  101.         ;start bit found. do following  
  102.         movlw    .8   
  103.         movwf    RX_bcnt        ;count for 8 bits incoming data  
  104.         movlw    .4   
  105.         movwf    RX_SLICE    ;wait 4 time-slice for 1st data bit  
  106.         movlw    .1   
  107.         movwf    RX_STA        ;switch to STATE 1 for 1st data bit sampling  
  108.         goto    rxEnd   
  109. rxReceiveBit    ;receive DATA bit  
  110.         decfsz    RX_SLICE,f    ;wait of bit timing  
  111.         goto    rxEnd   
  112.         ;time to sample incoming data bit  
  113.         rrf    RX_BUFF,f    ;right shift for new bit space  
  114.         bcf    RX_BUFF,7    ;pre-set to 0  
  115.         skp0    RX_PIN        ;incoming data bit test  
  116.         bsf    RX_BUFF,7    ;set if data bit = 1  
  117.         movlw    .3        ;3 slice for data bit timing  
  118.         movwf    RX_SLICE    ;bit timing for next data bit  
  119.         decfsz    RX_bcnt,f    ;see if 8-bit completed  
  120.         goto    rxEnd   
  121.         ;bit receive completed, do follwoing  
  122.         movlw    .2   
  123.         movwf    RX_STA        ;set to STATE 2 for idle waiting  
  124.         bsf    RXBF        ;set receive buffer full  
  125.         movf    RX_BUFF,w    ;display data on PORTB  
  126.         movwf    PORTB   
  127.         goto    rxEnd   
  128. rxIdle        ;wait for idle  
  129.         skp0    RX_PIN        ;try to find STOP bit  
  130.         clrf    RX_STA        ;back to STATE 0 for next byte  
  131.         goto    rxEnd   
  132.         ;====== End of RX =========  
  133. rxEnd   
  134.         ;====== start of TX =======  
  135.         ;do TX, if transmit is engaged  
  136.         skp1    TXEN        ;skip if TXEN set, do TX  
  137.         goto    tmr0IntEnd    ;not in transmit mode  
  138.         movf    TX_SLICE,f    ;see if in bit-timing delay  
  139.         skpnz            ;  
  140.         goto    txDo        ;bit-timing completed  
  141.         decfsz    TX_SLICE,f    ;keep bit-timing delay  
  142.         goto    txEnd   
  143. txDo   
  144.         ;Transmit STATE-MACHINE control  
  145.         movlw    high($)   
  146.         movwf    PCLATH        ;set PCLATH before PCL change  
  147.         movf    TX_STA,w    ;get current state  
  148.         andlw    0x03        ;make sure in range  
  149.         addwf    PCL,f        ;switch to TX STATE  
  150.         goto    txStartBit    ;send START bit  
  151.         goto    txDatBit    ;send DATA bit  
  152.         goto    txStop        ;send STOP bit  
  153.         goto    txIdle        ;set transtim IDLE  
  154. txStartBit    ;TX_STA=0, send START bit here  
  155.         bsf    TXBUSY        ;set TX busy flag  
  156.         movlw    .8   
  157.         movwf    TX_bcnt        ;count for 8 bit transmitting  
  158.         bcf    TX_PIN        ;start bit  
  159.         movlw    .3   
  160.         movwf    TX_SLICE    ;set bit timing  
  161.         movlw    .1   
  162.         movwf    TX_STA        ;set transmit STATE-MACHINE  
  163.         goto    txEnd   
  164. txDatBit    ;TX_STA=1, send DATA bit here  
  165.         ;time for next bit sending  
  166.         rrf    TX_BUFF,f    ;rotate bit to C  
  167.         skpnc            ;test C  
  168.         goto    $+3   
  169.         bcf    TX_PIN        ;0 out  
  170.         goto    $+2   
  171.         bsf    TX_PIN        ;1 out  
  172.         movlw    .3   
  173.         movwf    TX_SLICE    ;wait 3 time-slices  
  174.         decfsz    TX_bcnt,f   
  175.         goto    txEnd        ;8 bit serial not end  
  176.         movlw    .2   
  177.         movwf    TX_STA        ;set transmit STATE-MACHINE  
  178.         goto    txEnd   
  179. txStop        ;TX_STA=2, send STOP bit here  
  180.         bsf    TX_PIN        ;send STOP bit  
  181.         movlw    .3   
  182.         movwf    TX_SLICE    ;set bit timing  
  183.         movlw    .3   
  184.         movwf    TX_STA        ;set transmit STATE-MACHINE  
  185.         goto    txEnd   
  186. txIdle        ;TX_STA=3, reset transmission to IDLE  
  187.         bcf    TXBUSY        ;not busy  
  188.         bcf    TXEN        ;not in transmission  
  189.         clrf    TX_STA        ;reset transmit STATE-MACHINE  
  190.         goto    txEnd   
  191.         ;====== End of TX =========  
  192. txEnd   
  193.         ;add more TMR0 related code here  
  194. tmr0IntEnd   
  195.         movlw    TMR0CONST   
  196.         addwf    TMR0,f   
  197.         goto    int_end   
  198.   
  199. int_end   
  200.         banksel    pclath_temp   
  201.         movf    pclath_temp,w    ; retieve copy of PCLATH register  
  202.         movwf    PCLATH   
  203.         movf    status_temp,w    ; retrieve copy of STATUS register  
  204.         movwf    STATUS        ; restore pre-isr STATUS register contents  
  205.         swapf   w_temp,f   
  206.         swapf   w_temp,w    ; restore pre-isr W register contents  
  207.         retfie            ; return from interrupt  
  208.   
  209.   
  210. ;=======================================  
  211. ;Code wriiten for test purpose  
  212. MAIN   
  213.         banksel    TRISA        ;select respective bank  
  214.         movlw    b'00000100'    ;RA2-input, RA3-output  
  215.         movwf    TRISA   
  216.         clrf    TRISB   
  217.         movlw    b'10001000'    ;TMR0 in timer mode  
  218.         movwf    OPTION_REG   
  219.         clrf    STATUS        ;make sure in bank 0  
  220.   
  221.         call    USART_INIT   
  222.   
  223.         movlw    TMR0CONST   
  224.         movwf    TMR0   
  225.   
  226.         movlw    0xff   
  227.         movwf    PORTB   
  228.   
  229.         bsf    INTCON,T0IE   
  230.         bsf    INTCON,GIE   
  231.            
  232. LOOP                    ;test code  
  233.         skp1    RXBF        ;wait for data received  
  234.         goto    $-1   
  235.         bcf    RXBF        ;clear data flag  
  236.         movf    RX_BUFF,w   
  237.         movwf    TX_BUFF        ;send back received data  
  238.         bsf    TXEN   
  239.         skp0    TXEN        ;wait for transmit completion  
  240.         goto    $-1   
  241.         goto    LOOP        ;  
  242.   
  243.     
  244.   
  245. ;=======================================  
  246. ;Initializtion of software USART  
  247. USART_INIT   
  248.         clrf    USART_F        ;clear all flag bit  
  249.         clrf    RX_STA        ;reset STATE MACHINE  
  250.         clrf    TX_STA   
  251.         bsf    TX_PIN        ;TX is in Idle  
  252.         return   



 

推荐文章:89C51 单片机I/O 口模拟串行通信的实现方法[图]

 
相关文章:

 
最新开源项目
 
 
  查看更多...  
 
本站相关产品   淘宝网店
 




 
  查看更多...  

 

本站程序由百合电子工作室开发和维护
Copyright @ baihe electric studio
渝ICP备09006681号-4