;;这是遥控发端编码板,编码1-256号。用AT89CS51模拟的,带有键盘
;程序作者:姬瑞江。
;时间:2005年8月16日。
;程序版本:Ver1.2兼容Ver1.0、Ver1.1
;程序功能:驱动LED显示。键盘输入。模拟PT2272编码,数据输出使能延时1.5S,优化时间算法使发送单个数据包时间缩短1/3;REST时间由Ver1.0的4分钟缩短1.8分钟。
;模拟PT2272串行数据输出和数据输出使能。
TF2 BIT 0CFH
EXF2 BIT 0CEH
RCLK BIT 0CDH
TCLK BIT 0CCH
EXEN2 BIT 0CBH
TR2 BIT 0CAH
C_T2 BIT 0C9H
CP_RL2 BIT 0C8H
T2CON DATA 0C8H
RCAP2L DATA 0CAH
RCAP2H DATA 0CBH
TL2 DATA 0CCH
TH2 DATA 0CDH
WDTC DATA 0C0H
WDTD DATA 86H
SFDT DATA 0F8H
SFAL DATA 0F9H
SFAH DATA 0FAH
SFCM DATA 0FBH
SFCF DATA 0F7H
cbit equ 3fh
buffer equ 40h
codedata equ 41h ;41h-51h is code data
counterconvert equ 36h
counterBIT equ 39h
counterT equ 38h
Tcounter equ 37h
ADDR equ 35h
DATA4 equ 34h
key1 equ 52h
key2 equ 53h
key3 equ 54h
key4 equ 55h
keyposi equ 56h
memposi equ 57h
uartposi equ 58h
uartbuf1 equ 59h
uartbuf2 equ 60h
uartbuf3 equ 62h
uartflag equ 61h
dispposi equ 63h
addrbuf equ 64h
;delayflag equ 65h
EXMT equ 2fh
on equ 0F0h ;开态PT2272的引脚Dout值为高4位,此设定F0H为4位都为高
off equ 000h ;关态PT2272的引脚Dout值为高4位,此设定00H为4位都为低
EXMP BIT EXMT.0
dataout equ P1.7 ;PCM输出引脚
ampout equ p1.6 ;amp out
timerH equ 0FFh ;对于OSC=12Mhz时PCM输出的定时器设定值,
timerL equ 038h ;timerH为高字节,timerL为低字节
write equ 10100000B ;EEPROM写入命令字
read equ 10100001B ;EEPROM读出命令字
org 00h ;程序总入口
jmp main
org 0bh ;timer0的中断入口
jmp timerint
org 0023H ;串口中断的入口
jmp uartINT
org 002BH ;timer2的中断入口
jmp timer2INT
org 40h ;主程序开始地址
;==========================主程序开始于此===================
main:
;此下为测试代码
;test display
; mov r1,#0
;temp1: mov key1,r1
; mov key2,key1
; mov key3,key2
; mov key4,key3
; lcall display
;
; inc r1
; cjne r1,#10,temp
; mov r1,#0
;temp:
; jmp temp1
;~~~~~~~~~~~测试EEPROM
;mov r4,#0
;testread:
;call eepr
;inc r4
;cjne r4,#5,testread
;mov r4,#0
;mov r5,#0
;testeep:
;mov a,r4
;mov r5,a
;call eepw;
;inc r4
;cjne r4,#05h,testeep
;jmp main
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~测试写入eprom
;temp: mov keyposi,#3
; mov addr,#255
; call openon
; mov keyposi,#3
; mov addr,#255
; call shutdown
; jmp temp
;此上为测试代码
;=========================================
mov sp,#66h ;=
mov memposi,#00h ;=
mov dispposi,#0 ;=
mov IE,#10110010b ;=
setb PT0 ;=
;=========================================
clr et1
orl PCON,#00000000B
mov tmod,#021h
mov TH1,#0E6h
mov TL1,#0E6h
setb TR1
;timer2初始化
mov t2con,#00000000h
mov th2,#0ECH
mov tl2,#078H
mov rcap2h,#0ECH
mov rCAP2L,#078H
setb tr2
;串口设置
mov SCON,#01010000b
mov uartposi,#0
mov cbit,#6 ;发送次数基数
mov EXMT,#0 ;按键功能寄存器清0。
clr dataout
call clrdisp ;清除显示
clr ampout
;=================================================================
;debug:
; call delay1500ms
; jmp debug
;=================================================================
waitkey: ;等待按键与处理按键
lcall keyscan ;调用按键处理子程序
cjne a,#80h,tokeyloop ;返回编码为80H,则为无按键输入
mov a,uartflag
cjne a,#0fh,waitkey ;串口标志为0fh,说明同步码与地址、命令接收正确,可以进行相应动作,否则继续扫描键盘
jmp uartok
tokeyloop:
jmp keyloop ;有按键按下,转到keyloop进行键盘编码处理
uartINT: ;===============串口中断程序=============================
clr EA
clr RI
clr TI
push acc
push psw
mov a,SBUF
mov uartbuf3,a
mov a,uartposi ;判断现在接收的是计算机发送的第几位字节
cjne a,#0,uart1 ;若为0,则接收到的第一个字节若为f5h则位置计数加一
mov a,uartbuf3
cjne a,#0F5h,retuart1
mov uartposi,#1
jmp retuart
uart1:
cjne a,#1,uart2
mov a,uartbuf3 ;若为1,则接收到的第二个字节是00F,01F,02F时则存于uartbuf1
cjne a,#00h,uart11
jmp uart1ok
uart11: cjne a,#01h,uart12
jmp uart1ok
uart12: cjne a,#02h,retuart1
uart1ok:
mov uartBUF1,a
mov uartposi,#2
jmp retuart
uart2: cjne a,#2,uart3 ;若为2,则接收到的第三个字节存于uartbuf2
mov a,uartbuf3
mov uartBUF2,a
mov uartposi,#3
jmp retuart
uart3: cjne a,#3,retuart1
mov a,uartbuf3 ;若为3,则接收到的第三个字节若为f5h则转去处理串口接收的数据
cjne a,#0F5h,retuart1
mov uartflag,#0fh ;设置串口接收成功的标志位
retuart1: mov uartposi,#0
retuart:
pop psw
pop acc
setb EA
reti ;===============退出串口中断程序=========================
uartok: ;串口接收数据正确,进行相应的操作
mov uartflag,#00h ;清除标志位
mov a,uartbuf1
cjne a,#0,uartok1 ;开启特定的电动机
;PC发送开启命令,单片机进行相应动作,通过子程序发送编码信号
mov keyposi,#3
setb ampout
call delay1500ms
mov cbit,#12 ;发送基数赋值
call shutrecent ;关闭最近开启的机器
mov addr,uartbuf2
call uart2key ;调用子程序将串口数据转为显示代码
mov cbit,#6 ;发送基数赋值
jmp uartin ;进入开启机器的程序
uartok1:
cjne a,#1,uartok2 ;PC关断相应的机器
mov keyposi,#2
mov addr,uartbuf2
call uart2key
setb ampout
call delay1500ms
mov cbit,#12
call shutdown
jb tr0,$
call delay500ms
clr ampout
jmp retuartok
uartok2:
cjne a,#2,retuartok ;PC控制全部关断电动机
jmp uartin2 ;进入关断的程序
retuartok:
jmp waitkey
keyloop: ;=============按键处理程序============
;===========================按下关断键,关断特定的机器
;shut down key pushed,shut down a sub-device
cjne a,#0bh,shutall
;if wrong ,can not send data
mov a,key4
cjne a,#0ffh,shut1 ;无地址输入,退出
jmp retkeyloop
shut1:
call key2add ;将按键输入转化为地址代码
mov a,keyposi
cjne a,#0,inputwrong1
jmp retkeyloop
inputwrong1:
setb ampout
call delay1500ms
mov cbit,#12
call shutdown ;关断指定的机器
jb tr0,$
call delay500ms
clr ampout
jmp retkeyloop
;===========================复位键按下,关断全部机器
;reset key pushed ,shut down all sub-device
shutall:cjne a,#0Eh,open
;r4 is address ,r5 is data ,eepw and eepr is the subprogramm
uartin2:
mov keyposi,#2
mov key1,#0ah
mov key2,#0ah
mov key3,#0ah
mov key4,#0ah
setb ampout
call delay1500ms
mov cbit,#12
call shutrecent ;先关断最近开启的机器
mov cbit,#6
call shutdownall ;关断全部的机器
mov key1,#0eh
mov key2,#0eh
mov key3,#0eh
mov key4,#0eh
jb tr0,$
call delay500ms
clr ampout
jmp retkeyloop
;===========================开启特定的机器
;open on a sub-device
open:
cjne a,#0Fh,clearkey
;open key pushed ,convert the key data to ADD data and send PWM by subPRO
mov a,key4
cjne a,#0ffh,open2
jmp retkeyloop ;无地址输入,退出
open2:
call key2add ;将按键码转换为地址
mov a,keyposi
cjne a,#0,inputwrong2
jmp retkeyloop
inputwrong2:
setb ampout
call delay1500ms
mov cbit,#12
call shutrecent ;关断最近开启的机器
mov cbit,#6
call key2add ;将按键码转换为地址
uartin: mov a,memposi ;根据eeprom的存贮位置将地址码存入,保证存贮信息为最后5次开启机器编号
cjne a,#5,notovermem
mov memposi,#0
notovermem:
inc memposi
mov r4,memposi
mov r5,addr
mov addrbuf,r5
call eepw
call openon ;开启机器
;call shutother ;关闭其他机器
;r4 is address ,r5 is data ,eepw and eepr is the subprogramm
jb tr0,$
call delay500ms
clr ampout
jmp retkeyloop
;清除键按下,清除显示
;clear key pushed, clear the display
clearkey:
cjne a,#0ch,keyloop1
call clrdisp
jmp retkeyloop
;==========================以下为按键位置判断,以在LED上正常显示
keyloop1:
cjne a,#0ah,filter1
jmp retkeyloop
filter1:
cjne a,#0dh,filter2
jmp retkeyloop
filter2:
mov r7,keyposi
cjne r7,#0,keyloop2
mov key4,a
mov keyposi,#1
jmp retkeyloop
keyloop2:
cjne r7,#1,keyloop3
mov key3,key4
mov key4,a
mov keyposi,#2
jmp retkeyloop
keyloop3:
cjne r7,#2,keyloop4
mov key2,key3
mov key3,key4
mov key4,a
mov keyposi,#3
jmp retkeyloop
keyloop4:
cjne r7,#3,retkeyloop
retkeyloop:
mov cbit,#6
jmp waitkey
;=========================子程序部分
;sub programme
;===============看门狗程序
timer2INT:
push acc
push psw
clr TF2
mov 0A6H,#01EH
mov 0A6H,#0E1H
call display
pop psw
pop acc
reti
;===============将计算机传来的地址码转换为键盘码,用于显示
uart2key:
mov a,addr
cjne a,#255,uart2key1
mov key2,#2
mov key3,#5
mov key4,#6
jmp retuart2key
uart2key1:
inc a
mov b,#100
div ab
mov key2,a
mov a,b
mov b,#10
div ab
mov key3,a
mov key4,b
retuart2key:
ret
;===============开启特定机器的子程序
openon:
jb tr0,openon
mov a,keyposi
cjne a,#0,notretopenon
jmp retopenon
notretopenon:
mov data4,#on
call senddata
retopenon:
mov key1,#0Eh
ret
;===============关闭特定机器的子程序
shutdown:
jb tr0,$
mov a,keyposi
cjne a,#0,notretshut
jmp retshutdown
notretshut:
mov data4,#off
call senddata
retshutdown:
mov key1,#4ah
ret
;===============关闭最近开启机器的子程序
shutrecent:
mov r4,#1
shutrecent2:
call eepr
mov addr,r5
call shutdown
inc r4
cjne r4,#6,shutrecent2
ret
;===============关闭所有机器的子程序
shutdownall:
mov r7,#255
shutdownall3:
mov addr,r7
call shutdown
djnz r7,shutdownall3
mov addr,#0
call shutdown
mov r7,#255
shutdownall4:
mov addr,r7
call shutdown
djnz r7,shutdownall4
mov addr,#0
call shutdown
ret
;===============关闭除当前刚开启机器以外机器的子程序
Shutother:
mov r7,#255
shutother1:
mov addr,r7
mov a,addrbuf
cjne a,addr,shutother2
call shutdown
shutother2:
djnz r7,shutother1
mov addr,#0
call shutdown
mov key1,#0EH
ret
;===============将显示清空的子程序
clrdisp:
mov keyposi,#0
mov key1,#0FFh
mov key2,#0FFh
mov key3,#0FFh
mov key4,#0FFh
ret
clrdis: jnb EXMP,retdis
mov keyposi,#0
mov key1,#0FFh
mov key2,#0FFh
mov key3,#0FFh
mov key4,#0FFh
clr exmp
retdis: ret
;===============将键盘输入转换为8位的地址码
key2add:
mov b,#10
mov a,key3
cjne a,#0ffh,shiwei
mov r4,#0
mov r5,#0
jmp gewei
shiwei: mul ab
mov r4,b
mov r5,a
clr c
mov b,#100
mov a,key2
cjne a,#0ffh,baiwei
jmp gewei
baiwei: mul ab
clr c
add a,r5
mov r5,a
mov a,b
addc a,r4
mov r4,a
;first two byte
gewei: mov a,key4
cjne a,#0ffh,gewei2
jmp overflow
gewei2: clr c
add a,r5
mov r5,a
mov a,r4
addc a,#0
mov r4,a
;--------------------added
clr c
dec r5
cjne r5,#0ffh,gewei3
dec r4
;--------------------added
gewei3: cjne r4,#0,overflow
mov addr,r5
jmp retkey2add
overflow:
call clrdisp
retkey2add:
ret
;===============LED的显示子程序
;display subprogramme for LED
display:
mov a,dispposi
cjne a,#0,disp1
mov dispposi,#1
mov a,key1
call codeconvert
setb P1.1
setb P1.2
setb P1.3
mov P0,a
clr P1.0
jmp retdisp
disp1:
cjne a,#1,disp2
mov dispposi,#2
mov a,key2
call codeconvert
setb p1.0
setb P1.2
setb P1.3
mov P0,a
clr P1.1
jmp retdisp
disp2:
cjne a,#2,disp3
mov dispposi,#3
mov a,key3
call codeconvert
setb P1.0
setb P1.1
setb P1.3
mov P0,a
clr P1.2
jmp retdisp
disp3:
cjne a,#3,retdisp1
mov a,key4
call codeconvert
setb P1.1
setb P1.2
setb P1.0
mov P0,a
clr P1.3
retdisp1:
mov dispposi,#0
retdisp:
ret
;===============将按键码转换为LED对应的引脚电平状态
codeconvert:
cjne a,#1,code2
mov a,#0f9h
jmp retconvert
code2:
cjne a,#2,code3
mov a,#0a4h
jmp retconvert
code3:
cjne a,#3,code4
mov a,#0b0h
jmp retconvert
code4:
cjne a,#4,code5
mov a,#99h
jmp retconvert
code5:
cjne a,#5,code6
mov a,#92h
jmp retconvert
code6:
cjne a,#6,code7
mov a,#82h
jmp retconvert
code7:
cjne a,#7,code8
mov a,#0f8h
jmp retconvert
code8:
cjne a,#8,code9
mov a,#80h
jmp retconvert
code9:
cjne a,#9,codezero
mov a,#90h
jmp retconvert
codezero:
cjne a,#00h,codea
mov a,#0c0h
jmp retconvert
codea:
cjne a,#0ah,codeb
mov a,#88h
jmp retconvert
codeb:
cjne a,#0bh,codec
mov a,#83h
jmp retconvert
codec:
cjne a,#0ch,coded
mov a,#0c6h
jmp retconvert
coded:
cjne a,#0dh,codee
mov a,#0a1h
jmp retconvert
codee:
cjne a,#0eh,codef
mov a,#86h
jmp retconvert
codef:
cjne a,#0fh,codep
mov a,#8eh
jmp retconvert
codep:
cjne a,#01ah,codeu
mov a,#8ch
jmp retconvert
codeu:
cjne a,#2ah,codey
mov a,#0c1h
jmp retconvert
codey:
cjne a,#3ah,codeh
mov a,#91h
jmp retconvert
codeh:
cjne a,#4ah,codel
mov a,#89h
jmp retconvert
codel:
cjne a,#5ah,retconvert
mov a,#0c7h
jmp retconvert
retconvert:
ret
;===============键盘扫描程序
;keyboard input, output the key
keyscan:
mov p2,#0fh
mov a,p2
orl a,#0f0h
cpl a
jz nokey
lcall delay30ms ;延时30ms
lcall scan ;扫描按键输入
mov b,a ;暂时保存键盘输入
keep: ;如果一直按键,程序将一直停在此处
;此部分保证一次取一个按键码
mov p2,#0fh
mov a,p2
orl a,#0f0h
cpl a
jz retkeyscan
jmp keep
retkeyscan:
mov a,b
mov p2,#0fh
ret
nokey:
mov a,#80h ;没有按键输入,输入80h 作为标志
ret
;===============扫描按键输入
scan:
mov p2,#7fh ;first line
L11: jb p2.0,L12
call clrdis ;条件清空显示
mov a,#0Eh ;reset key
JMP RETKEY
L12: JB P2.1,L13
call clrdis ;条件清空显示
mov a,#0Ch ;clear key
jmp retkey
L13: JB P2.2,L14
call clrdis ;条件清空显示
mov a,#0Ah ;N/A
jmp retkey
L14: JB P2.3,L21
call clrdis ;条件清空显示
mov a,#0Bh ;N/A
jmp retkey
L21: mov p2,#0BFh ;SECOND line
jb p2.0,L22
call clrdis ;条件清空显示
mov a,#08h ;8key
JMP RETKEY
L22: JB P2.1,L23
call clrdis ;条件清空显示
mov a,#09h
jmp retkey
L23: JB P2.2,L24
setb EXMP ;发送标志置位
mov a,#0Fh ;on key
jmp retkey
L24: JB P2.3,L31
setb EXMP ;发送标志置位
mov a,#0Bh ;off key
jmp retkey
L31: mov p2,#0DFh ;THIRD line
jb p2.0,L32
call clrdis ;条件清空显示
mov a,#04h ;4 key
JMP RETKEY
L32: JB P2.1,L33
call clrdis ;条件清空显示
mov a,#05h ;5 key
jmp retkey
L33: JB P2.2,L34
call clrdis ;条件清空显示
mov a,#06h ;6 key
jmp retkey
L34: JB P2.3,L41
call clrdis ;条件清空显示
mov a,#07h ;7 key
jmp retkey
L41: mov p2,#0efh ;FORTH line
jb p2.0,L42
call clrdis ;条件清空显示
mov a,#00h
JMP RETKEY
L42: JB P2.1,L43
call clrdis ;条件清空显示
mov a,#01h ;1 key
jmp retkey
L43: JB P2.2,L44
call clrdis ;条件清空显示
mov a,#02h ;2 key
jmp retkey
L44: JB P2.3,L21
call clrdis ;条件清空显示
mov a,#03h ;3 key
jmp retkey
retkey: ret
;===============延时子程序
;delay subprogramms below
delay1500ms:
mov r7,#14
dy000:
mov r6,#100
dy111:
mov r2,#200
djnz r2,$
djnz r6,dy111
djnz r7,dy000
ret
delay500ms:
mov r7,#50
dy500:
mov r6,#200
djnz r6,$
djnz r7,dy500
ret
delay30ms:
mov r7,#150
dy0:
mov r6,#100
djnz r6,$
djnz r7,dy0
ret
delay5ms:
mov r7,#25
dy02:
mov r6,#100
djnz r6,$
djnz r7,dy02
ret
;=============================
;=============================
;=============================
;=============================
;以下的子程序是最重要的子程序之一,功能为将存储在Addr中的8bit地址数据和存储在
;data4中的4bit芯片PT2272数据输出引脚状态数据转化为codedata开始的缓冲区数据
;timer0中断程序根据这些数据输出宽或者窄脉冲进行控制
;=============================
;=============================
;=============================
;=============================
senddata:
jb tr0,$
mov r0,#codedata
mov @r0,#10000000b ;timer0根据缓冲区的bit位决定此周期是低电平还是高电平,此语句#10000000b是同步码
inc r0 ;此下的程序根据地址码的0或1写入缓冲区“0”的编码“88h”或“1”的编码“eeh”
mov @r0,#0
inc r0
mov @r0,#0
inc r0
mov @r0,#0
inc r0
mov counterconvert,#0
clr c
convertADD:
mov a,ADDR
clr c
rlc a
mov ADDR,a
jc code1
mov @r0,#088h
jmp code0
code1: mov @r0,#0eeh
code0: inc r0
inc counterconvert
mov a,counterconvert
cjne a,#8,convertADD
mov counterconvert,#0
convertDATA:
mov a,data4
clr c
rlc a
mov data4,a
jc code11
mov @r0,#088h
jmp code00
code11: mov @r0,#0eeh
code00: inc r0
inc counterconvert
mov a,counterconvert
cjne a,#4,convertDATA
;====================以上是地址和数据向串行数据格式的转换,timer0中断发送此串行数据
;convert the ADD and DATA to serial data format
mov r0,#codedata
mov buffer,@r0
clr dataout
mov TH0,#timerH
mov TL0,#timerL
mov counterbit,#0
mov counterT,#0
mov Tcounter,#0
setb TR0 ;启动timer0
ret
;=======================timer0的中断程序
timerint:
push acc
push psw
mov th0,#timerH
mov tl0,#timerL ;保护现场
mov a,buffer
clr c
RLC a
jc setout1
clr dataout
jmp setout0
setout1:setb dataout
setout0:mov buffer,a
inc counterBIT
mov a,counterBIT
cjne a,#8,nextBIT ;判断一个字节是否结束
inc counterT
mov counterBIT,#0
inc R0
mov a,@R0
mov buffer,a
nextBIT: ;一个字节未结束,判断81bit是否结束(一个完整的PT2262的编码转换成此串行数据的长度)
mov a,counterT
cjne a,#16,quitINT
mov counterBIT,#0
mov counterT,#0
inc Tcounter
mov a,Tcounter
cjne a,cbit,sendagain ;是否发送8次?
mov counterBIT,#0
mov counterT,#0
mov Tcounter,#0
clr TR0 ;停止timer0
;mov delayflag,#0fh ;set delay flag
jmp quitint
sendagain:
mov r0,#codedata
mov buffer,@r0
quitINT:
pop psw
pop acc
reti
;=======================timer0中断退出
;24C02中带有片内地址寄存器。每写入或读出一个数据字节后,该地址寄存器自动加1,以实现对下一个存储单元的读写。所有字节均以单一操作方式读取。为降低总的写入时间,一次操作可写入多达8个字节的数据。
SCL BIT P3.7 ;定义24C02的串行时钟线
SDA BIT P3.6 ;定义24C02的串行数据线
;读写子程序如下:
;写串行E2PROM子程序EEPW
;R3=10100000(命令1010+器件3位地址+读/写。 器件地址一个芯片,是000)
;(R4)=片内字节地址
;r5内存储要发送的数据
EEPW:
orl p3,#11000000b
clr SDA
mov a,#write ;送器件地址,固定为#write
acall subs
mov a,r4 ;送片内字节地址
acall subs
MOV A,r5
acall subs
CLR SDA ;SDA置0, 准备送停止信号
ACALL DELAY ;延时以满足传输速率要求
SETB SCL ;发停止信号
ACALL DELAY
SETB SDA
CAll delay
RET
SUBS: MOV R1,#08H ;发送单字节子程序
subsLOOP:
CLR SCL
RLC A
MOV SDA,C
NOP
nop
SETB SCL
ACALL DELAY
DJNZ R1,subsLOOP ;循环8次送8个bit
CLR SCL
ACALL DELAY
SETB SCL
mov r7,#25
eepwdelay:
mov r6,#100
REP: MOV C,SDA
dec r6
JNC RETEEPW ;判应答到否,未到则等待
cjne r6,#0,rep
djnz r7,eepwdelay
;mov key1,#0fH
;mov key2,#0fH
;mov key3,#0fH
;mov key4,#0fH
RETEEPW:
CLR SCL
RET
;DELAY: ;延时子程序,占用寄存器R7,R6
DELAY: ;延时子程序,占用寄存器R7,R6
nop
nop
nop
nop
RET
;读串行E2PROM子程序EEPR
;R3=10100001(命令1010+器件3位地址+读/写。 器件地址一个芯片,是000)
;(R4)=片内字节地址
;r5 is the data to read
EEPR: orl p3,#11000000b
CLR SDA ;发开始信号
MOV A,#write
ACALL SUBS ;调发送单字节子程序
MOV A,R4 ;送片内字节地址
ACALL SUBS
orl p3,#11000000b
CLR SDA ;发开始信号
MOV A,#read ;发送读命令
ACALL SUBS
ACALL SUBR ;read data from 24C01
mov r5,a
CLR SDA
ACALL DELAY
SETB SCL
ACALL DELAY
SETB SDA ;送停止信号
call delay
RET
SUBR: MOV R1,#08H ;接受单字节子程序
LOOP2: SETB SCL
ACALL DELAY
MOV C,SDA
RLC A
CLR SCL
ACALL DELAY
DJNZ R1,LOOP2
SETB SDA ;若是最后一个字节置A=1
ACALL DELAY
SETB SCL
ACALL DELAY
CLR SCL
ACALL DELAY
SETB SDA ;应答毕,SDA置1
RET
;程序中多处调用了DELAY子程序(仅两条NOP指令),这是为了满足I2C总线上数据传送速
;率的要求,只有当SDA数据线上的数据稳定下来之后才能进行读写(即SCL线发出正脉冲)。
;另外,在读最后一数据字节时,置应答信号为“1”,表示读操作即将完成。
end
https://static.assets-stash.eet-china.com/album/old-resources/2008/12/8/19d7fd26-7667-4281-9afb-752aab48938f.rar
文章评论(0条评论)
登录后参与讨论