⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pic16c74_485.asm

📁 这是一个PIC16F74的485通信程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
;******************************************************************************
;                                                                             *
;    文件名称:RS485通讯,PORTD输出.asm                                         *
;    日期:2004-10-31  12:10                                                   *
;    文件版本:V3.0                                                            *
;;******************************************************************************
;    注意:    如果你要更改,请先保存本文件,然后新建立一个文件!!!!
;    说明:                                                                    *
;   端口设置:                                                                 *
;    MAX485 通讯                                                              *
;    RC0-->/RE-->DE                                                           *
;    RC6-->TXD-->DI   ( MAX485: 1-RO 2-/RE 3-DE 4-DI 5-GND 6-A 7-B 8-VCC      *
;    RC7-->RXD-->RO                                                           *
;-----------------------------------------------------------------------------*
;
;    D口为继电器输出口                                                        *
;    输出高电位为打开,外面接光耦隔离继电器输出,继电器为直流24V供电.           *
;
;    指令格式为:#AA(DATA)CR                                                   *
;    前导字符:# ,地址:AA,命令数据ATA,结束符:回车(ODH)-->CR,共6个字符          *
;    (DATA)-- 00-FF                                                           *
;     00-FF 表示从D口输出的数据                                               *
;    要D口输出数据时返回输出的格式为:>AACR
;     ****标准的ADAM4050、4060指令格式,共4个字符                              *
;
;!!!!!!!! 必须注意在启动发送时,要给他延迟时间
;
;    本机地址为"01"                                                           *
;    60-65H-->接收存储区                                                      *
;    66H开始为发送数据的存储区
;    使用了接收中断,使用发送中断                                             *
;    用TMR1做为接收时间限制,                                                 *
;    如果在固定时间(2ms)内没有接收到下一个字符,则接收计数器清0               *
;                                                                             *
;******************************************************************************

LIST  P=16C74,R=HEX

         INCLUDE "P16C74.INC"

;------------------定义变量寄存器----------------------------------------------
W_TEMP             EQU  0x020
S_TEMP             EQU  0x021

MYSTATUS           EQU  0x022      ;0--接收完毕;1-D口输出数据允许;

RC_CP              EQU  0x023      ;接收数据个数的寄存器
RC_FSR             EQU  0x024      ;接收到的数据存储的地址指针寄存器
TX_CP              EQU  0x025      ;发送个数计数器
TX_FSR             EQU  0x026      ;发送缓冲区的地址指针
COMMAND_BUF        EQU  0x027      ;接收到的指令缓存寄存器
COMMAND            EQU  0x028      ;命令寄存器
COMMAND_ASCII_L    EQU  0x029      ;命令低4位的ASCII码
COMMAND_ASCII_H    EQU  0x02A      ;命令高4位的ASCII码
Delay256us_Reg     EQU  0x02E      ;定时器寄存器
Delay1ms_Reg       EQU  0x02F      ;定时器寄存器
;------------------定义字符常量------------------------------------------
RC_FSR_S           EQU  0x060      ;接收存储区首地址
RC_CNT             EQU  0x006       ;接收字符的个数
TX_FSR_S           EQU  0x066       ;发送区首地址
START_RC           EQU  '#'        ;0x23接收的前导字符
START_TX           EQU  '>'        ;0x3E发送的前导字符
END_ASCII          EQU  0x0D       ;回车   发送的结束字符
ADDRESSH           EQU  '0'        ;0x30 本机地址高字节
ADDRESSL           EQU  '1'        ;0x31 本机地址底字节


;--------------------程序开始--------------------------------------------

        ORG      0x0000
        GOTO     MAINLINE
        ORG      0x0004
        GOTO     IntService

;----------------------------------------------------------------
;----------------------------------------------------------------
MAINLINE
        CALL     MAIN_INIT
MAINLOOP
        CLRWDT
        BCF      STATUS,RP0
        BTFSC    MYSTATUS,0 
        CALL     TEST_RCFIFO   ;是,执行测试接收到的字符是否为本机命令,执行输出程序,和发送配制
        BTFSC    MYSTATUS,1    ;是否允许更新D口数据        
        CALL     PORTD_OUT     ;YES 将指令从D口输出
        GOTO     MAINLOOP

;----------------------------------------------------------------
;------------------查表程序---------------------
;----------------------------------------------------------------
ATH_TABEL
     ADDWF    PCL,F          ;ASCII     CHR
     RETLW    0x000          ;0X30      ;0  
     RETLW    0x001          ;0x31      ;1 
     RETLW    0x002          ;0x32      ;2 
     RETLW    0x003          ;0x33      ;3 
     RETLW    0x004          ;0x34      ;4 
     RETLW    0x005          ;0x35      ;5 
     RETLW    0x006          ;0x36      ;6 
     RETLW    0x007          ;0x37      ;7 
     RETLW    0x008          ;0x38      ;8 
     RETLW    0x009          ;0x39      ;9 
     RETLW    0              ;0x3A      ;:
     RETLW    0              ;0x3B      ;;
     RETLW    0              ;0x3C      ;<
     RETLW    0              ;0x3D      ;=
     RETLW    0              ;0x3E      ;>
     RETLW    0              ;0x3F      ;?
     RETLW    0              ;0x40      ;@
     RETLW    0x00A          ;0x41      ;A
     RETLW    0x00B          ;0x42      ;B
     RETLW    0x00C          ;0x43      ;C
     RETLW    0x00D          ;0x44      ;D
     RETLW    0x00E          ;0x45      ;E
     RETLW    0x00F          ;0x46      ;F     


;*******************************;程序初始化************************************
MAIN_INIT    

;^^^^^^^^^^^^^^^^^^^^^^^^^^^各个功能寄存器设置^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     BANKSEL  OPTION_REG       ;BANK1
     MOVLW    B'00001111'      ;下降沿触发,1:128用于WDT
     MOVWF    OPTION_REG       ;
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    BANKSEL  TRISB             ;
     MOVLW    B'11111111'      ;
     MOVWF    TRISB            ;PORTB IS INPUT
     BCF      TRISC,0          ;PORTC0 IS OUTPUT ,MAX485-->/RE-->DE 
     CLRF     TRISD            ;PORTD IS OUTPUT
     BSF      PIE1,RCIE        ;允许接收中断 
    BANKSEL  INTCON            ;BANK 0 
     MOVLW    B'11010000'      ;
     MOVWF    INTCON           ;开总中断,允许外围中断,INT中断
;^^^^^^^^^^^^^^^^^^^^^^^^^^^串口通讯设定^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
UART_INIT   
    BANKSEL  SPBRG              ;BANK 1 
     MOVLW    0x019             ;4MHz    
     MOVWF    SPBRG             ;9600dps
     BSF      TXSTA,BRGH        ;高速模式 
     BSF      TXSTA,TXEN        ;启动UART的传送功能,
     BCF      TRISC,6           ;TX,数据输出功能引脚
     BSF      TRISC,7           ;RX,数据接收功能引脚
    BANKSEL   RCSTA             ;BANK 0 
     BSF      RCSTA,CREN        ;启动UART的接收功能,
     BSF      RCSTA,SPEN        ;激活UART的全部功能,
;^^^^^^^^^^^^^^^^^^^^^^^^^^^^^其他寄存器设置^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     BCF      PORTC,0           ;SET MAX485 IS 接收状态  ( PC.0=0 )
     CLRF     PORTD             ;
     MOVLW    RC_FSR_S          ;
     MOVWF    RC_FSR            ;确定接收存储的首地址
     CLRF     RC_CP             ;复位接收计数器
     MOVLW    TX_FSR_S          ;
     MOVWF    TX_FSR            ;确定发送存储的首地址
     CLRF     TX_CP             ;复位发送计数器
     CLRF     COMMAND
     RETURN
     
     
;====================中断服务程序=================================================
IntService:
     MOVWF    W_TEMP         ;||||||||||
     SWAPF    STATUS,W       ;||||||||||
     MOVWF    S_TEMP         ;||||||||||保存现场  
    BANKSEL  INTCON          ;BANK 0 
COLSEInt:
     BCF      INTCON,GIE
     BTFSC    INTCON,GIE
    GOTO     COLSEInt        ;确认关闭了总中断则向下执行,否则继续关闭总中断.
     BTFSC    PIR1,RCIF      ;判断是否为接收中断?是则执行<接收服务>程序.否则向下执行
     CALL     RC_Service
    BANKSEL  PIE1
     BTFSS    PIE1,TXIE
    GOTO     $+4   
    BANKSEL  PIR1 
     BTFSC    PIR1,TXIF      ;判断是否为发送中断,是,执行TX中断服务    
     CALL     TX_Service 
    BANKSEL  PIR1 
     BTFSC    PIR1,TMR1IF    ;判断是否为定时器中断,是,执行定时器中断服务
     CALL     TMR1_Service
POP_S
    BANKSEL  S_TEMP
     SWAPF    S_TEMP,W       ;|||||||||
     MOVWF    STATUS         ;|||||||||
     SWAPF    W_TEMP,F       ;|||||||||
     SWAPF    W_TEMP,W       ;|||||||||恢复现场
    RETFIE   
;*********************************接收服务****************************

RC_Service  
;PUT_RCFIFO   ;接收队列,将接收到的数据保存起来,用来判断是不是发到本机的数据
    BANKSEL  RC_CP             ;BANK 0 
     MOVF     RC_CP,W
     SUBLW    RC_CNT
     BTFSC    STATUS,Z         ;判断接收队列是否已经满了,
    RETURN                      ;如果满了就退出本服务,否则向下执行
     INCF     RC_CP,F          ;RC_CP+1   接收计数器+1 
     MOVF     RC_FSR,W          ;存储地址
     MOVWF    FSR              ;设定间接寻址的目标寄存器为RC_FSR
     MOVF     RCREG,W          ;RCDATA
     MOVWF    INDF             ;SAVE DATA
     INCF     RC_FSR,F          ;将地址指针加1
;****必须这么做的原因是:不这么做的时候,存储区的地址超出了他的范围,
;进入了后面的存储区域,造成程序错误.!!!!!!!!
;这样可以使存储区进行循环不会超出范围
     MOVLW    RC_CNT
     ADDLW    RC_FSR_S         ;个数+首地址=结束地址+1.
     SUBWF    RC_FSR,W         ;
     BTFSS    STATUS,Z         ;判断是否存储区满?
    GOTO    SET_TMR1           ;否:执行接收超时设置
     MOVLW    RC_FSR_S         ;是: 初始化接收存储器地址指针 
     MOVWF    RC_FSR
     BSF      MYSTATUS,0       ;接收完成,放置自己的标志位
    RETURN  
SET_TMR1
    BANKSEL  TMR1L            ;复位定时器,为定时器设置初值
      MOVLW   0x00            ;定时为1ms,所以开始初值为"FC17" 大约为FC00
      MOVWF   TMR1L           ;晶体震荡为4MHZ,每条指令为1us.
      MOVLW   0xFC
      MOVWF   TMR1H  
      MOVLW    B'00010001'    ;打开TMR1定时器,1:2,为进行2ms延时
      MOVWF    T1CON          ;工作在定时器方式
    BANKSEL   PIE1
     BSF      PIE1,TMR1IE     ;启动接收计时器中断
     BCF      STATUS,RP0
    RETURN
 
  
 
;********************************接收《判断服务》*********************************
TEST_RCFIFO
    BANKSEL  MYSTATUS
       BCF     MYSTATUS,0     ;清除标志位,防止重复调用
     CLRF     RC_CP           ;CLEAR RC_CP  复位接收计数器,允许下次接收
    BANKSEL  PIE1
      BCF     PIE1,RCIE        ;禁止接收中断
      BCF     PIE1,TMR1IE      ;禁止接收定时器中断,
    BCF  STATUS,RP0
     CLRF     T1CON            ;清除定时器内的数据,复位定时器
;~~~~~~~~~~~~ TEST START ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     MOVLW    RC_FSR_S

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -