📄 ds1820.c
字号:
//文件名:MC430F14_DEMO_5.c
//版本: 1.0
//描述:MC430F14开发板的主程序,MSP430对DS18B20操作,将读取的温度显示在LCD上。
//编程环境:IAR WE430 3.40A
//编写: www.microcontrol.cn DC
//时期: 2006.10.21.
#include <msp430x14x.h>
#include "DS1820.h"
#include "lcd_ch.h"
#define DQ1 P5OUT|=BIT7 //DQ=1
#define DQ0 P5OUT&=~BIT7 //DQ=0
const unsigned char digit[10] = {'0','1','2','3','4','5','6','7',
'8','9'};
unsigned char temp_display [9] = {'x','0','0','0','.','0','0','0','\0'};
//将温度值转换成可显示十进制值
//取数范围整数3位,小数点后3位.
void display_number(float f_data)
{ unsigned long value;
float n;
n=f_data *1000;
value = (unsigned long int)n;
temp_display[1] = digit[value/100000]; //100位
value = value%100000;
temp_display[2] = digit[value/10000]; //10位
value = value%10000;
temp_display[3] = digit[value/1000]; //1位
value = value%1000;
temp_display[5] = digit[value/100]; //0.1位
value = value%100;
temp_display[6] = digit[value/10]; //0.01位
value = value%10;
temp_display[7] = digit[value/1]; //0.001位
}
//--------------------------------------------------------------------
//说明:实验标题1,应用单实形式发送.
void send_title() //标题显示
{
sendCMD(off_cursor); //关光标
sendCMD(LCD_L11);
display(LCD_L11,0xca,0xd4); //试
display(LCD_L12,0xd1,0xe9); //验
//sendDAT('D'); sendDAT('S'); sendDAT('1'); sendDAT('8');
//sendDAT('2'); sendDAT('0');
display(LCD_L13,0xca,0xd2); //室
display(LCD_L14,0xb5,0xb1); //当
display(LCD_L15,0xc7,0xb0); //前
display(LCD_L16,0xce,0xc2); //温
display(LCD_L17,0xb6,0xc8); //度
//display(LCD_L25,0xce,0xaa); //为
sendCMD(LCD_L21); //显示地址指回处
sendCMD(off_cursor); //关光标
}
//---------------------------------------------------------------------
//MSP430F14初始化
void mcuinit(void)
{
P1DIR |=BIT1; //P1.1驱动LED
P5DIR |=BIT7; //设DQ电时为1
DQ1;
initlcm(); //LCD初始化
send_title(); //显示实验标题
}
//---------------------------------------------------------------------
//MC430F14 DS18B20实验主程序
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // 停止WDT
mcuinit();
while(1)
{
GetTemp(); //读取温度
if(symbol==1)
temp_display[0] = '+'; //处理正负符合
else
temp_display[0] = '-';
if(Error==1)
{ display(LCD_L26,0xca,0xa7); //失
display(LCD_L27,0xb0,0xdc); //败
}
else
{ display(LCD_L26,0xd5,0xfd); //正
display(LCD_L27,0xc8,0xb7); //确
}
P1OUT ^= BIT1;
display_number(Temper); //数据变换显示数据
char_string (temp_display,LCD_L21);
}
}
//END--------------------------------------------------------------
//文件名:MC430F14_DEMO_5.h
//版本: 1.0
//描述:程序声明
//编程环境:IAR WE430 3.40A
//编写: www.microcontrol.cn DC
//时期: 2006.10.21
//例程解说: 将DS18B20的变量及程序声明,供外部程序使用
//END--------------------------------------------------------------
//文件名:MSP430_DS18B20.c
//版本: 1.0
//描述:MC430F14开发板的MSP430与DS18B20操作主程。
//编程环境:IAR WE430 3.40A
//编写: www.microcontrol.cn DC
//时期: 2006.10.21
#include <msp430x14x.h>
//定义一个位设置,这样可以简化程序编写
#define DQ1 P5OUT|=BIT7 //DQ=1
#define DQ0 P5OUT&=~BIT7 //DQ=0
#define DQIO_OUT P5DIR|=BIT7 //设为输出
#define DQIO_IN P5DIR &= ~BIT7 //设为输入
#define positive 0x0f //正温系数
//定义
unsigned char Error = 0;
float Temper=0.0; //真正有效温度值
int temperature=0; //读取两字节温度数据
unsigned char symbol = 1 ; //温度正负符号
//----------------------------------
//功能:us 级别延时
// n=10,则延时10*5+6=56uS
//----------------------------------
void DelayNus(unsigned int n)
{
while(n--){};
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ0;
_NOP();_NOP(); //延时5us
_NOP();_NOP();_NOP();
if((n&0X01)==0X01) //DQ=1
DQ1;
else
DQ0; //DQ=0
n=n>>1; //下一位
DelayNus(6); //延时50us 以上
DQ1;
}
}
//------------------------------------
//功能:读取18B20
//------------------------------------
unsigned char Read_18B20(void)
{
unsigned char i;
unsigned char temp;
for(i=0;i<8;i++)
{
temp=temp>>1; //移向下一位
DQ0;
_NOP(); //延时1us
DQ1;
_NOP();_NOP(); //延时5us
_NOP();
DQIO_IN; //DQ口设为输入
if((P5IN&BIT7)==0) //DQ是否等于0
{
temp=temp&0x7F; //读入DQ为0
}
else
{
temp=temp|0x80; //读入DQ为1
}
DelayNus(5); //延时40us
DQIO_OUT; //DQ口设为输出
DQ1; //DQ输出1
}
return temp; //返回一个数据
}
//-----------------------------------
//复位说明:复位要求主CPU将数据线下拉500us,然后释放,
//当DS18B20收到信号后等待16~60us左右,后发出60~240微秒的存在低脉冲,
//主CPU收到此信号表示复位成功。
//初始化DS18B20
void Init (void)
{
DQ0;
DelayNus(50); //延时500us
DQ1;
DelayNus(12); //延时16~60us
DQIO_IN; //设DQ为输入
if((P5IN&BIT7)==BIT7) //1000 0000b=1f,DQ是否为1
{
// Error =1; //失败1
DQIO_OUT; //设DQ为输输出
}
else
{
Error = 0; //初始化成功
DQIO_OUT; //设DQ为输输出
DQ1;
}
}
//----------------------------------
//指令描述:跳过ROM命令,指定代码为CCH,忽略64位ROM地址,直接向DS1820发温度变换
//命令,适用于单片机工作.
void Skip(void)
{
Write_18B20(0xcc);
}
//----------------------------------
//指令描述:温度转换命令,指定代码为44H.启动DS1820进行温度转换,12位转换时最长
//为750ms(9位为93.75ms).结果存入内部9字节RAM中.
void Convert (void)
{
Write_18B20(0x44);
}
//----------------------------------
//指令描述:读暂存器,指定代码为BEH.读内部RAM中9字节的内容.
void ReadDo (void)
{
Write_18B20(0xbe);
}
//----------------------------------
//读取温度值
void ReadTemp (void)
{
char temp_low, temp_high; //温度值
temp_low = Read_18B20(); //读低位
temp_high = Read_18B20(); //读高位
if((temp_high|positive)==positive)
symbol=1; //测到的温度为正
else
symbol=0; //测到的温度为负
temperature=(temp_high&0x0f);//屏蔽高4位
temperature<<=8; //将temp_high部分数据移到temperature高8位
temperature|=temp_low; //将高低两字节内部合并成一个16位数据
if(symbol==0) //是否为负温度
{ temperature = (~temperature)+1; //将其取反后加1
}
Temper=temperature*0.0625; //计算真实温度值
}
//----------------------------------
//MCU对DS18B20进行温度转换时,其操作必须满足以下过程:
// 1- 每一次读写之前都要对DS18B20进行复位.
// 2- 完成复位后发送一条ROM命令到DS18B20.
// 3- 最后发送一条RAM命令到DS18B20.
// 以上系列动作是根据DS18B20的通讯协议所得.
//读取温度
void GetTemp(void)
{
Init(); //DS1820初始化
Skip(); //跳过64位ROM(ROM命令)
Convert(); //转换(RAM命令)
DelayNus(60000); //60000x5us=0.3s
DelayNus(60000); //0.3s
DelayNus(60000); //0.3s
Init(); //DS1820初始化
Skip(); //跳过64位ROM
ReadDo(); //读暂存器
ReadTemp(); //读取温度值
}
//END--------------------------------------------------------------
//LCD型号:KM12232F(ST7920A),连接模式:串口模式,供电:3V.
//KM12232F是内带汉字库,只须提供汉字内码地址给LCD模块即可.
//MCU:TI MSP430F1121. SID-->P4.6,SCK-->P4.7
//C编译器:IAR Embedded Workbench IDE 3.2
//编写日期:2004.7.
//编写提供:DC Huang
# include <msp430x14x.h>
#define SID 0x40 //串行数据输入端
#define SCK 0x80 //同步时钟输入端
#define DDRAM_0 0x80 //显示回位
#define off_cursor 0x0c //关闭光标
#define on_cursor 0x0e //开光标
#define off_cursor_filsh 0x0e //光标关闪烁
#define on_cursor_filsh 0x0f //光标开闪烁
#define GM12232_MINADD_L1 0x80 //第一行第一位地址
#define GM12232_MAXADD_L1 0x87 //第一行最后地址
#define GM12232_MINADD_L2 0x90 //第二行第一位地址
#define GM12232_MAXADD_L2 0x97 //第二行最后地址
//**************************************************
void delay(void)
{ char i;
for (i = 0;i != 0xff;i++);
}
//**************************************************
void sendBYTE(char dat) //串行传送一字节数据
{
char i;
P4DIR|=SID; //设P1.3 SID为输出
for (i=0;i<8;i++)
{
P4OUT&=~SCK; //SCK=0
if((dat & 0x80)!=0)
P4OUT|=SID; //SID=1
else
P4OUT&=~SID; //SID=0
P4OUT|=SCK; //SCK=1;
dat = dat<<1;
}
}
//****************************************************
//如果需要改变半字地址,也是用此程序.只需输入地址就可以.
void sendCMD(char dat) //写控制指令
{
sendBYTE(0xf8);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void sendDAT(char dat)//写显示数据;也可以写一个单字节字符
{
sendBYTE(0xfa);
sendBYTE(dat & 0xf0);
sendBYTE((dat<<4)&0xf0);
}
//****************************************************
void display(char x_add,char dat,char dat1)
//写汉字到LCD屏指定位置
//x_add显示RAM地址
//dat/dat1显示汉字编码
{
sendCMD(x_add);
sendDAT(dat);
sendDAT(dat1);
}
//*****************************************************
void initlcm(void)//初始化LCM
{
delay();
P4DIR|=SCK; //SCK设为输出
sendCMD(0x30);//功能设置:一次送8位数据,基本指令集
sendCMD(0x04);//点设定 :显示字符/ 光标从左到右移位,DDRAM地址加一
sendCMD(0x0f);//显示设定:开显示 ,显示光标,当前显示位反白闪动
sendCMD(0x0f);//显示设定:开显示,显示光 标,当前显示位反白 闪动
sendCMD(0x01);//清DDRAM
sendCMD(0x02);//*DDRAM 地址归位
}
//****************************************************
//发送半角数字和字母字符串
//*p为字符串指针
//x_add 所要显示的地址
void char_string (unsigned char *p, unsigned char x_add)
{
unsigned char n;
if((x_add >= GM12232_MINADD_L1)&&(x_add <GM12232_MAXADD_L1))
{ sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else if ((x_add >= GM12232_MINADD_L2)&&(x_add <GM12232_MAXADD_L2))
{ sendCMD(x_add);
for (n=0; p[n]!='\0'; n++)
{ sendDAT(p[n]); }
}
else
return ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -