ds18b20基于msp430的水温控制系统完整程序.docx
《ds18b20基于msp430的水温控制系统完整程序.docx》由会员分享,可在线阅读,更多相关《ds18b20基于msp430的水温控制系统完整程序.docx(36页珍藏版)》请在冰点文库上搜索。
ds18b20基于msp430的水温控制系统完整程序
main.c
#include
#include"keypad.h"
#include"lcd1602.h"
#include"ds18b20.h"
#include"control.h"
typedefunsignedcharuchar;
typedefunsignedintuint;
voidInitSys();//函数声明
intmain(void)
{
WDTCTL=WDTPW+WDTHOLD;//关闭看门狗
/*下面六行程序关闭所有的IO口*/
P1DIR=0XFF;P1OUT=0XFF;
P2DIR=0XFF;P2OUT=0XFF;
P3DIR=0XFF;P3OUT=0XFF;
P4DIR=0XFF;P4OUT=0XFF;
P5DIR=0XFF;P5OUT=0XFF;
P6DIR=0XFF;P6OUT=0XFF;
P6DIR|=BIT2;P6OUT|=BIT2;//关闭电平转换
InitSys();//系统初始化
Init_Keypad();//键盘初始化
LcdReset();//lcd初始化
start:
disp_18b20();
gotostart;
}
/***************************************************
系统初始化
*******************************************/
voidInitSys()
{
unsignedintiq0;
BCSCTL1&=~XT2OFF;//打开XT2振荡器
do
{
IFG1&=~OFIFG;//清除振荡器失效标志
for(iq0=0xFF;iq0>0;iq0--);//延时,等待XT2起振
}
while((IFG1&OFIFG)!
=0);//判断XT2是否起振
BCSCTL2=SELM_2+SELS;//选择MCLK,SMCLK为XT2
TACTL|=TASSEL_2+ID_3;//计数时钟选择SMLK=8MHz,1/8分频后为1MHz
P5DIR|=BIT5;//加热器控制端口
P5OUT&=~BIT5;
P5DIR|=BIT7;//风扇控制端口
P5OUT&=~BIT7;
_EINT();//打开全局中断控制,若不需要打开,可以屏蔽本句
}
/*********************************************************************
端口1(键盘)中断函数
*************************************************************/
#pragmavector=PORT1_VECTOR
__interruptvoidPort1()
{
Key_Event();//判断按键并获取键值
if(key_val>16)//输入为数字键
temp_disp();
elseif(key_val==12)//输入为确定键
{
sure=1;
temp_set_2=ten2two();
}
elseif(key_val==13)//输入为清除键
temp_clr();
Init_Keypad();//键盘初始化
}
keypad.h
voidInit_Keypad(void);
voidCheck_Key(void);
voiddelay(unsignedinttmp);
voidKey_Event(void);
//引用外部变量的声明
externunsignedcharkey_Pressed;
externunsignedcharkey_val;
externunsignedcharkey_Flag;
keypad.c
#include
typedefunsignedcharuchar;
typedefunsignedintuint;
/***************全局变量***************/
ucharkey_Pressed;//按键是否被按下:
1--是,0--否
ucharkey_val;//存放键值
ucharkey_Flag;//按键是否已放开:
1--是,0--否
//设置键盘逻辑键值与程序计算键值的映射
ucharkey_Map[]={'1','2','3','4','5','6','7','8',
'9','0',11,12,13,14,15,16};//k12,清除键。
k13,确定键
/*******************************************
Init_Keypad:
初始化扫描键盘的IO端口
********************************************/
voidInit_Keypad(void)
{
P1DIR=0xf0;//P1.0~P1.3设置为列输入,P1.4~P1.7设置为行输出
P1OUT=0x0f;//P1.4~P1.7输出低电平
P1IFG=0X00;
P1SEL=0;//P1口设置为一般I/O端口
P1IES=0x0f;
P1IE=0x0f;//P1低四位中断开启
key_Flag=0;
key_Pressed=0;
key_val=0;
}
/*******************************************
延时约15ms,完成消抖功能
********************************************/
voiddelay(uinttmp)
{
for(;tmp>0;tmp--);
}
/*******************************************
扫描键盘的IO端口,获得键值
********************************************/
voidCheck_Key(void)
{
ucharrow,col,tmp1,tmp2;
tmp1=0x80;
for(row=0;row<4;row++)//行扫描
{
P1OUT=0xf0;//P1.4~P1.7输出全1
P1OUT-=tmp1;//P1.4~p1.7输出四位中有一个为0
tmp1>>=1;
if((P1IN&0x0f)<0x0f)//是否P1IN的P1.0~P1.3中有一位为0
{
tmp2=0x01;//tmp2用于检测出那一位为0
for(col=0;col<4;col++)//列检测
{
if((P1IN&tmp2)==0x00)//是否是该列,等于0为是
{
key_val=key_Map[row*4+col];//获取键值
return;//退出循环
}
tmp2<<=1;//tmp2右移1位
}
}
}
}
/*******************************************
检测按键,并获取键值
********************************************/
voidKey_Event(void)
{
uchartmp;
P1OUT&=0x00;//设置P1OUT全为0,等待按键输入
tmp=P1IN;//获取p1IN
if((key_Pressed==0x00)&&((tmp&0x0f)<0x0f))//如果有键按下
{
key_Pressed=1;//如果有按键按下,设置key_Pressed标识
delay(1200);//消除抖动
Check_Key();//调用check_Key(),获取键值
}
elseif((key_Pressed==1)&&((tmp&0x0f)==0x0f))//如果按键已经释放
{
key_Pressed=0;//清除key_Pressed标识
key_Flag=1;//设置key_Flag标识
}
else
{
_NOP();
}
}
Lcd1602.h
voidDispStr(unsignedcharx,unsignedchary,unsignedchar*ptr);
voidDispNChar(unsignedcharx,unsignedchary,unsignedcharn,unsignedchar*ptr);
voidLocateXY(unsignedcharx,unsignedchary);
voidDisp1Char(unsignedcharx,unsignedchary,unsignedchardata);
voidLcdReset(void);
voidLcdWriteCommand(unsignedcharcmd,unsignedcharchk);
voidLcdWriteData(unsignedchardata);
voidWaitForEnable(void);
voidDelay5ms(void);
voidDelay400ms(void);
externunsignedchartemp_set[];
lcd1602.c
#include
#include"lcd1602.h"
#include"keypad.h"
typedefunsignedcharuchar;
typedefunsignedintuint;
uchartemp_set[]={"tempset:
__.__"};
uchartemp_now[]={"tempnow:
"};
/**************宏定义***************/
#defineDataDirP4DIR
#defineDataPortP4OUT
#defineBusy0x80
#defineCtrlDirP3DIR
#defineCLR_RSP3OUT&=~BIT0;//RS=P3.0
#defineSET_RSP3OUT|=BIT0;
#defineCLR_RWP3OUT&=~BIT1;//RW=P3.1
#defineSET_RWP3OUT|=BIT1;
#defineCLR_ENP3OUT&=~BIT2;//EN=P3.2
#defineSET_ENP3OUT|=BIT2;
/***********************************************
让液晶从某个位置起连续显示一个字符串
x--位置的列坐标
y--位置的行坐标
ptr--指向字符串存放位置的指针
***********************************************/
voidDispStr(ucharx,uchary,uchar*ptr)
{
uchar*temp;
uchari,n=0;
temp=ptr;
while(*ptr++!
='\0')n++;//计算字符串有效字符的个数
for(i=0;i{
Disp1Char(x++,y,temp[i]);
if(x==0x0f)
{
x=0;
y^=1;
}
}
}
/*******************************************
让液晶从某个位置起连续显示N个字符
x--位置的列坐标
y--位置的行坐标
n--字符个数
ptr--指向字符存放位置的指针
********************************************/
voidDispNChar(ucharx,uchary,ucharn,uchar*ptr)
{
uchari;
for(i=0;i{
Disp1Char(x++,y,ptr[i]);
if(x==0x0f)
{
x=0;
y^=1;
}
}
}
/*******************************************
功能:
向液晶输入显示字符位置的坐标信息
参数:
x--位置的列坐标
y--位置的行坐标
********************************************/
voidLocateXY(ucharx,uchary)
{
uchartemp;
temp=x&0x0f;
y&=0x01;
if(y)temp|=0x40;//如果在第2行
temp|=0x80;
LcdWriteCommand(temp,1);
}
/*******************************************
功能:
在某个位置显示一个字符
参数:
x--位置的列坐标
y--位置的行坐标
data--显示的字符数据
********************************************/
voidDisp1Char(ucharx,uchary,uchardata)
{
LocateXY(x,y);
LcdWriteData(data);
}
/*******************************************
LcdReset:
对1602液晶模块进行复位操作
********************************************/
voidLcdReset(void)
{
CtrlDir|=0x07;//控制线端口设为输出状态
DataDir=0xFF;//数据端口设为输出状态
LcdWriteCommand(0x38,0);//规定的复位操作
Delay5ms();
LcdWriteCommand(0x38,0);
Delay5ms();
LcdWriteCommand(0x38,0);
Delay5ms();
LcdWriteCommand(0x38,1);//显示模式设置
LcdWriteCommand(0x08,1);//显示关闭
LcdWriteCommand(0x01,1);//显示清屏
LcdWriteCommand(0x06,1);//写字符时整体不移动
LcdWriteCommand(0x0c,1);//显示开,不开游标,不闪烁
DispNChar(0,0,14,temp_set);//显示预设温度提示
DispNChar(0,1,9,temp_now);//显示实时温度提示
}
/*******************************************
函数名称:
LcdWriteCommand
功能:
向液晶模块写入命令
参数:
cmd--命令,
chk--是否判忙的标志,1:
判忙,0:
不判
********************************************/
voidLcdWriteCommand(ucharcmd,ucharchk)
{
if(chk)WaitForEnable();//检测忙信号?
CLR_RS;
CLR_RW;
_NOP();
DataPort=cmd;//将命令字写入数据端口
_NOP();
SET_EN;//产生使能脉冲信号
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函数名称:
LcdWriteData
功能:
向液晶显示的当前地址写入显示数据
参数:
data--显示字符数据
返回值:
无
********************************************/
voidLcdWriteData(uchardata)
{
WaitForEnable();//等待液晶不忙
SET_RS;
CLR_RW;
_NOP();
DataPort=data;//将显示数据写入数据端口
_NOP();
SET_EN;//产生使能脉冲信号
_NOP();
_NOP();
CLR_EN;
}
/*******************************************
函数名称:
WaitForEnable
功能:
等待1602液晶完成内部操作
******************************************/
voidWaitForEnable(void)
{
P4DIR&=0x00;//将P4口切换为输入状态
CLR_RS;
SET_RW;
_NOP();
SET_EN;
_NOP();
_NOP();
while((P4IN&Busy)!
=0);//检测忙标志
CLR_EN;
P4DIR|=0xFF;//将P4口切换为输出状态
}
/*******************************************
Delay5ms:
延时约5ms
********************************************/
voidDelay5ms(void)
{
uinti=40000;
while(i!
=0)
{
i--;
}
}
/*******************************************
Delay400ms:
延时约400ms
********************************************/
voidDelay400ms(void)
{
uchari=50;
uintj;
while(i--)
{
j=7269;
while(j--);
}
}
Ds18b20.h
voidDelayNus(unsignedintn);
unsignedcharInit_18B20(void);
voidWrite_18B20(unsignedcharwdata);
unsignedcharRead_18B20(void);
voidSkip(void);
voidConvert(void);
voidRead_SP(void);
unsignedintReadTemp(void);
unsignedintDo1Convert(void);
voidDisp_Numb(unsignedinttemper);
voiddisp_18b20(void);
externunsignedchardN[6];//要显示的6位温度数字
externunsignedinttemp_now_2;//温度值的十六进制存储
ds18b20.c
#include
#include"ds18b20.h"
#include"lcd1602.h"
#include"control.h"
typedefunsignedcharuchar;
typedefunsignedintuint;
#defineDQ1P5OUT|=BIT6
#defineDQ0P5OUT&=~BIT6
#defineDQ_inP5DIR&=~BIT6
#defineDQ_outP5DIR|=BIT6
#defineDQ_val(P5IN&BIT6)
unsignedchardN[6];//要显示的6位温度数字
unsignedinttemp_now_2=0;//温度值的十六进制存储
voiddisp_18b20(void)
{
Disp_Numb(Do1Convert());
Disp1Char(9,1,dN[5]+0x30);
Disp1Char(10,1,dN[4]+0x30);
Disp1Char(11,1,0x2e);//0x2e是小数点对应的ASCII码值
Disp1Char(12,1,dN[3]+0x30);
Disp1Char(13,1,dN[2]+0x30);
//Disp1Char(14,1,dN[1]+0x30);
//Disp1Char(15,1,dN[0]+0x30);
if(sure!
=0)compare();
}
/*******************************************
函数名称:
DelayNus
功能:
实现N个微秒的延时
参数:
n--延时长度
返回值:
无
说明:
定时器A的计数时钟是1MHz,CPU主频8MHz
所以通过定时器延时能够得到极为精确的
us级延时
********************************************/
voidDelayNus(uintn)
{
CCR0=n;
TACTL|=MC_1;//增计数到CCR0
while(!
(TACTL&BIT0));//等待
TACTL&=~MC_1;//停止计数
TACTL&=~BIT0;//清除中断标志
}
/*******************************************
函数名称:
Init_18B20
功能:
对DS18B20进行复位操作
参数:
无
返回值:
初始化状态标志:
1--失败,0--成功
*******************************************