📄 temp&sonic.c
字号:
#include "msp430x22x4.h"
#include "1602.h"
#define DQ1 P1OUT|=BIT2 //定义 ds18b20的DQ引脚的 输出 高 1;
#define DQ0 P1OUT&=~BIT2 ////定义 ds18b20的DQ引脚的 输出 低 0;
float Temper=0.0; //温度 变量
int temperature=0; //温度的 16进制
unsigned char Error = 0;
int dis_mm;
int tp[5]={0,0,0,0,1};
int tep=1;
float dis_;
int dis[4];
int jian=0; //显示的 查询标志
int ojian=0;
int ck=0;
//用定时器A的CCR0来捕获外部 ccia0的输入信号 的 上升沿 和 下降沿。
//使用 时钟频率1MHz 内部DCO
//定时器时钟源选择SMCLK=1MHZ
//一个超声波最长周期为 32ms ,一个连续计数周期为62ms,
//第一个TACCR0的捕获值是不超声波发射的 开始 (上升沿),
//应该将第二个TACCR0的值减去第一个TACCR0的值才是一个完整的超声波周期
// 转化显示 距离 = (时间*340m/s)/2
// MSp430F2274
// -----------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | p1.1|-->echo ultra sonic moudle
// | P1.0|-->tigger
void tigger(); //预声明函数
void Delay(void);
long float count(float x,float y);
void convert_sonic(void);
void convert_temp(void);
void DelayNus(unsigned int n)
{
while(n--){};
}
//-----------------------------------
//功能:写18B20
//-----------------------------------
void Write_18B20(unsigned char n)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ0;
DelayNus(1);//延时13us 左右
if((n&0X01)==0X01) DQ1;
else DQ0;
n=n>>1;
DelayNus(9);//延时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();_NOP();_NOP();
P1DIR&=~BIT2;
if((P1IN&BIT2)==0)
{
temp=temp&0x7F;
}else
{
temp=temp|0x80;
}
DelayNus(7);//延时40us
P1DIR|=BIT2;
DQ1;
}
return temp;
}
//-----------------------------------
void Init (void)
{
DQ0;
DelayNus(50);//延时500us
DQ1;
DelayNus(17);//延时90us
P1DIR&=~BIT2;
if((P1IN&BIT2)==BIT2) //0001 1111b=1f
{
Error =1; //失败1
P1DIR|=BIT2;
}else
{
Error = 0;//初始化成功
P1DIR|=BIT2;
DQ1;
}
}
//----------------------------------
void Skip(void)
{
Write_18B20(0xcc);
}
//----------------------------------
void Convert (void)
{
Write_18B20(0x44);
}
//----------------------------------
void ReadDo (void)
{
Write_18B20(0xbe);
}
//----------------------------------
void ReadTemp (void)
{
char temp_low,temp_high; //温度值
temp_low=Read_18B20(); //读低位
temp_high=Read_18B20(); //读高位
temperature=(temp_high&0x0f);
temperature<<=8;
temperature|=temp_low;
Temper=temperature*0.0625;
}
void GetTemp(void)
{
Init();
Skip();
Convert();
DelayNus(60000);
DelayNus(60000);
DelayNus(60000);//延时1s以上
Init();
Skip();
ReadDo();
ReadTemp();
}
////////////////////////////////////////////////////////////////////////////////
/////////////////////main program///////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
///// 主程序的 开始/////////////////////////////////////////////////////////////
int main( void )
{
WDTCTL=WDTPW+WDTHOLD; //关看门狗
// BCSCTL1 =CALBC1_1MHZ; //设定DCO为1MHZ
// DCOCTL =CALBC1_1MHZ;
//定义数组
float value1,value2; //两个沿的 保存
P2DIR =0x00; // P2为输入
P2IES=0x0F; //中断沿 选择
P2IE=0x0F; //中断使能
P2IFG=0; //清中断标志位
P1SEL|=BIT1; //定义P1。1为第二功能 , CCIx0
P1DIR&=~BIT1; //P1。1为输入
P1DIR |=BIT2; //开始 P1.2为输出
DQ1; //输出 1
_EINT(); //使能全局中断
LcdInit(); //初始化液晶
//LcdWriteCommand(0x01, 1); //清平
while(1)
{
////////////////////////// temperature moudle//////////////////////////
GetTemp(); //读取温度
////////////////////////////ultra sonic start///////////////////////////
TACCTL0=CM_3+CCIS_0+CAP; //捕获模式,捕获上升沿和下降,捕获CCIxA
TACCTL0 &=~CCIFG; //清CCR0的标志位
tigger(); //触发 ultra sonic
TACTL=TASSEL_2+MC_2+TACLR; //定时器时钟源为SMCLK,启动连续计数,清TAR
while(!(CCIFG&TACCTL0)); //查CCR0标志位,等待发射的 超声波
value1=TACCR0; //第一个捕获值存入value,捕获到返回的值
TACCTL0 &=~CCIFG;
while (!(CCIFG&TACCTL0)); //等待反射回来的超声波 下降沿
value2=TACCR0;
dis_=count(value1,value2); //转化值为时间、距离单位为厘米
//TACCTL0 &=~CCIFG; //清CCR0的标志位
///////////////////////////ultra sonic moudle over//////////////////////
convert_sonic(); //分离 各个位 送 显示数组
convert_temp();
int remain=0;
remain=dis_mm/30;
//if(jian==0)
/*{ LcdWriteCommand(0x01, 1); //清平
DispStr(0,0,"Distance:"); //调用显示 显示距离
////////////距离的显示///////////////////////////
for (int i=0;i<3;i++)
Disp1Char(i+9,0,dis[i]);
DispStr(0,12,".");
Disp1Char(13,0,dis[3]);
Disp1Char(14,0,0x43);
Disp1Char(15,0,0x4d);
//
}
else
{ LcdWriteCommand(0x01, 1); //清平
DispStr(1,0,"Temperat:");
/////////////温度的显示//////////////////////////
for(int i=0;i<3;i++)
Disp1Char(i+9,1,tp[i]);
Disp1Char(12,1,0x2e);
Disp1Char(13,1,tp[3]);
Disp1Char(14,1,tp[4]);
Disp1Char(15,1,0x43);
// LcdWriteCommand(0x01, 1); //清平
} */
/*////////////////////////////////////////////////////
{
LcdWriteCommand(0x01, 1); //清平
DispStr(0,0,"High:"); //调用显示 显示距离
for (int i=1;i<3;i++)
Disp1Char(i+5,0,dis[i]);
DispStr(0,8,".");
Disp1Char(9,0,dis[3]);
Disp1Char(10,0,0x43);
Disp1Char(11,0,0x4d);
Disp1Char(2,1,0x25); //显示%号;
DispStr(1,3,"remain");
/////////////温度的显示//////////////////////////
for(int i=1;i<3;i++)
Disp1Char(i+9,1,tp[i]);
Disp1Char(12,1,0x2e);
Disp1Char(13,1,tp[3]);
Disp1Char(14,1,tp[4]);
Disp1Char(15,1,0x43);
}
else
{
LcdWriteCommand(0x01, 1); //清平
if(jian==1)
{
DispStr(0,0,"SET THE LEVEL");
Disp1Char(15,1,0x3e); //显示 >
}
else
{
if(jian==2)
{DispStr(0,0,"TEMPERA.:");
for(int i=1;i<3;i++)
Disp1Char(i+9,0,tp[i]);
Disp1Char(12,0,0x2e);
Disp1Char(13,0,tp[3]);
Disp1Char(14,0,tp[4]);
Disp1Char(15,0,0x43);
DispStr(1,3,"HEATING?");
Disp1Char(0,1,0x3c);
Disp1Char(15,1,0x3e);
}
else
{DispStr(0,0,"SET THE ALARM"); Disp1Char(0,1,0x3c);}
}
}
*/
switch((ck==2)?ojian:jian)
{
case 0:
{
LcdWriteCommand(0x01, 1); //清平
DispStr(0,0,"High:"); //调用显示 显示距离
for (int i=1;i<3;i++)
Disp1Char(i+5,0,dis[i]);
DispStr(0,8,".");
Disp1Char(9,0,dis[3]);
Disp1Char(10,0,0x43);
Disp1Char(11,0,0x4d);
Disp1Char(2,1,0x25); //显示%号;
DispStr(1,3,"remain");
/////////////温度的显示//////////////////////////
for(int i=1;i<3;i++)
Disp1Char(i+9,1,tp[i]);
Disp1Char(12,1,0x2e);
Disp1Char(13,1,tp[3]);
Disp1Char(14,1,tp[4]);
Disp1Char(15,1,0x43);
break;
}
case 1:
{
switch(ck)
{
case 2:
{ LcdWriteCommand(0x01, 1); //清平
DispStr(0,0,"NOW IS:"); //调用显示 显示距离
for (int i=1;i<3;i++)
Disp1Char(i+8,0,dis[i]);
DispStr(0,11,".");
Disp1Char(12,0,dis[3]);
Disp1Char(13,0,0x43);
Disp1Char(14,0,0x4d);
DispStr(1,0,"SET TO:");
break;
}
case 1: {LcdWriteCommand(0x01, 1);DispStr(0,0,"SET THE LEVEL");Disp1Char(15,1,0x3e);break;}
//case 0: {LcdWriteCommand(0x01, 1);DispStr(0,0,"TIME")break;}
}
break;
}
case 2:
{
switch(ck)
{
case 1 :
{
LcdWriteCommand(0x01, 1); //清平
DispStr(0,0,"TEMPERA.:");
for(int i=1;i<3;i++)
Disp1Char(i+9,0,tp[i]);
Disp1Char(12,0,0x2e);
Disp1Char(13,0,tp[3]);
Disp1Char(14,0,tp[4]);
Disp1Char(15,0,0x43);
DispStr(1,3,"HEAT?");
Disp1Char(0,1,0x3c);
Disp1Char(15,1,0x3e);break;
}
case 2:
{ LcdWriteCommand(0x01, 1); //清平
DispStr(0,3,"HEATING....");break;}
}
break;
}
case 3:
{
switch(ck)
{
case 1:{LcdWriteCommand(0x01, 1); DispStr(0,0,"SET THE ALARM"); Disp1Char(0,1,0x3c);break;}
case 2:{LcdWriteCommand(0x01, 1);DispStr(0,0,"UP :");DispStr(1,0,"DOWN:");break;}
}
}
break;
}
//////////////all over///////////////////////////////
Delay();
Delay();
Delay();
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////模块化编程 被调用的 子程序//////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
long float count(float x,float y) //计算 时间 和 距离
{
long float times,distance ;
times=((y-x)/0x400);
times=(times/(0x400));
distance = ((times)*170);
return distance;
}
void tigger()
{
P1DIR|=BIT0;//p1.0为输出
P1OUT&=~0x01;//输出0;
P1OUT|=0x01;
Delay();
//Delay();
P1OUT&=~0x01;//输出0;
}
void Delay(void)//大约5ms的延时
{
for (int i=0;i< 4000;i++);
}
void convert_sonic(void)
{
dis_mm=1000*dis_; //分离 各个位
dis[0]=((dis_mm/1000)+0x30);
dis[1]=((dis_mm/100)%10+0x30);
dis[2]=((dis_mm/10)%10+0x30);
dis[3]=((dis_mm%10)+0x30);}
void convert_temp(void)
{ tep=Temper*100;
tp[0]=(((tep)/10000)+0x30);
tp[1]=((tep)/1000)%10+0x30;
tp[2]=((tep)/100)%10+0x30;
tp[3]=(tep/10)%10+0x30;
tp[4]=(tep)%10+0x30;}
//////////////////////////////////////////////////////////////////////////////
//////////////////////// the key interrupt ///////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#pragma vector=PORT2_VECTOR
__interrupt void Port2()
{ //int tab=P2IN;
// int k=0;
//k=P2IFG&0x0f;
switch(P2IFG&0x0F)
{case 0x01:if((P2IFG&0x0F)==0x01)
{ Delay5ms();
Delay5ms();
Delay5ms();
if((P2IFG&0x0F)==0x01)
{ //while(tab!=0x0f);
jian=1;
if(ojian==0) ojian=1; // 修正连续安两下 SET的 错误。
ck++;
P2IFG=0;
break;}}
case 0x02:if((P2IFG&0x0F)==0x02)
{ Delay5ms();
Delay5ms();
Delay5ms();
if((P2IFG&0x0F)==0x02)
{ //while(tab!=0x0f);
jian=0; ck=0;
P2IFG=0;
break;}}
case 0x04:if((P2IFG&0x0F)==0x04)
{Delay5ms();
Delay5ms();
Delay5ms();
if((P2IFG&0x0F)==0x04)
{ //while(tab!=0x0f);
if (ck!=0) // 不允许 空按 上下键;
{if(jian!=3) {jian++; ojian=jian;}
else jian=1;
//jian=2;
P2IFG=0;}
else jian=0;
break;}
}
case 0x08: if((P2IFG&0x0F)==0x08)
{ Delay5ms();
Delay5ms();
Delay5ms();
if((P2IFG&0x0F)==0x08)
{ //while(tab!=0x0f);
if(ck!=0)
{if(jian!=1) {jian--; ojian=jian;}
else jian=3;}
else jian =0;
//jian=3;
P2IFG=0;}}
// default:
// DispStr(5,0,"TIANCAI");
//break;
}
P2IFG=0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -