📄 i2c_wr.asm
字号:
;===========================================================
;名 称:模拟I2C总线通讯
;说 明:以普通I/O口模拟I2C通讯,本例以主控方式驱动24C02
;入口参数:WR_ADR、RD_ADR、WR_DATA
;出口参数:RD_DATA
;程序入口:BYTE_WRITE、BYTE_READ
;占用资源:5CH~50H,B、C、WA、HL、IX
;涉及模块:-
;===========================================================
;===========================================================
$include"TMP86P808.H";包含头文件
;-------------------------------
;中断及复位向量
;-------------------------------
CODE_INVEC SECTION CODE ABS=0XFFE0
INTVEC:
DW TO_RETI;/INT5 0XFFE0
DW TO_RETI;INTTXD1 0XFFE2
DW TO_RETI;INTRXD1 OXFFE4
DW TO_RETI;INT 0XFFE6
DW TO_RETI;INTTIC0 0XFFEa
DW TO_RETI;INTET0 0XFFEc
DW TO_RETI;INTTXD0 0XFFEe
DW TO_RETI;INTRXD0 0XFFF0
DW TO_RETI;INTT1 0XFFF2
DW INTTBT;INTTBT 0XFFF4
DW TO_RETI;INT1 0XFFF6
DW TO_RETI;/INTT0 0XFFF8
DW TO_RETN;INTWDT 0XFFFA
DW TO_RETN;INTATRAP 0XFFFC
DW TO_RETN;INTUNDEF 0XFFFE
DW START;RESET 0XFFEF
;------------------------------------
;=========================================内存分配
;---------------------------------------TBT
HOUR EQU 0X4E
MIN EQU 0X4F
SEC EQU 0X50
MS EQU 0X51
TEN_MS EQU 0X52
BP_FLAG EQU 0X6F;蜂鸣器标志
BP_TIM EQU 0X70;蜂鸣器鸣响时间
;----------------------------------------I2C
BIT_CNT EQU 0X5C;位计数器
WR_ADR EQU 0X5D;写入地址
RD_ADR EQU 0X5E;读出地址
WR_DATA EQU 0X5F;写入数据
RD_DATA EQU 0X60;读出数据
FLAG EQU 0X61;读写标志
;------------------------------------------------
;--------------------------------------------
SDA_IN EQU 0Y10000011;SDA输入状态时端口控制器数值
SDA_OUT EQU 0Y11000011;SDA输出状态时端口控制器数值
;=======================================LCD_DISP位定义
TBTEN EQU 3;TBT允许
;-----------------------------------------I2C位定义
SDA EQU 6;P36
SCL EQU 7;P37
;----------------------------------------
READ_FLAG EQU 0;读写操作标志,1表示读操作
;---------------------------------------------
BP_ON EQU 0;打开蜂鸣器标志,1有效
;=============================================主程序开始
MAIN_CODE SECTION CODE ABS=0XE000
START:
LD SP,0X13F;堆栈指针
LD (SYSCR2),0X80;单时钟模式
LD (WDTCR1),0X00
LD (WDTCR2),0XB1;禁用WDT
LD (P1),0X0
LD (P2),0X0
LD (P3),0X0
LD (P0OUTCR),SDA_OUT;
LD (P1CR),0XFF;P1全部输出
; LD (P2PRD),0X01;
LD (P3CR),SDA_OUT
;------------------------------------------内存清0
RAM_CLR:
LD HL,0X40
LD WA,0X13F-0X40
RCLR1:
LD (HL),0X0
INC HL
DEC WA
J F,RCLR1
;---------------------------------------------------主循环
LOOP:
LD (TBTCR),0X05;每次中断约1MS-4MHZ晶振
DI
SET (TBTCR).TBTEN;启动TBT
SET (EIRL).6;允许TBT中断
EI;打开中断
;------------------------------------------开始24CXX操作
SET (BP_FLAG).BP_ON
LD (WR_ADR),0X01;载入写数据地址
LD (WR_DATA),0X44;载入写数据
CALL BYTE_WRITE;写入24Cxx
CALL DELY10MS;延时10ms,24Cxx一次操作后必须延时10ms再进行下一次操作
CALL DELY10MS
;CALL DELY10MS
;CALL DELY10MS
LD (RD_ADR),0X01;读出数据地址
CALL BYTE_READ;读数据
LD A,(RD_DATA);将读出数据载入A
CALL DELY10MS;延时10ms
J $;循环等待中断
;===========================================================
;===========================================================
;NO_USEINT SECTION CODE MEDIUM;未使用中断向量处理
TO_RETI:
RETI
TO_RETN:
RETN
;===========================================================
;===========================================================
DELY10MS:
LD IX,50000
DE_IX:
DEC IX
J NZ,DE_IX
RET
;===========================================================
;==========================================TBT构成的实时时钟
INTTBT:
PUSH A
PUSH B
PUSH C
PUSH H
PUSH L;压栈
MSF:
INC (MS);每次中断约等于1ms
CMP (MS),0X0A
J CS,CLOCK_EXIT;是否大于等于10ms
;----------------------------------------------蜂鸣器
LD CF,(BP_FLAG).BP_ON
J CC,TEN_MSF;是否要打开蜂鸣器
SET (P1).2
INC (BP_TIM)
CMP (BP_TIM),30
J CS,TEN_MSF;蜂鸣器是否鸣想了30ms
CLR (BP_FLAG).BP_ON
LD (BP_TIM),0
CLR (P1).2
;---------------------------------------------------
TEN_MSF:
LD (MS),0X0
INC (TEN_MS)
CMP (TEN_MS),0X64
J CS,CLOCK_EXIT
SECF:
LD (TEN_MS),0X0
INC (SEC)
CMP (SEC),0X3C
J CS,CLOCK_EXIT
MINF:
LD (SEC),0X0
INC (MIN)
CMP (MIN),0X3C
J CS,CLOCK_EXIT
HOURF:
LD (MIN),0X0
INC (HOUR)
CMP (HOUR),0X3C
J CS,CLOCK_EXIT
LD (HOUR),0X0
CLOCK_EXIT:
POP L
POP H
POP C
POP B
POP A
RETI
;===========================================================
;===========================================================
;I2C_START:
; LD SP,0X130
; LD (SYSCR2),0X80
; LD (WDTCR1),0X00
; LD (WDTCR2),0XB1;禁用WDT
MAKE_S:
SET (P3).SDA
NOP
NOP
LD (P3CR),SDA_OUT
NOP
NOP
NOP
NOP
ACK_CHECK:
;SET (P3).SDA
;NOP
;NOP
LD (P3CR),SDA_IN;SDA输入状态
NOP
NOP
NOP
NOP
M_START:
SET (P3).SCL;时钟拉高
NOP
NOP
NOP
LD CF,(P3).SDA
J CC,MAKE_S;总线不空则强制拉高
M_START0:
NOP
NOP
SET (P3).SCL
NOP
NOP
NOP
NOP
CLR (P3).SDA;起始信号
NOP
NOP
LD (P3CR),SDA_OUT;SDA输出
LD B,0y10100001;读命令字
LD CF,(FLAG).READ_FLAG
J CS,W_BYTE;读标志是否=1
LD B,0y10100000;写命令字
W_BYTE:
LD (P3CR),SDA_OUT
LD (BIT_CNT),0X08
BIT_LOOP:
NOP
NOP
NOP
CLR (P3).SCL
ROLC B
J CC,BIT_0
SET (P3).SDA
J SEND_DATA
BIT_0:
CLR (P3).SDA
SEND_DATA:
NOP
NOP
NOP
NOP
SET (P3).SCL
DEC (BIT_CNT)
J NZ,BIT_LOOP
NOP
NOP
NOP
NOP
CLR (P3).SCL
NOP
NOP
SET (P3).SDA;输出锁存器置1
LD (P3CR),SDA_IN
NOP
NOP
NOP
SET (P3).SCL
NOP
NOP
NOP
LD CF,(P3).SDA
J CS,M_START0
CLR (P3).SCL
RET
W_STOP:
M_STOP:
CLR (P3).SDA
LD (P3CR),SDA_OUT
NOP
NOP
NOP
NOP
SET (P3).SCL
NOP
NOP
NOP
NOP
SET (P3).SDA
NOP
NOP
NOP
NOP
CLR (P3).SCL
RET
RD_BYTE:
RNXTB:
CLR (P3).SCL
NOP
NOP
NOP
LD (P3CR),SDA_IN
LD (BIT_CNT),0X08
RNX:
CLR (P3).SCL
NOP
NOP
NOP
CLR CF
TEST (P3).SDA
J F,BITIS_0
SET CF
BITIS_0:
ROLC B
SET (P3).SCL
NOP
NOP
NOP
DEC (BIT_CNT)
J NZ,RNX
LD (RD_DATA),B
CLR (P3).SCL
LD (P3CR),SDA_OUT
R_STOP:
J M_STOP
;===========================================================
BYTE_WRITE:
CALL ACK_CHECK
LD B,(WR_ADR)
CALL W_BYTE
LD B,(WR_DATA)
CALL W_BYTE
CALL W_STOP
RET
;===========================================================
BYTE_READ:
CALL ACK_CHECK
LD B,(RD_ADR)
CALL W_BYTE
CALL DELY10MS
;CALL DELY10MS
;CALL DELY10MS
SET (FLAG).READ_FLAG
CALL ACK_CHECK
CLR (FLAG).READ_FLAG
CALL RD_BYTE
RET
;===========================================================
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -