📄 ds18s20drv.asm
字号:
//==================================
//DS18S20驱动程序
//Design by ZM
//2007/1/8
//==================================
.include SPCE061A.inc
//定义IO口
//.define P_IOA_Dir 0x7002
//.define P_IOA_Attrib 0x7003
//.define P_IOA_Data 0x7000
//.define P_IOA_Buffer 0x7001
//.define P_IOB_Dir 0x7007
//.define P_IOB_Attrib 0x7008
//.define P_IOB_Data 0x7005
//.define P_IOB_Buffer 0x7006
//重复定义IO口便于根据实际的需要改变。只要改动很少的部分即可
.define Port_Dir P_IOB_Dir
.define Port_Attrib P_IOB_Attrib
.define Port_Data P_IOB_Data
.define Port_Buffer P_IOB_Buffer
//M_DQ定义具体连接DS18S20的DQ端口
.define M_DQ 0x8000 //IOB15连接DS18S20的DQ脚
//.define Bit 0x0f00 //IOB8-IOB11连接4个数码管的位选
//.define Segment 0x00ff //IOB0-IOB7为数码管的段选
.DATA
R_SystemClock:
.DW 0x001b //24.575Mhz Fosc/8 上电复位后的默认
.CODE
//==================================================
//汇编格式: _F_18S20_Delay
//C格式: void F_18S20_Delay(unsigned int timer);
//功能: 49Mhz下的精确延时
//入口: 需要延时的时间(以uS计),由r1带入
//出口: 无
//===================================================
.PUBLIC _F_18S20_Delay
_F_18S20_Delay:
cmp r1,1
jna ?Delay_Exit
?Delay_Loop:
nop //一个nop占用5个时钟周期
nop
nop
nop
nop
nop
nop
nop
nop
nop
r1-=1 //占用3个时钟周期
jnz ?Delay_Loop //占用3个时钟周期
?Delay_Exit:
retf
//======================================================
//汇编格式: _F_18S20_SetSystemCLK
//C格式: void F_18S20_SetSystemCLK(void)
//功能: 设置系统时钟为49Mhz实现精确延时
//入口参数: 无
//出口参数:无
//======================================================
.PUBLIC _F_18S20_SetSystemCLK
_F_18S20_SetSystemCLK:
r1=0x88
[P_SystemClock]=r1
retf
//=========================================================
//汇编格式: _F_18S20_RsuSystemCLK
//C格式: void F_18S20_RsuSystemCLK(void)
//功能: 恢复系统及CPU主频
//入口参数: 用前面定义的系统时钟R_SystemClock的值确定.
// 可以根据实际的需要改动
//出口参数: 无
//==========================================================
.PUBLIC _F_18S20_RsuSystemCLK
_F_18S20_RsuSystemCLK:
r1=[R_SystemClock]
[P_SystemClock]=r1
retf
//========================================================
//汇编格式: _F_18S20_Initial_IO
//C格式: void F_18S20_Initial_IO(void)
//功能: 端口初始化子程序
//入口参数: 无
//出口参数: 无
//=========================================================
.PUBLIC _F_18S20_Initial_IO
_F_18S20_Initial_IO:
r1=[Port_Dir]
r1=r1&(~M_DQ) //连接DQ的端口初始化为->输入
[Port_Dir]=r1
r1=[Port_Attrib]
r1=r1|M_DQ //DQ悬浮式输入
[Port_Attrib]=r1
r1=[Port_Buffer]
r1=r1|M_DQ
[Port_Buffer]=r1
retf
//=========================================================
//汇编格式: _F_18S20_Reset
//C格式: unsigned int F_18S20_Reset(void)
//功能: DS18S20的复位子程序
//入口参数: 无
//出口参数: 复位成功r1->1;失败r1->0
//==========================================================
.PUBLIC _F_18S20_Reset
_F_18S20_Reset:
r1=[Port_Dir]
r1=r1|M_DQ
[Port_Dir]=r1 //连接DQ的端口设置为->输出
r1=[Port_Buffer]
r1=r1&(~M_DQ)
[Port_Buffer]=r1 //输出低电平
r1=600
call _F_18S20_Delay //600uS延时
r1=[Port_Buffer]
r1=r1|M_DQ
[Port_Buffer]=r1 //延时后,DQ输出高电平
r1=[Port_Dir]
r1=r1&(~M_DQ)
[Port_Dir]=r1 //DQ端口设置为->输入
r1=30
call _F_18S20_Delay //30uS延时
r2=1000
?F_18S20_Reset_L: //检测有没有接收到低电平
r2-=1
jz ?F_18S20_Reset_Err //如果检测1000次仍没有检测到,认为复位失败
r1=[Port_Data]
r1=r1&M_DQ
jnz ?F_18S20_Reset_L
r2=1000
?F_18S20_Reset_L2: //采样到低电平后,再采样高电平,如果1000次没有检测到,认为复位失败
r2-=1
jz ?F_18S20_Reset_Err
r1=[Port_Data]
r1=r1&M_DQ
jz ?F_18S20_Reset_L2
r1=1 //成功,r1->1
jmp ?F_18S20_Reset_Exit
?F_18S20_Reset_Err: //失败,r1->0
r1=0
?F_18S20_Reset_Exit:
retf
//====================================================
//汇编格式: _F_18S20_Write_1
//C格式: void F_18S20_Write_1(void)
//功能: 向DS18S20写1子程序
//入口参数: 无
//出口参数: 无
//====================================================
.PUBLIC _F_18S20_Write_1
_F_18S20_Write_1:
r1=[Port_Dir] //DQ设置为输出口
r1=r1|M_DQ
[Port_Dir]=r1
r1=[Port_Buffer] //DQ输出低电平
r1=r1&(~M_DQ)
[Port_Buffer]=r1
r1=10 //启动写脉冲,要保持低电平大于1uS小于15uS
call _F_18S20_Delay
r1=[Port_Buffer] //高电平
r1=r1|M_DQ
[Port_Buffer]=r1
r1=50 //整个过程要大于60uS
call _F_18S20_Delay
r1=[Port_Dir] //恢复DQ属性为悬浮输入端口
r1=r1&(~M_DQ)
[Port_Dir]=r1
retf
//====================================================
//汇编格式: _F_18S20_Write_0
//C格式: void F_18S20_Write_0(void)
//功能: 向DS18S20写0子程序
//入口参数: 无
//出口参数: 无
//====================================================
.PUBLIC _F_18S20_Write_0
_F_18S20_Write_0:
r1=[Port_Dir] //DQ设置为输出口
r1=r1|M_DQ
[Port_Dir]=r1
r1=[Port_Buffer] //保持低电平
r1=r1&(~M_DQ)
[Port_Buffer]=r1
r1=40 //整个过程要大于60uS
call _F_18S20_Delay
r1=[Port_Buffer]
r1=r1|M_DQ
[Port_Buffer]=r1
r1=1
call _F_18S20_Delay
r1=[Port_Dir] //恢复DQ属性为悬浮输入端口
r1=r1&(~M_DQ)
[Port_Dir]=r1
retf
//====================================================
//汇编格式: _F_18S20_Read
//C格式: void F_18S20_Read(void)
//功能: 从DS18S20读数据子程序
//入口参数: 无
//出口参数: r1带回当前读的值0/1
//====================================================
.PUBLIC _F_18S20_Read
_F_18S20_Read:
r1=[Port_Dir] //DQ 输出
r1=r1|M_DQ
[Port_Dir]=r1
r1=[Port_Buffer] //DQ 低电平
r1=r1&(~M_DQ)
[Port_Buffer]=r1
r1=10
call _F_18S20_Delay
r1=[Port_Dir] //DQ 输入
r1=r1&(~M_DQ)
[Port_Dir]=r1
r1=3
call _F_18S20_Delay
r3=[Port_Data] //读入的数据
r3=r3&M_DQ //取DQ上的数据
jz ?F_18S20_Read_0
r3=0x80
?F_18S20_Read_0:
r1 = 30
call _F_18S20_Delay
r1=[Port_Buffer]
r1 = r1|M_DQ
[Port_Buffer] = r1
r1 = 1
call _F_18S20_Delay //Delay 1us
r1 = r3
retf
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -