📄 experiment_3.c
字号:
/**************************************************************************
实验三 读 ds18b20 64位 ROM码
**************************************************************************/
#include <string.h>
#include "..\inc\option.h"
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\timer.h"
/*Timer5 初始化
入口参数:Timing_count=定时时间常数,定时时间=定时时间常数*0.02ms
T5_int_Enable=1,T5 中断方式,T5_int_Enable=0,T5 查询方式*/
void Timer_Init(U16 timing_count,U8 T5_int_Enable)
{
rINTMSK=BIT_GLOBAL|BIT_TIMER5;
rTCFG0=0X0c70101;//prescaler=199 rTCFG0=0X010101;prescaler=1
rTCFG1=0X0100000; // DIV=4
rTCNTB5=timing_count;
//rTCMPB5=(timing_count/2); havn't rTCMPB5!!! but T0--T4 have.
rTCON=0X2000000;
rTCON=0X1000000;
if(T5_int_Enable)
{
rINTCON=0X05;
rINTMOD=0X0;
rINTMSK=~(BIT_GLOBAL|BIT_TIMER5);
}
}
/*匹配ROM(命令 55H),发8字节ROM代码
入口参数:*ROM_addr 为DS18B20-ID首地址 */
void Match_Rom(U8 *ROM_addr)
{
U8 count;
U8 *p;
// U8 temp=0x55; //匹配ROM 命令 55H
Write_Byte(0x55);
p=ROM_addr; //发8字节ROM代码
count=8;
while(count)
{
Write_Byte(*p);
p++;
count--;
}
}
/*读ROM(命令 33H),读回8字节ROM代码
入口参数:Read_Addr=ROM代码首地址
出口参数:Read_Addr 地址开始的8个单元= 读回8字节ROM代码 */
void Read_Rom(U8 *Read_Addr)
{
U8 count;
U8 *p;
U8 temp=0x33; //读ROM 命令 33H
Write_Byte(temp);
p=Read_Addr; //从18b20 读回8字节ROM代码
count=8;
while(count)
{
*p=Read_Byte();
p++;
count--;
}
}
/*复位ds18b20
入口参数:无
返回参数:=1:总线上有18B20应答; =0:总线上无应答;*/
U8 Reset_18B20(void)
{
U8 temp;
rPCONG |= 0X0100; //PCONG[15:0]16位, G口配置寄存器.
rPCONG &= 0x0fdff; //PCONG[9:8]=01, 定义PG4 output。
rPUPG &=0xef; //PUPG[7:0]8位, PUPG[4]=0,pull up enabled
rPDATG |=0x0100; //置"1"总线,3.8us.
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
rPDATG &=0x0ef; //主机发复位脉冲"0",500 us.
temp=150; //500us
while(temp)
{
asm("nop");
temp--;
}
rPDATG |=0x10; //主机发"1",17 us.(ds18b20等候15--60us,实测25us)
temp=4;
while(temp)
{
asm("nop");
temp--;
}
rPCONG &=0xfcff; //PG4[9:8]=00,input
Timer_Init(12,0); //12*0.02ms=240 us
while(1)
{
temp=rPDATG;
temp &=0x10;
if(temp==0x0) //有应答?
{
rTCON=0x0; //停止T5计时
while(temp==0x0)
{
temp=rPDATG;//等应答结束
temp &=0x10;
}
temp=80; //250us
while(temp)
{
asm("nop");
temp--;
}
return 1; //有应答,返回1.
}
else
{
if(~(rTCNTO5))
return 0; //无应答,返回0.
}
}
}
/*主机读 1 Byte
入口参数: 无
返回参数: 读入的 1 Byte数据, 低位在先!! */
U8 Read_Byte()
{
U8 count;
U8 temp_Byte=0;
U8 temp;
count=8; //读入1 Byte数据(=8bit)
while(count)
{
temp=Read_Bit(); //读入 1 Bit
temp_Byte=(temp_Byte>>1)|(temp&0x80);
count--;
}
return temp_Byte;
}
/*主机读 1 Bit
入口参数: 无
返回参数: 读入的 1 Bit数据(U8 temp的 Bit[0] ) */
U8 Read_Bit()
{
U8 temp;
U8 read_bit;
rPDATG &=0x0ef; //主机发"0",2.2us
asm("nop");
asm("nop");
rPDATG |=0x010; //主机发"1",3.8us.
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
rPCONG &=0xfcff; //PG4[9:8]=00,input.
asm("nop");
while(1)
{
read_bit=(rPDATG<<3)&0x80; //读总线 PG4
asm("nop");
if(read_bit==((rPDATG>>4)&0X01));//再读总线 PG4
break; //两次读相等?
}
temp=8; //30us
while(temp)
{
asm("nop");
temp--;
}
rPCONG |=0x0100; //PG4[9:8]=01,output
asm("nop");
rPDATG |=0x10; //发"1",2us.
asm("nop");
asm("nop");
return read_bit;
}
/*主机写 1 Byte
入口参数:欲写的 1 Byte数据
返回参数:无 */
void Write_Byte(U8 write_Byte)
{
U8 count;
U8 temp_bit;
count=0x08;
while(count)
{
temp_bit=write_Byte&0x01;
Write_Bit(temp_bit);
write_Byte=write_Byte>>1;
count--;
}
}
/*主机写 1 Bit
入口参数:欲写的 1 Bit数据(U8 temp的 Bit[0] )
返回参数:无 */
void Write_Bit(U8 write_Bit)
{
U8 temp;
rPCONG |=0x100; //PG4[9:8]=01,output
asm("nop");
rPDATG &=0x0ef; //发"0",3us.
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
asm("nop");
if((write_Bit &0x01)==0x01)
rPDATG |=0x10;
else
rPDATG &=0x0ef;
temp=8; //30us
while(temp)
{
asm("nop");
temp--;
}
rPDATG |=0x10; //发"1",2us.
asm("nop");
asm("nop");
}
void Main(void)
{
U8 Rom_buf1[8];
U8 Rom_buf2[8];
U8 temp;
while(1)
{
// 读 ds18b20 的8字节ROM码
temp=Reset_18B20(); //复位
if(temp==1)
Read_Rom(Rom_buf1); //发(33h)命令,读回64位ROM码。
temp=Reset_18B20(); //再读
if(temp==1)
Read_Rom(Rom_buf2);
asm("nop");
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -