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

📄 main.asm

📁 IIC汇编子程序 在伟福仿真器调试通过 在主程序中 直接复制即可使用!
💻 ASM
📖 第 1 页 / 共 2 页
字号:
			NOP
			NOP
			RET


;*******************************************************************
;                    向有子地址器件读取多字节数据函数
;函数原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
;功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
;          地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
;           如果返回1表示操作成功,否则操作有误。
;注意:    使用前必须已结束总线。
;********************************************************************/
READ_RAM:	        LCALL START_I2C

		 	MOV A,SLA
			LCALL SENDBYTE	   ;发送SLA,0XA0H
			JNB ACK,RET_SLA0    ;

			MOV A,HIGH1
			LCALL SENDBYTE      ;发送HIGH,0000H
			JNB ACK,RET_HIGH0

			MOV A,ADDR
			LCALL SENDBYTE      ;发送SUBA,0XA1,0XA2,0XA3,0XA4
			JNB ACK,RET_SUBA0

			LCALL START_I2C
			MOV SLA,A
			INC A
			LCALL SENDBYTE       ;发送数据
			JNB ACK,RET_PRM0

			SETB ACK_A
			LCALL ACK_I2C

			LCALL STOP_I2C


RET_SLA0:   MOV ADDR,#00H		   ;这里返回的值是主程序定义的开始标志位
			RET
RET_HIGH0:  MOV ADDR,#00H			;停止标志位
			RET
RET_SUBA0:  MOV ADDR,#00H			;0XA1,0XA2,0XA3,0XA4
			RET
RET_PRM0:   MOV ADDR,#00H			;返回参数0
			RET

;*****************************************/

SENDBYTE:   CLR SCL			  ;写一个字节
			MOV R7,#8

SEND1:		MOV C,ACC.7	  ;;;;此处用的寄存器A循环未清值
			MOV SDA,C
			NOP
			NOP
			NOP
			SETB SCL
			NOP
			NOP
			NOP
			NOP
			NOP
			CLR SCL
			RL A
			DJNZ R7,SEND1

			SETB SDA
			NOP
			NOP
			SETB SCL
			NOP
			NOP
			NOP
			JB SDA,ANS1
			SETB ACK
			AJMP ANS2
ANS1:		CLR ACK
ANS2:		CLR SCL
			NOP
			NOP
			RET

;*********************************************/

RCVBYTE:	MOV A,#00H	   ;读取一个字节

			SETB SDA
			NOP
			NOP
			MOV R7,#8
RBYTE3:		CLR SCL
			NOP
			NOP
			NOP
			NOP
			NOP
			SETB SCL
			NOP
			NOP
			RL A
			JB SDA,RBYTE1
			AJMP RBYTE2
RBYTE1:     INC A

RBYTE2:		CLR SCL
			NOP
			NOP
			DJNZ R7,RBYTE3
			CLR SCL
			NOP
			NOP
			MOV RETC,A		   ;RETC就是C程序中的d,I2C中的
			RET
;*************************************/
ACK_I2C:    JNB ACK_A,SEND_ANS1
			SETB SDA
			AJMP SEND_ANS2
SEND_ANS1:	CLR SDA
SEND_ANS2:  NOP
            NOP
			NOP
			SETB SCL
			NOP		       ; 时钟低电平周期大于4μs
			NOP
			NOP
			NOP
			NOP
			CLR SCL
			NOP
			NOP
			RET
;****************************************/
ISENDSTR:	LCALL START_I2C

			MOV A,SLA
			LCALL SENDBYTE	   ;发送器件地址SLA,0XA0H
			JNB ACK,RETB0_SLA0    ;

			MOV A,HIGH1
			LCALL SENDBYTE      ;发送器件子地址HIGH,0000H
			JNB ACK,RETB0_HIGH0

			MOV A,ADDR
			LCALL SENDBYTE      ;发送器件子地址SUBA,0XA1,0XA2,0XA3,0XA4
			JNB ACK,RETB0_SUBA0


			MOV A,S				;S位18B20发送来的温度

			LCALL SENDBYTE       ;发送数据
			JNB ACK,RETB0_PRM0

			RET

RETB0_SLA0: MOV B0,#00H		   ;这里返回的值是主程序定义的标志位,b0未定义
			RET
RETB0_HIGH0:MOV B0,#00H
			RET
RETB0_SUBA0:MOV B0,#00H
			RET
RETB0_PRM0: MOV B0,#00H
			RET


;*******************************************************************************
;                                                                              *
;                        18B20子程序                                           *
;                                                                              *
;*******************************************************************************

;以下是DS18B20的程序:
;|--------------------------------------------------------------|
;| 获取单个ds1820转化的温度值的应用程序,P1.7接ds1820 |
;|--------------------------------------------------------------|

TEMP_GET:
		LCALL INT
		LCALL WAITMCU
		LCALL GET_TEMP
		LCALL CONVERT
		LCALL READ

;***18B20初始化****************************************************
INT:       CLR PSW.4
           SETB PSW.3          ;设置工作寄存器当前所在的区域RS0
           CLR EA 			   	;使用ds1820一定要禁止任何中断产生
L0:        CLR P1.7            ;ds1820总线为低复位电平
           MOV R2,#200
L1:        CLR P1.7
           DJNZ R2,L1          ;总线复位电平保持600us
           SETB P1.7           ;释放ds1820总线
           MOV R2,#5
L4:        DJNZ R2,L4          ;释放ds1820总线保持10us
			RET
;*********************等待单片机信号
WAITMCU:
           CLR C               ;清存在信号(存在C=0,不存在C=1)
           ORL C,P1.7
           JC INIT_18B20        ;存在吗?不存在则重新来
           MOV R6,#20 			 ;原来是80
L5:        ORL C,P1.7 			;等待单片机给应答信号 低电平有效
           JC INIT_18B20
           DJNZ R6,L5
		   RET

INIT_18B20: CLR P1.7            ;ds1820总线为低复位电平
           MOV R2,#200
L2:        CLR P1.7
           DJNZ R2,L2          ;总线复位电平保持600us
           SETB P1.7           ;释放ds1820总线
           MOV R2,#5
L3:        DJNZ R2,L3          ;释放ds1820总线保持10us
	       AJMP WAITMCU



;***************写入18B20命令************


GET_TEMP:
		   LCALL DELAY1MS
           MOV A,#0CCH 		   ;送入跳过ROM命令
           LCALL WRITE
		   MOV A,#4EH		   ;写温度寄存器
		   LCALL WRITE
		   MOV A,#63H		   ;设定温度上限99
		   LCALL WRITE
		   MOV A,#01H		   ;设定温度下线0
		   LCALL WRITE
		   MOV A,#1FH		   ;设定温度精度9位
		   LCALL WRITE

		   LCALL INT           ;温度转换完全,再次初使化ds1820
		   LCALL DELAY1MS
		   LCALL WAITMCU

		   MOV A,#0CCH		   ;送入跳过ROM命令
		   LCALL WRITE
		   MOV A,#48H		   ;将寄存器中的温度报警值复制到EPROM中
		   LCALL WRITE
		   RET




;****写数据****************************************************
WRITE:                         ;向ds1820写操作命令子程序
           CLR EA
           MOV R3,#8           ;写入ds1820的bit数,一个字节8个bit
WR1:   	   RRC A
           CLR P1.7
		   JC WRITE1

WRITE0:	    CLR P1.7				 ;写入0
		    MOV R4,#70
WAIT2:     	DJNZ R4,WAIT2
			SETB P1.7
	     	MOV R4,#2
WAIT3:		DJNZ R4,WAIT3
			DJNZ R3,WR1
			RET


WRITE1:	    CLR P1.7			  ;写入1
			MOV R4,#2
WAIT:		DJNZ R4,WAIT
			SETB P1.7
			MOV R4,#70
WAIT1:		DJNZ R4,WAIT1
			DJNZ R3,WR1
			RET

;****读温度*****************************************************
READ:
		   CLR EA
		   LCALL INT
		   LCALL WAITMCU
		   LCALL DELAY1MS
		    MOV A,#0CCH 		   ;送入跳过ROM命令
           LCALL WRITE
		    MOV A,#0BEH 		   ;read scratchpad命令
           LCALL WRITE
          ;CLR EA
           MOV R6,#8           ;连续读8个bit
RE1:       CLR P1.7            ;读前总线保持为低
           MOV R4,#4
           NOP
           SETB P1.7           ;开始读,总线释放
RE2:       DJNZ R4,RE2         ;持续8us
           MOV C,P1.7         ;从ds1820总线读得一个bit
           RRC A               ;把读得的位值环移给 A
           MOV R5,#30
RE3:       DJNZ R5,RE3         ;持续60us
           DJNZ R6,RE1         ;读下一个bit
           SETB P1.7		   ;重新释放ds1820总线
		   MOV  R7,A
		   SETB EA
           RET

;*********************延时1MS
DELAY1MS: ;精确延时1ms子程序
		   MOV R6,#2
	YS1MSD:MOV R7,#248
		   DJNZ R7,$
		   DJNZ R6,DELAY1MS
		   RET
;********************转换温度
CONVERT:   LCALL INT
		   LCALL WAITMCU
		   LCALL DELAY1MS
		   MOV A,#0CCH 		   ;送入跳过ROM命令
           LCALL WRITE
		    MOV A,#44H 		   ;CONVERT命令
           LCALL WRITE
		   RET


END





⌨️ 快捷键说明

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