📄 main.asm
字号:
LDI R0 ,04H ;发送D7~D4共4位SEND_D7_D4: ANDIM PA_TMP ,0011B ;开始发数据,同时发送D7,因D7~D4为0,故此位为0 STA PA CALL DELAY_1MS ;调用延时1MS的子程式 ORIM PA_TMP ,0100B ;将CLK置为高 STA PA CALL DELAY_1MS ;将时钟置为高后再延时1MS SBIM R0 ,01H BNZ SEND_D7_D4 LDI R0 ,04H ;发送D3~D0共4位SEND_D3_D0: ANDIM PA_TMP ,1011B LDA SEND_COM ;发送的命令字 BA3 $+3 ANDIM PA_TMP ,0111B ;发送的是0 JMP $+2 ORIM PA_TMP ,1000B ;发送的位为1 LDA PA_TMP ,00H STA PA ;发送数字每次发送总是在下降沿发送 CALL DELAY_1MS ;调用延时1MS的子程式 ORIM PA_TMP ,0100B ;将CLK置为高 STA PA CALL DELAY_1MS ;调用延时1MS的子程式 LDA SEND_COM,00H ADDM SEND_COM,00H ;将发送的命令位左移一位 BNC $+2 ORIM SEND_COM,0001B ;循环移动,这样发送完命令后,命令字不会改变 SBIM R0 ,01H BNZ SEND_D3_D0 ;如果4位已发出,则说明命令已发送完毕 ANDIM PA_TMP ,0111B STA PA ;将DATA置为低SEND_CHECK: ;检查发送的是不是读的命令,如果发送的是读的命令,就要从读的端口 ;读出状态,然后再显示出来(从PF1口读出) SBI SEND_COM,09H ;检查刚才是否发送的是读状态的命令字 BNZ SEND_COM_EXIT CALL DELAY_1MS ;再延时1MS CALL DELAY_1MS ;共延时2MS,然后读状态 LDI RD_CNT_L,00H LDI RD_CNT_H,00H ;还没有开始计时,所以将读入个数清零 CALL DELAY_1MS ;再延时1MSSEND_READ_ING: ;在读取数的过程中 ANDIM PA_TMP ,1011B ;由高变为低的时候读状态 STA PA LDA RD_STATUS1,00H ADDM RD_STATUS1,00H LDA RD_STATUS2,00H ADCM RD_STATUS2,00H LDA RD_STATUS3,00H ADCM RD_STATUS3,00H LDA RD_STATUS4,00H ADCM RD_STATUS4,00H LDA RD_STATUS5,00H ADCM RD_STATUS5,00H LDA RD_STATUS6,00H ADCM RD_STATUS6,00H LDA RD_STATUS7,00H ADCM RD_STATUS7,00H LDA RD_STATUS8,00H ADCM RD_STATUS8,00H LDA RD_STATUS9,00H ADCM RD_STATUS9,00H LDA RD_STATUS10,00H ADCM RD_STATUS10,00H LDA RD_STATUS11,00H ADCM RD_STATUS11,00H LDA RD_STATUS12,00H ADCM RD_STATUS12,00H LDA RD_STATUS13,00H ADCM RD_STATUS13,00H LDA RD_STATUS14,00H ADCM RD_STATUS14,00HSEND_READ_STATUS: NOP NOP LDA PD ;每次是下降沿读状态 BA2 $+3 LDI R0 ,00H ;第一次读的是0的寄存器 JMP $+2 LDI R0 ,01H ;第一次读的值是1 NOP NOP LDA PD BA2 $+3 LDI R1 ,00H ;第二次读的值是0 JMP $+2 LDI R1 ,01H ;第二次读的值是1 LDA R0 ,00H SUB R1 ,00H BNZ SEND_READ_STATUS;如果两次读的值不一样,再读一次,这样就可以了 SBI R0 ,01H BAZ $+3 ANDIM RD_STATUS1,1110B;读到的值是0 JMP $+2 ORIM RD_STATUS1,0001B;读到的值是1 CALL DELAY_1MS ;读完数据后再延时1MS ORIM PA_TMP ,0100B ;将SCL置为1 STA PA CALL DELAY_1MS ;变为高后再延时1MS ADIM RD_CNT_L,01H LDI R0 ,00H ADCM RD_CNT_H,00H SBI RD_CNT_L,08H ;一共是读56(10进制)=38(16进制)个 LDI R0 ,03H SBC RD_CNT_H,00H BNC SEND_READ_ING ;如果还没有读到56个数则继续读SEND_COM_EXIT: NOP NOP NOP RTNI;----------------------------------------------------------------- DELAY_1MS: ;延时1MS的子程式 LDI R1 ,00H LDI R2 ,04HDELAY_1MS_ING: ;如果没有把这个数减为0,则不停延时 LDI WDT ,08H SBIM R1 ,01H LDI R3 ,00H SBCM R2 ,00H BC DELAY_1MS_INGDELAY_1MS_EXIT: RTNI;=================================================================DELAY_5MS: ;延时5MS的子程式 LDI R1 ,0ah;01H LDI R2 ,0ch;04H LDI R3 ,02h;03HDELAY_5MS_ING: ;如果没有把这个数减为0,则不停延时 LDI WDT ,08H SBIM R1 ,01H LDI R0 ,00H SBCM R2 ,00H LDI R0 ,00H SBCM R3 ,00H BC DELAY_5MS_ING RTNI;=================================================================DELAY_20MS: ;延时5MS的子程式 LDI R1 ,09h;01H LDI R2 ,02h;04H LDI R3 ,0bh;03HDELAY_20MS_ING: ;如果没有把这个数减为0,则不停延时 LDI WDT ,08H SBIM R1 ,01H LDI R0 ,00H SBCM R2 ,00H LDI R0 ,00H SBCM R3 ,00H BC DELAY_20MS_ING RTNI;=================================================================DELAY_5S: ;延时5MS的子程式 LDI R4 ,07H LDI R3 ,0AH LDI R2 ,01H LDI R1 ,02H LDI R0 ,00HDELAY_5S_ING: ;如果没有把这个数减为0,则不停延时 LDI WDT ,08H SBIM R0 ,01H EOR R0 ,00H SBCM R1 ,00H EOR R1 ,00H SBCM R2 ,00H EOR R2 ,00H SBCM R3 ,00H EOR R3 ,00H SBCM R4 ,00H BC DELAY_5S_ING RTNI;=================================================================;=================================================================READ_DATA: ORIM PACNT ,0011B ;每写入1次就读1次,读完之后改变显示数据 CALL start_i2c call delay_2us ldi ROM_DATA,1010b call write_byte ldi ROM_DATA,0000b ;device address call write_byte call ack_sub LDA I2C_ERRO_CNT,00H BNZ READ_DATA_EXIT lda DATA_ADDRH,00h sta ROM_DATA,00h call write_byte lda DATA_ADDRL,00h sta ROM_DATA,00h ;read address call write_byte call ack_sub LDA I2C_ERRO_CNT,00H BNZ READ_DATA_EXIT ////---------------------read_data2: call scl_low ;将SCL置为低 call delay_2us call start_i2c call delay_2us ////--------------------- ldi ROM_DATA,1010b call write_byte ldi ROM_DATA,0001b ;read commande call write_byte call ack_sub LDA I2C_ERRO_CNT,00H BNZ READ_DATA_EXIT ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LDI PACNT ,1101B ;sda input ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ldi READ_DATAL,00h ldi READ_DATAH,00h LDI READ_CNT ,08H ;读入的数据read_loop: call scl_low call delay_2us call scl_high lda READ_DATAH,00h addm READ_DATAH,00h lda READ_DATAL,00h addm READ_DATAL,00h bnc d1_bit0_0 orim READ_DATAH,01hd1_bit0_0: nop nop LDA PA ,00h ;原程序PA.2为SDA,现在程序PA.1为SDA BA1 is_bit_1 ;原程序PA.3为SCL,;现在程序PA.0为SCL jmp cnt_subis_bit_1: orim READ_DATAL,01hcnt_sub: sbim READ_CNT,01h bnz read_loop ////%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ldi PACNT,1111B ANDIM PA_TMP ,1110B ORIM PA_TMP ,0010B STA PA call delay_2us ORIM PA_TMP ,0001B STA PA call delay_2us call stop_i2c call delay_2usREAD_DATA_EXIT: rtni////=====================================================WRITE_DATA:write_data_on: call start_i2c call delay_2us ldi ROM_DATA,1010b call write_byte ldi ROM_DATA,0000b ;device address call write_byte call ack_sub LDA I2C_ERRO_CNT,00H BNZ WRITE_DATA_EXIT lda DATA_ADDRH,00h sta ROM_DATA,00h call write_byte lda DATA_ADDRL,00h sta ROM_DATA,00h ;write address call write_byte call ack_sub LDA I2C_ERRO_CNT,00H BNZ WRITE_DATA_EXIT; ldi DATA_H,02H lda DATA_H,00H sta ROM_DATA,00h call write_byte LDA DATA_L,00H sta ROM_DATA,00h ;write data call write_byte call ack_sub; LDA I2C_ERRO_CNT,00H; BNZ WRITE_DATA_EXIT call stop_i2cWRITE_DATA_EXIT: nop rtni////=====================================================write_byte: LDI R0 ,04H ;因为传送的数字为4位write_in: call scl_low ;将SCL信号置为低 LDA ROM_DATA,00H ;将要传送的数的最高位送给SDA BA3 $+3 ANDIM PA_TMP ,1101B ;;原程序PA.2为SDA,现在程序PA.1为SDA JMP $+2 ORIM PA_TMP ,0010B ;传送的最高位为1 STA PA CALL delay_2us call scl_high ;将SCL信号置为高 call delay_2us SBIM R0 ,01H ;将传送数字的个数减1,如果没有传送完再传送 BAZ write_exit ;传数结束 LDA ROM_DATA,00H ADDM ROM_DATA,00H ;将DATA1左移一位 JMP write_inwrite_exit: RTNI////=====================================================ack_sub: call scl_low ;将SCL信号置为低 call delay_2us ORIM PA_TMP ,0010B STA PA LDI PACNT ,1101B ;将SDA置为输入脚 call delay_2us call scl_high ;将SCL信号置为高 LDI R0 ,00H nop nop nopack_wait: nop nop ADIM R0 ,01H BC ack_wrong LDA PA ,00H BA1 ack_waitack_right: ;ack的信号是正常的 LDI I2C_ERRO_CNT ,00H;24C02读错的次数清零 JMP ack_exit ;ack检查完毕ack_wrong: ;ACK信号在长时间内没有收到,则不记忆 ADIM I2C_ERRO_CNT ,01H;24C02设定读错一次的次数ack_exit: LDI PACNT ,1111B call delay_2us rtni////=====================================================scl_low: ANDIM PA_TMP ,1110B ;scl low STA PA RTNI////=====================================================scl_high: orim PA_TMP ,0001B STA PA RTNI////=====================================================start_i2c: LDI PA_TMP ,1111B STA PA call delay_2us ANDIM PA_TMP ,1101B ;sda low,start I2C STA PA RTNI////=====================================================stop_i2c: call scl_low call delay_2us andim PA_TMP ,1100B ;sda low STA PA nop nop call scl_high call delay_2us ORIM PA_TMP ,0010B ;sda high when scl high,stop STA PA call delay_2us rtni////=====================================================delay_2us: nop nop nop nop rtni/////====================================================////===================================================== ;-----------------------------------------------------------------;=================================================================;=================================================================;================================================================= include "sh69p20c.h" include "vartable.inc";================================================================= END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -