ds18b20序列号的读取
时间:10-02
整理:3721RD
点击:
我在用lcd读取ds18b20的序列号 改变了lcd的管脚 我的序列号就读不出来了 求大神帮忙解答/****************************************Copyright (c)**************************************************
********************************************************************************************************/
#include "LPC21xx.H"
#define uint unsigned int //数据类型定义
#define uchar unsigned char
#define LCM_RS (1<<24)
#define LCM_RW (1<<25)
#define LCM_E (1<<26)
#define DQ (1<<31) //定义DS18B20通信端口
unsigned char zfflag=0; //温度正负标志
unsigned char err; //DS18B20检测标志
unsigned char Terr[]={"T-Err"};
unsigned char temp_value,temp_value2; //温度值
unsigned char save_number[8];
#define nop() {__asm("nop");}
/****************************************************************************
* 名称:ChkBusy()
* 功能:检查总线是否忙
****************************************************************************/
void ChkBusy()
{
int status;
IO1DIR=0x7000000; //0111 0000 0000 0X00等于输人
do
{
IO1CLR|=LCM_RS;
IO1SET|=LCM_RW;
IO1SET|=LCM_E;
nop();nop();nop();nop();
status = IO1PIN;
IO1CLR |= LCM_E;
} while (status & 0x800000);
IO1DIR=0x7ff0000; //0X00等于输出
}
/****************************************************************************
* 名称:WC_Lcd()
* 功能:写函数
****************************************************************************/
void WC_Lcd(unsigned char dat)
{
ChkBusy();
IO1CLR|=LCM_RS; //全部清零
IO1CLR|=LCM_RW;
IO1CLR=0xff0000; //先清零
IO1SET|=(dat<<16); //再送数
nop();nop();nop();nop();
IO1SET|=LCM_E;
IO1CLR|=LCM_E;
}
/****************************************************************************
* 名称:WD_Lcd()
* 功能:写数据函数
****************************************************************************/
void WD_Lcd(unsigned char dat)
{
ChkBusy();
IO1SET|=LCM_RS;
IO1CLR|=LCM_RW;
IO1CLR=0xff0000; //先清零
IO1SET|=(dat<<16); //再送数
nop();nop();nop();nop();
IO1SET|=LCM_E;
IO1CLR|=LCM_E;
}
/*****************************************************
函 数 名:LCD_Mychar()
功 能:自定义字符--CGRAM
说 明:LCD1602字符库中没有温度符号,自定义温度符号
******************************************************/
void LCD_Mychar(void)
{
//---------自定义字符代码--01H-------温度符号------------
WC_Lcd(0x48); //第1行
WD_Lcd(0x02); //
WC_Lcd(0x49); //第2行
WD_Lcd(0x05); //
WC_Lcd(0x4A); //第3行 1------**--
WD_Lcd(0x05); // 2----**--**
WC_Lcd(0x4B); //第4行 3----**--**
WD_Lcd(0x02); // 4------**--
WC_Lcd(0x4C); //第5行 5----------
WD_Lcd(0x00); // 6----------
WC_Lcd(0x4D); //第6行 7----------
WD_Lcd(0x00); // 8----------
WC_Lcd(0x4E); //第7行
WD_Lcd(0x00); //
WC_Lcd(0x4F); //第8行
WD_Lcd(0x00); //
}
/****************************************************************************
* 名称:lcd_init()
* 功能:lcd初始化函数
****************************************************************************/
void lcd_init(void)
{
WC_Lcd(0x38);
WC_Lcd(0x06);
WC_Lcd(0x0c);
LCD_Mychar(); // 写入自定义字符,代码01
}
/****************************************************************************
* 函数名称:DisText()
* 函数功能:显示文本
* 入口参数:addr 1602 DDRAM地址,*p 显示文本数据指针
****************************************************************************/
void DisText(unsigned char addr,unsigned char *p){
WC_Lcd(addr);
while(*p !='\0')WD_Lcd(*(p++));
}
/****************************************************************************
* 函数名称:Delay_DS18B20()
* 函数功能:软件延时
* 入口参数:time 延时参数,值越大,延时越久
****************************************************************************/
void Delay_DS18B20(unsigned char time){
unsigned char i,j;
for(i=0;i<8;i++){
for(j=1;j<time;j++);
}
}
/****************************************************************************
* 函数名称:Init_DS18B20()
* 函数功能:DS18B20初始化
* 出口参数:x=0则初始化成功 x=1则初始化失败
****************************************************************************/
unsigned char Init_DS18B20(void){
unsigned char x=1;
IO1DIR|=DQ; //设置引脚为输出
IO1SET|=DQ; //DQ复位
Delay_DS18B20(2); //稍做延时
IO1CLR|=DQ; //将DQ拉低
Delay_DS18B20(560); //精确延时 大于 480us
IO1SET|=DQ; //拉高总线
IO1DIR&=(~DQ); //转为输入
Delay_DS18B20(55); //延迟30~130
x=(IO1PIN&DQ)>>31; //150us延时后 如果x=0则初始化成功 x=1则初始化失败
Delay_DS18B20(480); //精确延时 110~480
return (x);
}
unsigned char ReadOneChar(void){
unsigned char i=0;
unsigned char dat = 0;
IO1DIR|=DQ; //设置引脚为输出
for (i=8;i>0;--i){
dat>>=1;
IO1DIR|=DQ; //设置引脚为输?
IO1SET|= DQ; //给脉冲信号
Delay_DS18B20(2);
IO1CLR|=DQ; //给脉冲信号
Delay_DS18B20(10); //延迟
IO1SET|= DQ; //给脉冲信号
Delay_DS18B20(10); //此时间不能太大,大了就会不稳定
IO1DIR&=(~DQ); //设置引脚为输入
if(IO1PIN & DQ)dat|=0x80;
Delay_DS18B20(60); //至少等待50us
}
IO1DIR |= DQ; //设置引脚为输出
IO1SET |= DQ; //给脉冲信号
return(dat);
}
/****************************************************************************
* 函数名称:WriteOneChar()
* 函数功能:DS18B20写一个字节
* 入口参数:dat 写入的数据
****************************************************************************/
void WriteOneChar(unsigned char dat){
unsigned char i=0;
IO1DIR|=DQ; //设置引脚为输出
for (i=8; i>0; --i){
if(dat&0x01){
IO1CLR |= DQ; // 给脉冲信号
Delay_DS18B20(10);
IO1SET|=DQ; // 给脉冲信号
Delay_DS18B20(60);
}
else{
IO1CLR |= DQ; // 给脉冲信号
Delay_DS18B20(60);
IO1SET|=DQ; // 给脉冲信号
Delay_DS18B20(10);
}
dat>>=1;
}
}
/****************************************************************************
* 函数名称:ReadTemp()
* 函数功能:读取DS18B20当前温度
* 出口参数:tvalue 读取的温度值
****************************************************************************/
unsigned char ReadTemp(void){
unsigned char a=0,b=0;
unsigned char tvalue=0; //温度值
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
tvalue = (b << 8);
tvalue = tvalue | a;
return(tvalue*(0.625)); //温度值扩大10倍,精确到1位小数
}
void dis_readnumber()
{
unsigned char i,temp;
Init_DS18B20();
WriteOneChar(0x33); //读rom 即rom中的编码
for(i=0;i<8;i++)
{
save_number[i]=ReadOneChar(); //保存序列号
}
WriteOneChar(0x80);
for(i=0;i<8;i++)
{
temp=save_number[i]>>4;
if(temp<10)
{
WD_Lcd(0x30+temp);
}
else
{
WD_Lcd(0x37+temp);
}
temp=save_number[i]&0x0f;
if(temp<10)
{
WD_Lcd(0x30+temp);
}
else
{
WD_Lcd(0x37+temp);
}
}
}
/****************************************************************************
* 名称:main()
* 功能:显示文本
****************************************************************************/
int main(void)
{
PINSEL2 &=0x00000000; //1111 1111 1100 0000 0000 0000 0000 0000
IO1DIR |= 0x7ff0000; //0000 0111 1111 1111
IO1SET |= 0xff0000; //1111 1111
PINSEL1 |=0x00000000;
lcd_init();
DisText(0x80,"");
while(1)
{
dis_readnumber(); //显示序列号
}
}
********************************************************************************************************/
#include "LPC21xx.H"
#define uint unsigned int //数据类型定义
#define uchar unsigned char
#define LCM_RS (1<<24)
#define LCM_RW (1<<25)
#define LCM_E (1<<26)
#define DQ (1<<31) //定义DS18B20通信端口
unsigned char zfflag=0; //温度正负标志
unsigned char err; //DS18B20检测标志
unsigned char Terr[]={"T-Err"};
unsigned char temp_value,temp_value2; //温度值
unsigned char save_number[8];
#define nop() {__asm("nop");}
/****************************************************************************
* 名称:ChkBusy()
* 功能:检查总线是否忙
****************************************************************************/
void ChkBusy()
{
int status;
IO1DIR=0x7000000; //0111 0000 0000 0X00等于输人
do
{
IO1CLR|=LCM_RS;
IO1SET|=LCM_RW;
IO1SET|=LCM_E;
nop();nop();nop();nop();
status = IO1PIN;
IO1CLR |= LCM_E;
} while (status & 0x800000);
IO1DIR=0x7ff0000; //0X00等于输出
}
/****************************************************************************
* 名称:WC_Lcd()
* 功能:写函数
****************************************************************************/
void WC_Lcd(unsigned char dat)
{
ChkBusy();
IO1CLR|=LCM_RS; //全部清零
IO1CLR|=LCM_RW;
IO1CLR=0xff0000; //先清零
IO1SET|=(dat<<16); //再送数
nop();nop();nop();nop();
IO1SET|=LCM_E;
IO1CLR|=LCM_E;
}
/****************************************************************************
* 名称:WD_Lcd()
* 功能:写数据函数
****************************************************************************/
void WD_Lcd(unsigned char dat)
{
ChkBusy();
IO1SET|=LCM_RS;
IO1CLR|=LCM_RW;
IO1CLR=0xff0000; //先清零
IO1SET|=(dat<<16); //再送数
nop();nop();nop();nop();
IO1SET|=LCM_E;
IO1CLR|=LCM_E;
}
/*****************************************************
函 数 名:LCD_Mychar()
功 能:自定义字符--CGRAM
说 明:LCD1602字符库中没有温度符号,自定义温度符号
******************************************************/
void LCD_Mychar(void)
{
//---------自定义字符代码--01H-------温度符号------------
WC_Lcd(0x48); //第1行
WD_Lcd(0x02); //
WC_Lcd(0x49); //第2行
WD_Lcd(0x05); //
WC_Lcd(0x4A); //第3行 1------**--
WD_Lcd(0x05); // 2----**--**
WC_Lcd(0x4B); //第4行 3----**--**
WD_Lcd(0x02); // 4------**--
WC_Lcd(0x4C); //第5行 5----------
WD_Lcd(0x00); // 6----------
WC_Lcd(0x4D); //第6行 7----------
WD_Lcd(0x00); // 8----------
WC_Lcd(0x4E); //第7行
WD_Lcd(0x00); //
WC_Lcd(0x4F); //第8行
WD_Lcd(0x00); //
}
/****************************************************************************
* 名称:lcd_init()
* 功能:lcd初始化函数
****************************************************************************/
void lcd_init(void)
{
WC_Lcd(0x38);
WC_Lcd(0x06);
WC_Lcd(0x0c);
LCD_Mychar(); // 写入自定义字符,代码01
}
/****************************************************************************
* 函数名称:DisText()
* 函数功能:显示文本
* 入口参数:addr 1602 DDRAM地址,*p 显示文本数据指针
****************************************************************************/
void DisText(unsigned char addr,unsigned char *p){
WC_Lcd(addr);
while(*p !='\0')WD_Lcd(*(p++));
}
/****************************************************************************
* 函数名称:Delay_DS18B20()
* 函数功能:软件延时
* 入口参数:time 延时参数,值越大,延时越久
****************************************************************************/
void Delay_DS18B20(unsigned char time){
unsigned char i,j;
for(i=0;i<8;i++){
for(j=1;j<time;j++);
}
}
/****************************************************************************
* 函数名称:Init_DS18B20()
* 函数功能:DS18B20初始化
* 出口参数:x=0则初始化成功 x=1则初始化失败
****************************************************************************/
unsigned char Init_DS18B20(void){
unsigned char x=1;
IO1DIR|=DQ; //设置引脚为输出
IO1SET|=DQ; //DQ复位
Delay_DS18B20(2); //稍做延时
IO1CLR|=DQ; //将DQ拉低
Delay_DS18B20(560); //精确延时 大于 480us
IO1SET|=DQ; //拉高总线
IO1DIR&=(~DQ); //转为输入
Delay_DS18B20(55); //延迟30~130
x=(IO1PIN&DQ)>>31; //150us延时后 如果x=0则初始化成功 x=1则初始化失败
Delay_DS18B20(480); //精确延时 110~480
return (x);
}
unsigned char ReadOneChar(void){
unsigned char i=0;
unsigned char dat = 0;
IO1DIR|=DQ; //设置引脚为输出
for (i=8;i>0;--i){
dat>>=1;
IO1DIR|=DQ; //设置引脚为输?
IO1SET|= DQ; //给脉冲信号
Delay_DS18B20(2);
IO1CLR|=DQ; //给脉冲信号
Delay_DS18B20(10); //延迟
IO1SET|= DQ; //给脉冲信号
Delay_DS18B20(10); //此时间不能太大,大了就会不稳定
IO1DIR&=(~DQ); //设置引脚为输入
if(IO1PIN & DQ)dat|=0x80;
Delay_DS18B20(60); //至少等待50us
}
IO1DIR |= DQ; //设置引脚为输出
IO1SET |= DQ; //给脉冲信号
return(dat);
}
/****************************************************************************
* 函数名称:WriteOneChar()
* 函数功能:DS18B20写一个字节
* 入口参数:dat 写入的数据
****************************************************************************/
void WriteOneChar(unsigned char dat){
unsigned char i=0;
IO1DIR|=DQ; //设置引脚为输出
for (i=8; i>0; --i){
if(dat&0x01){
IO1CLR |= DQ; // 给脉冲信号
Delay_DS18B20(10);
IO1SET|=DQ; // 给脉冲信号
Delay_DS18B20(60);
}
else{
IO1CLR |= DQ; // 给脉冲信号
Delay_DS18B20(60);
IO1SET|=DQ; // 给脉冲信号
Delay_DS18B20(10);
}
dat>>=1;
}
}
/****************************************************************************
* 函数名称:ReadTemp()
* 函数功能:读取DS18B20当前温度
* 出口参数:tvalue 读取的温度值
****************************************************************************/
unsigned char ReadTemp(void){
unsigned char a=0,b=0;
unsigned char tvalue=0; //温度值
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
tvalue = (b << 8);
tvalue = tvalue | a;
return(tvalue*(0.625)); //温度值扩大10倍,精确到1位小数
}
void dis_readnumber()
{
unsigned char i,temp;
Init_DS18B20();
WriteOneChar(0x33); //读rom 即rom中的编码
for(i=0;i<8;i++)
{
save_number[i]=ReadOneChar(); //保存序列号
}
WriteOneChar(0x80);
for(i=0;i<8;i++)
{
temp=save_number[i]>>4;
if(temp<10)
{
WD_Lcd(0x30+temp);
}
else
{
WD_Lcd(0x37+temp);
}
temp=save_number[i]&0x0f;
if(temp<10)
{
WD_Lcd(0x30+temp);
}
else
{
WD_Lcd(0x37+temp);
}
}
}
/****************************************************************************
* 名称:main()
* 功能:显示文本
****************************************************************************/
int main(void)
{
PINSEL2 &=0x00000000; //1111 1111 1100 0000 0000 0000 0000 0000
IO1DIR |= 0x7ff0000; //0000 0111 1111 1111
IO1SET |= 0xff0000; //1111 1111
PINSEL1 |=0x00000000;
lcd_init();
DisText(0x80,"");
while(1)
{
dis_readnumber(); //显示序列号
}
}