📄 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 + -