📄 温度测量.c
字号:
#include <msp430x41x.h>
#include "main.h" //自己定义的必要的结构和变量
void delay(INT16U dd);
//以下为初始化函数
void initial_port(void);//初始化端口
void AD_sampling(INT16U * AD_temp);
float calc_Temperature(float R);
INT8U long2dec(INT32U d, INT32U * p);
//以下为显示函数
void display_LCD_all_on(void);//点亮所有LCD段
void display_LCD_all_off(void);//熄灭所有LCD段
void display_INT32U(INT32U temp);
void display_flag_clear(void);//为了节约空间而用
void display_float(float QQ, INT8U pos);
//以下为主程序逻辑函数
void monitor_key(void);//对按键进行监控
void monitor_time(void);//对时间进行监控
void monitor_AD(void);//对AD采样进行监控
void monitor_display(void);
static struct BIT16_flag common_flag1={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#define is_one_second common_flag1.b0
#define is_display_now common_flag1.b1
#define is_k1_key_ok common_flag1.b2
#define is_AD_sample_time common_flag1.b5
#define is_start_measure_R common_flag1.b6 //AD测量
static struct BIT16_flag display_flag1={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
#define is_display_temperature_in display_flag1.b2
#define is_display_temperature_out display_flag1.b3
#define is_display_INT32U display_flag1.b10
INT8U start_measure_status=0;
INT8U one_second=0, k1_key_page=0;
INT16U AD_sample_time=0;
INT8U LCD_buf[9], test=0;//LCD 缓存
INT16U N_Pt_IN[2], N_Pt_OUT[2], N_ref, temp_t=0;//存放采样值
//以下要保存
float T1, T2, T1_adjust_coefficient=0, T2_adjust_coefficient=0; //进水温度,出水温度
//主函数
void main(void)
{
initial_port();
_EINT();
display_LCD_all_off();
while(1){
monitor_time();
monitor_key();
monitor_AD();
monitor_display();
LPM3;
}
}
void display_flag_clear(void)
{
INT16U * ptr_INT16U;
ptr_INT16U = (INT16U*) &display_flag1;
*ptr_INT16U = 0;
display_LCD_all_off();
is_display_now=1;
}
//功能:按键
//描述:无
//参数:无
//返回:无
void monitor_key(void)
{
if(is_k1_key_ok)
{
is_k1_key_ok=0;
///////////////////////////////////////////////////////////////
switch(k1_key_page)
{
case 0:
//显示进水温度 (°C)
display_flag_clear();
is_display_temperature_in=1;
break;
case 1:
//显示出水温度(°C)
display_flag_clear();
is_display_temperature_out=1;
break;
default:
break;
}
k1_key_page++; k1_key_page%=2;
}
}
void monitor_display(void)
{
if(is_display_temperature_in)
{
display_float(T1,2);
}
if(is_display_temperature_out)
{
display_float(T2,2);
}
if(is_display_INT32U)
{
display_INT32U((INT32U)temp_t);
}
}
//功能:时间处理程序
//描述:无
//参数:无
//返回:无
void monitor_time(void){
if(is_one_second)//一秒钟到了
{
is_one_second=0;
AD_sample_time++;
if(AD_sample_time>=5) //10秒
{
AD_sample_time=0;
is_AD_sample_time=1;
}
}
}
//功能:AD处理
//描述:无
//参数:无
//返回:无
void monitor_AD(void)
{
if(is_AD_sample_time)//测量时间到了
{
is_AD_sample_time = 0;
is_start_measure_R = 1; //启动测量程序
}
if(is_start_measure_R)
{
switch(start_measure_status)
{
case 0: //测量标准电阻
delay(30000);
P6OUT |= (BIT0+BIT2+BIT3);//P6.0=1, 打开4051
//P6.1=0, P6.2=1, P6.3=1选择精密电阻
P6OUT &= ~BIT1;
AD_sampling(&N_ref);
start_measure_status++;
break;
case 1: //测量Pt_IN
delay(50000);
P6OUT |= (BIT0+BIT1+BIT3);//P6.0=1, 打开4051
//P6.1=1, P6.2=0, P6.3=1选择Pt_IN
P6OUT &= ~BIT2;
AD_sampling(&N_Pt_IN[0]);
start_measure_status++;
break;
case 2://测量Pt_OUT
delay(30000);
P6OUT |= (BIT0+BIT1+BIT2);//P6.4=1, 打开4051
//P6.1=1, P6.2=1, P6.3=0选择Pt_OUT
P6OUT &= ~BIT3;
AD_sampling(&N_Pt_OUT[0]);
start_measure_status++;
break;
case 3:
//以下为进水Pt, 取1k,1.4k两个点的值
N_Pt_IN[1] = N_Pt_IN[0]-N_ref;
//N_Pt_IN[1] -= 128;
T1 = 1000+400*((float)N_Pt_IN[1])/2021.1;
if((T1<=1600)&&(T1>=1000))//不能超过150°
{
T1 = calc_Temperature(T1);
if(T1>T1_adjust_coefficient) T1=T1-T1_adjust_coefficient; //此处进行微调
else T1=0;
}
else
{
T1=0;
}
//以下为出水Pt,取1k,1.4k两个点的值
N_Pt_OUT[1] = N_Pt_OUT[0]-N_ref;
//N_Pt_OUT[1]-= 181;//调试时需要注释掉
T2 = 1000+400*((float)N_Pt_OUT[1])/2031.1;
if((T2<=1600)&&(T2>=1000))//不能超过150°
{
T2 = calc_Temperature(T2);
if(T2>T2_adjust_coefficient) T2 = T2-T2_adjust_coefficient;//此处进行微调
else T2=0;
}
else
{
T2=0;
}
//++++++++++以下调试用+++++++++++++
#if 1 //校准时需要为1,校准完后改为0
display_flag_clear();
temp_t = N_Pt_IN[1];//选择其中一个
//temp_t = N_Pt_OUT[1];
is_display_INT32U=1;
#endif
start_measure_status=0;
is_start_measure_R=0;
break;
default:
break;
}
}
}
//显示0~65535的数字
void display_INT32U(INT32U t)
{
INT32U temp=0;
INT8U i=0, len;
len = long2dec(t, &temp);
for(i=0;i<len;i++)
{
LCD_buf[7-i] = (temp&0x0000000f);
temp>>=4;
}
for(i=0;i<(7-len);i++)
{
LCD_buf[i]=16;
}
}
void display_float(float QQ, INT8U pos)//显示pos=2,3,4位小数点
{
INT32U temp=0, temp2=0;
INT8U i=0, len;
INT8U pp=2;
pp= pos;
if(pos==2)
{
temp2 = (INT32U) (QQ*100);
if(QQ>=0.01) goto display_1;
else goto display_2;
}
if(pos==3)
{
temp2 = (INT32U) (QQ*1000);
if(QQ>=0.001) goto display_1;
else goto display_2;
}
if(pos==4)
{
temp2 = (INT32U) (QQ*10000);
if(QQ>=0.0001) goto display_1;
else goto display_2;
}
if(pos==5)
{
temp2 = (INT32U) (QQ*100000);
if(QQ>=0.00001) goto display_1;
else goto display_2;
}
display_1:
len = long2dec(temp2, &temp);
if(len<=pp)//处理小数点
{
for(i=0;i<len;i++)
{
LCD_buf[7-i] = (temp&0x0000000f);
temp>>=4;
}
for(i=0;i<=pp-len;i++)
{
LCD_buf[7-pp+i] = 0;
}
for(i=0;i<=6-pp;i++)
{
LCD_buf[i]=16;
}
}
else
{
for(i=0;i<len;i++)
{
LCD_buf[7-i] = (temp&0x0000000f);
temp>>=4;
}
for(i=0;i<(7-len);i++)
{
LCD_buf[i]=16;
}
}
goto display_3;
display_2:
//显示0
for(i=0;i<=6;i++)
{
LCD_buf[i] = 16;
}
LCD_buf[7] =0;
display_3:
_NOP();
}
//功能:点亮所有LCD段
//描述:无
//参数:无
//返回:无
void display_LCD_all_on(void)
{
INT8U i;
for(i=0;i<=9;i++){//全部点亮LCD段
LCD_buf[i] = 18;
LCDMEM[i] |= 0xff;
}
}
//功能:熄灭所有LCD段
//描述:无
//参数:无
//返回:无
void display_LCD_all_off(void)
{
INT8U i;
for(i=0;i<=9;i++){//全部熄灭LCD段
LCDMEM[i] = 0;
LCD_buf[i] = 16;
}
}
//功能:初始化有关端口
//描述:对有关端口进行设置
//参数:无
//返回:无
void initial_port(void){
//以下为看门狗定义
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
//以下为口定义
P1DIR |= BIT3;//rf power
P1OUT &= ~BIT3;
P1IES |= (BIT4+BIT5);//P1.4-RF干簧管,P1.5-限位开关,下降沿触发
P1IE |= (BIT4+BIT5);
P2IES |= (BIT0+BIT1+BIT2+BIT5);//P2.2-按键, P2.5-校准键, P2.0,P2.1-流量
P2IE |= (BIT0+BIT1+BIT2+BIT5);
P2DIR &= ~BIT4; //P2.4--输入, 电压检测, 电压低则引脚为低,平常为高
BTCTL = BTFRFQ0 + BTSSEL+BTDIV +BTIP1; //每1秒中断16次,只作为时钟用
IE2 |= BTIE; // Enable BT interrupt
LCDCTL = LCDON + LCD4MUX + LCDSG0_2; // STK LCD 4Mux, S0-S19
P6DIR |= (BIT0+BIT1+BIT2+BIT3+BIT4+BIT6+BIT7);//P6.0,...,P6.3输出--温度测量
P6OUT &= ~(BIT0+BIT1+BIT2+BIT3+BIT4+BIT6+BIT7);//P6.6,P6.7-电机
//TACTL = TASSEL0 + TACLR;// + ID0; //SMCLK, TAR = 0 , 二分频
//TACTL |= MC1; //连续计数, start
//CCTL0 |= CCIE; //CCR0 interrupt
P2SEL |= (BIT6+BIT7);
P3SEL =0xff;
P4SEL =0xff;
P5SEL =0xff;
}
#pragma vector=BASICTIMER_VECTOR
__interrupt void INT_timer_basic(void)
{
INT8U i;
one_second++;
if(one_second>=16){
one_second=0;
is_one_second=1;
}
for(i=0;i<8;i++){
LCDMEM[i] = digit[LCD_buf[i]];//只管显示数字
}
if(is_display_temperature_in)
{
LCDMEM[8] |= P8;//显示进水符号
LCDMEM[9] |= S1;//显示温度符号
if(T1>=0.01) point2; //显示小数点
}
if(is_display_temperature_out)
{
LCDMEM[8] |= P10;//显示出水符号
LCDMEM[9] |= S1;//显示温度符号
if(T2>=0.01) point2; //显示小数点
}
if(is_display_now){
is_display_now=0;
LCDCTL |= LCDON;
}
LPM3_EXIT;
}
#pragma vector=PORT2_VECTOR
__interrupt void INT_port2(void){
if(P2IFG & BIT2) {//键
is_k1_key_ok=1; //键按下
}
P2IFG=0;
LPM3_EXIT;
}
void delay(INT16U dd)
{
INT16U i;
for(i=0;i<dd;i++) _NOP();
}
void AD_sampling(INT16U * AD_temp)
{
INT32U AD_counter=30000;
INT32U AD_value=0;
INT32U i;
CACTL2 = P2CA0 + P2CA1+CAF;
CACTL1 |= CAON;
P2DIR |= BIT3;
P2OUT |= BIT3;//P2.3=1, 电容预充电
AD_value=0;
while(CAOUT & CACTL2==0);//等待比较器翻转
_DINT();
for(i=0;i<AD_counter;i++)
{
if((CAOUT&CACTL2)==CAOUT) //CAOUT =1
{
P2OUT &= ~BIT3;//电容放电
}
else
{
P2OUT |= BIT3;//电容充电
AD_value++;
}
}
*AD_temp = AD_value;
CACTL1 &= ~CAON;//关掉比较器
P6OUT &= ~(BIT0+BIT1+BIT2+BIT3);//P6.4=0, 关掉4051
P2OUT &= ~BIT3;//电容放电
_EINT();
//选择线全部无
}
//功能:计算温度值
//描述:由电阻计算对应的温度值
//参数:电阻值,(1000欧姆为0°C)参数范围1000~1454.072
//返回:温度值(°C),若有错则返回-1
float calc_Temperature(float R){
float T;
if((R>=1000)&&(R<=1229.388)){//0~60°C
T = -247.1918 + 0.23551 * R+1.1687e-005*R*R;
return T;
}
else if((R>1229.388)&&(R<=1454.072)){//60~120°C
T = -246.0572 + 0.23366 * R+1.2436e-005*R*R;
return T;
}
else{//出错
return -1;
}
}
//32位无符号转换为BCD码,如:0xbc614e(12345678)->0x12345678
//返回字符数
INT8U long2dec(INT32U d, INT32U * p) {
INT8U i=0, len=0;
INT32U temp=0;
do {
temp<<=4;
temp |= (INT32U) (d % 10);
d= d / 10;
len++;
} while(d!=0);
(*p) =0;
for(i=0;i<len;i++)
{
(*p) <<=4;
(*p) |= (temp&0x0000000f);
temp >>=4;
}
return len;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -