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

📄 iic.asm

📁 IIC总线
💻 ASM
字号:
;在本程序中用到A口的RA3,RA4,分别对应SCL和SDA位
;在主程序中初始化为高电平,并且在退出子程序时保持SCL为底电平,并且时钟线由(SCL)由单片机控制
;在子程序一定要确认SDA为输入还是输出
;注意A口本身默认为AD转换口(除RA4),要对ADCON1进行相关的配置

;************************************************************************
;                                IIC总线
;************************************************************************
;宏定义
ack    equ  00h                    ;应答位
scl    equ  03h                    ;
sda    equ  04h
rc4    equ  04h
rc5    equ  05h
rp0    equ  05h

pcl    equ  02h
status equ  03h
porta  equ  05h
portc  equ  07h
trisa  equ  85h
trisc  equ  87h
adcon1 equ  9fh
indf   equ  00h
fsr    equ  04h
;变量
mid1   equ  20h                     ;发送或接收中间量
rec1   equ  21h                     ;循环变量1
rec2   equ  22h						;循环变量2
databuff equ 23h                    ;输入或输出时数据的中转
flag    equ 24h                     ;是否收到应答信号标识位
numbyte equ 25h                     ;发送或接收的字节数
sla     equ 26h                     ;从器件的物理地址
suba    equ 27h                     ;发送或接收的从器件当中N位数据的首址
mtd     equ 28h                     ;接收发送数据缓冲区首址


;***************************************
;               主程序
;***************************************

      org   0000h
      goto  main
      org   0005h
main  
      bsf status,rp0                 ;入体1
      movlw 0f7h
      movwf adcon1                   ;A口设为数据输入输出
      bcf trisa,scl                  ;SCL位设为输出
      bcf trisc,rc4
      bcf trisc,rc5                  ;设为输出
      bcf status,rp0                 ;回体0
;****************************************************
      movlw b'10100000'
      movwf sla                      ;控制字(从器件的地址)
         
      movlw 30h                      
      movwf suba                     ;接收或发送的数据首址30h

      movlw 29h
      movwf mtd                      ;接收或发送数据缓冲区首址                   
    
      movlw 04h
      movwf numbyte                 ;设置为4个字节数据
      
      movlw 01h
      movwf 29h
      movlw 02h
      movwf 2Ah
      movlw 03h
      movwf 2Bh
      movlw 04h
      movwf 2Ch
    
      call sendn

;****************************************************


      movlw b'10100000'
      movwf sla                      ;控制字(从器件的地址)
         
      movlw 60h                      
      movwf suba                     ;接收或发送的数据首址30h

      movlw 30h
      movwf mtd                      ;接收或发送数据缓冲区首址                   
    
      movlw 04h
      movwf numbyte                 ;设置为4个字节数据

      call reciven                   ;接收发送出的四个数据
      
      movf 30h,w
      call table
      call display

      movf 31h,w
      call table
      call display

      movf 32h,w
      call table
      call display

      movf 33h,w
      call table
      call display
      
      goto $
;***************************************
;               段码表
;***************************************
;程序功能:返回所查字符段码
;入口参数:W
;出口参数:W      
;变量
table                      
      ADDWF  pcl,F
      RETLW  28H           ;0
      RETLW  0EBH          ;1
      RETLW  19H           ;2
      RETLW  89H           ;3
      RETLW  0CAH          ;4
      RETLW  8CH           ;5
      RETLW  0CH           ;6
      RETLW  0E9H          ;7
      RETLW  08H           ;8
      RETLW  88H           ;9
       
;********************************************
;                读取N个数据
;********************************************
;程序功能:读取器件中指定地址开始的N 个数据
;入口参数: 器件地址SLA ,数据地址SUBA ,接收字节数NUMBYTE,接收数据缓冲区首址MTD
;出口参数: 
;变量 sla,suba,numbyte,mtd

reciven
      call start                 ;发送开始信号

      movf sla,w                 ;寻找从器件
      movwf databuff             
      call send
      call chack 
      btfss flag,ack
      goto reend                 ;没有找到,返回

      movf suba,w                ;要读取数据地址
      movwf databuff
      call send
      call chack
      btfss flag,ack
      goto reend

      call start                 ;重新启动总线
      movf sla,w
      movwf databuff             ;从器件的地址
      incf databuff,f              ;改为读方式
      call send
      call chack
      btfss flag,ack
      goto reend
      movf mtd,w
      movwf fsr
relop2      
      call recive
      movf databuff,w
      movwf indf
      decfsz numbyte,f
      goto relop1
      call snack
reend 
      call stop
      return
relop1
      call sack
      incf fsr,f
      goto relop2
;********************************************
;                写N个数据
;********************************************
;程序功能:向器件指定子地址写N个数据
;入口参数: 器件地址SLA,起始地址SUBA 发送字节数NUMBYTE,数据起始地址在FSR中
;          发送数据缓冲区首址MTD
;出口参数: 
;变量 sla,suba,numbyte  
sendn
      call start                       ;发送开始信号

      movf sla,w                       ;寻找从器件
      movwf databuff
      call send
      call chack
      btfss flag,ack
      goto seend                       ;未检测到应答信号,返回(可能是从器件存储器出问题)
   
      movf suba,w                      ;发送要写入数据地址
      movwf databuff
      call send
      call chack
      btfss flag,ack
      goto seend                        ;无应答返回
      
      movf mtd,w                          ;有应答,把首址放入FSR
      movwf fsr  
selop1
      movf indf,w
      movwf databuff
      call send
      call chack
      btfss flag,ack
      goto  sendn                      ;如果没有收到信号就重新开始 
      incf fsr,f
      decfsz numbyte,f
      goto selop1 
seend 
      call stop
      call delay
      return
 
;***************************************
;               发送一个字节
;***************************************
;程序功能:
;入口参数:databuff
;出口参数:      
;变量  databuff,rec1

send     
      bsf status,rp0
      bcf trisa,sda               ;sda输出
      bcf status,rp0
      
      movlw 08h                   ;发送8位数据
      movwf rec1

selp3 btfss databuff,7
      goto  selp0
      goto  selp1
      
selp2 rlf databuff,f
      decfsz rec1,f
      goto selp3
      nop
      return

selp0 bcf porta,sda
      nop
      nop
      nop                 ;应该不用这么长时间..............
      nop
      nop
      bsf porta,scl
      nop
      nop
      nop                 ;高电平持续4us就可以了
      nop
      nop
      bcf porta,scl
      nop
      goto selp2

selp1 bsf porta,sda
      nop
      nop
      nop
      nop
      nop
      bsf porta,scl
      nop
      nop
      nop
      nop
      nop
      bcf porta,scl
      nop
      goto selp2

;***************************************
;               接收一个字节
;***************************************
;程序功能:
;入口参数:
;出口参数:databuff     
;变量 rec1,databuff

recive
      bsf status,rp0                 
      bsf trisa,sda                             ;sda输入
      bcf status,rp0
      movlw 08h
      movwf rec1
relp1 bsf porta,sda                            ;先把端口写1,由存储器把它拉低
      nop 
      nop
      bsf porta,scl
      nop
      nop 
      bcf status,0
      bsf databuff,0
      btfss porta,sda
      bcf databuff,0
      bcf porta,scl
      rlf databuff,f
      nop
      nop
      nop
      decfsz rec1,f                             ;判断是否完成8位数据的接收接收完返回
      goto relp1
      rrf databuff,f
      nop
      return
      
;***************************************
;               开始信号
;***************************************
;程序功能:IIC开始信号
;入口参数:
;出口参数:      
;变量  

start
      bsf status,rp0             ;体1
      bcf trisa,sda              ;sda位输出
      bcf status,rp0             ;回体0
      bsf porta,sda
      nop
      bsf porta,scl               ;起始条件建立4.7us
      nop 
      nop
      nop
      nop
      nop
      bcf porta,sda               ;开始信号4us
      nop
      nop
      nop
      nop
      nop
      bcf porta,scl               ;初始条件建立准备发送数据   
      nop
      return

;***************************************
;               停止信号
;***************************************
;程序功能:返回所查字符段码
;入口参数:
;出口参数:      
;变量  

stop
      bsf status,rp0             ;体1
      bcf trisa,sda              ;sda位输出
      bcf status,rp0             ;回体0
      
      bcf porta,sda              
      nop
      bsf porta,scl              ;发送最后一个结束信号的时钟   要大于4us
      nop
      nop
      nop
      nop
      nop
      bsf porta,sda               ;停止位   要保证和下一次开始之间的时间大于4.7us
      nop
      nop
      nop
      nop
      nop
      return

;***************************************
;               发送应答信号
;***************************************
;程序功能:
;入口参数:
;出口参数:      
;变量  

sack
      bsf status,rp0
      bcf trisa,sda               ;设为输出
      bcf status,rp0
      bcf porta,sda
      nop
      nop
      bsf porta,scl
      nop
      nop
      nop
      nop
      bcf porta,scl
      nop
      nop
      return

;***************************************
;             发送非应签信号
;***************************************
;程序功能:
;入口参数:
;出口参数:      
;变量  
snack
      bsf status,rp0
      bcf trisa,sda
      bcf status,rp0
      bsf porta,sda
      nop
      nop
      bsf porta,scl
      nop
      nop
      nop
      nop
      nop
      bcf porta,scl
      nop
      nop
      return

;***************************************
;             检测应答信号
;***************************************
;程序功能:
;入口参数:
;出口参数:      
;变量  flag
chack                                 
      bsf porta,sda                   ;置高后由存储器把信号拉低  
      nop
      bsf status,rp0
      bsf trisa,sda                    ;输入
      bcf status,rp0
      nop
      bsf porta,scl
      bcf flag,ack                     ;清除标志位
      nop
      nop
      nop
      btfss porta,sda
      bsf flag,ack                     ;置位flag
      nop
      nop
      bcf  porta,scl
      nop
      nop
      return


      
;******************************************
;               显示
;******************************************
;程序功能:显示W寄存器的内容
;入口参数:W
;出口参数:
;变量:rec1,mid1
display
      movwf mid1
      movlw 09h                           
      movwf rec1
di4   decfsz rec1,f
      goto  di1
      goto  diend
di1   bcf   portc,rc4
      btfsc mid1,0
      goto  di2
      bcf   portc,rc5
      goto  di3
di2   bsf   portc,rc5      
di3   rrf   mid1,f
      bsf   portc,rc4
      goto  di4 
diend return   

;******************************************
;               延时10ms
;******************************************
;程序功能:
;入口参数:
;出口参数:
;变量:rec1,rec2

delay  
       movlw 0ffh
       movwf rec1
delp2  movlw 0ffh
       movwf rec2
delp1  decfsz rec2,f
       goto delp1
       decfsz rec1,f
       goto delp2
       return
     end
  
      

⌨️ 快捷键说明

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