一、温度处理模块程序:
我们采用模块化编程风格,有利于管理项目工程,也更容易查找BUG,大家千万要形成一个好的代码风格,不要一个main.c文件从头写到尾,各种函数都在main.c里面,这样让人看起来烟花缭乱,程序出现BUG也不利于分析问题。因此,最好是每个模块建立一个.c文件和一个.h文件,这样其他模块通过调用该模块的头文件即可。建议大家有空多看看代码风格方面的帖子,会对大家有个好的帮助的。好了,废话不多说,进入正题吧。
1、首先,我们建立一个temperature.h和一个temperature.c文件,将temperature.c文件添加到项目keil工程,并且在temperature.c文件中包含temperature.h文件;
2、其次,由于我们这个模块是个温度处理模块,因此我们需要定义如下三个模块,以便其他模块使用本模块的变量。所以需要在temperature.c文件中定义如下三个变量;
u16 current_temperature = 0;//用来保存当前温度值
u16 current_AD = 0;//当前温度值对应的NTC的AD值
u16 next_temperature = 0;//上一次采样温度
定义了如上三个变量以后,我们需要在temperature.h文件中声明如上三个变量为外部变量,只有这样,其他模块才能使用temperature.c文件里面定义的变量,因此需要在temperature.h文件中增加如下三行代码。
extern u16 current_temperature;
extern u16 current_AD;
extern u16 next_temperature;
以上三个变量就是本模块定义的全局外部变量,剩下的一些其他变量就是本模块的静态变量了,只供本模块使用,接下来的工作就是要编写程序,将采集到的值赋值给以上三个全局外部变量了。
u16 code tab_AD_to_temperature[] = {
1938,2052,2172,2298,2430,2568,2673,2782,2894,3009, //0 - 9
3128,3273,3424,3580,3742,3909,4084,4265,4452,4645, //10 - 19
4845,5053,5267,5489,5717,5952,6193,6441,6696,6958, //20 - 29
7227,7509,7799,8096,8401,8714,9030,9355,9687,10026, //30 - 39
10373,10733,11100,11475,11858,12248,12650,13060,13477,13902, //40 - 49
14276,14770,15213,15663,16119,16582,17049,17522,18000,18483, //50 - 59
18971,19459,19951,20447,20947,21450,21963,22479,22998,23519, //60 - 69
24042,24557,25074,25592,26110,26629,27176,27724,28270,28817, //70 - 79
29362,29898,30432,30966,31496,32025,32552,33076,33596,34114, //80 - 89
34629,35146,35658,36168,36672,37173,37656,38133,38607,39075, //90 - 99
39539,40012,40479,40942,41397,41849,42289,42722,43150,43572, //100 - 109
43987,44401,44808,45210,45603,45990,46371,46748,47114,47480, //110 - 119
47833,48195,48552,48900,49242,49577,49909,50231,50548,50858, //120 - 129
51164,51441,51713,51984,52245,52504,52754,53001,53247,53486, //130 - 139
53718,53957,54193,54423,54650,54869,55086,55300,55506,55709, //140 - 149
55909 //150
};
有了上表,就可以通过查表的方式,得到当前的奶温温度了。
/***************************************************************************************
名 称:process_temperature
功 能:温度进程
参 数:无
返 回:无
***************************************************************************************/
void process_temperature(void)
{
//以下变量全部为本函数的静态变量
static u8 process_temperature_statu = 0;//进程状态
static u32 ADC_sum = 0;//ADC总和
static u8 ADC_count = 0;//ADC采集次数
static u16 AD_max = 0;//AD最大值
static u16 AD_min = 0;//AD最小值
u8 i;
u16 tmp = 0;
switch (process_temperature_statu){
case 0:
tmp = get_ADC_val(ADC_CH_7);//获取NTC通道AD值
if (!ADC_count){//如果ADC_count为0,则把第一次的值作为最大最小值
AD_max = tmp;
AD_min = tmp;
}else{//反之处理最大最小值
if (tmp > AD_max){//如果当前值大于上一次值,则更新最大值变量
AD_max = tmp;
}
if (tmp < AD_min){//如果当前值小于上一次值,则更新最小值变量
AD_min = tmp;
}
}
ADC_sum += tmp;//计算采集AD值总和
ADC_count++;//采集次数自加
if (ADC_count >= 66){//总共采集66次,去掉最大值最小值,计算平均值作//为本次AD值,根据AD值计算当前温度
ADC_sum -= AD_max;//减去最大值
ADC_sum -= AD_min;//减去最小值
tmp = ADC_sum;
current_AD = tmp / (66 - 2);//计算平均值为当前//AD值
process_temperature_statu = 1;//跳转到状态1处理其他工作
}
break;
case 1:
tmp = ADC_sum;//将64次AD值付给tmp
for (i = 0; i < TAB_TEMPERATURE_NUMBER; i++){//for循环查表,看看当前//AD值的64倍在哪个范围
if((tmp>=tab_AD_to_temperature)&&(tmp< tab_AD_to_temperature[i + 1])){
current_temperature = i * 10;//满足if条件,当前温度为i度,并//扩大10倍
current_temperature += (((tmp - tab_AD_to_temperature) * 10) / (tab_AD_to_temperature[i + 1] - tab_AD_to_temperature));
}
}
if (tmp < tab_AD_to_temperature[0]){
current_temperature = 0;
}
if (tmp >= tab_AD_to_temperature[TAB_TEMPERATURE_NUMBER]){
current_temperature = TAB_TEMPERATURE_NUMBER * (u16)10;
}
ADC_sum = 0;
ADC_count = 0;
process_temperature_statu = 0;//处理完成返回状态0重新采集温度
break;
default:
process_temperature_statu = 0;
break;
}
}
二、NTC故障处理部分代码:
由于功能规格书里面要求有NTC故障检测功能,因此我们还需要编写NTC故障报警处理程序。所以我们要新建check_self.h和check_self.c文件作为故障处理模块。由于要记录各种系统故障,所以我们需要在check_self.c文件中定义如下变量:
u8 error_num = 0;//错误代码变量;0:正常;1:NTC故障;2:干烧故障;3:初始//奶温过高故障。
由于error_num变量需要供外部模块调用,因此需要在check_self.h头文件中声明为外部变量,方法和温度处理模块一样。
下面直接贴出NTC故障报警处理代码:
/***************************************************************************************
名 称:check_NTC
功 能:检查NTC
参 数:无
返 回:无
***************************************************************************************/
void check_NTC(void)
{
static u8 process_check_NTC_statu = 0;//静态变量,NTC故障处理状态变量
static u16 process_check_NTC_count = 0;//计时变量
process_check_NTC_count++;//计时变量自加,2ms自加一次
switch (process_check_NTC_statu){
case 0:
if (process_check_NTC_count >= 68){//延时,确保//AD采集完成
process_check_NTC_count = 0;
process_check_NTC_statu = 1;//跳到状态1处理
}
break;
case 1:
if (current_AD <= 3 || current_AD >= 1021){//NTC开路或者短路故障检测,//当前AD值小于4或者大于1020,则判断NTC故障
set_standy_statu();//恢复所有变量为初始值
error_num = 1;
PIN_LED_BUBBLE_BLUE = 0;//蓝灯亮
PIN_LED_BUBBLE_RED = 1;//红灯灭
process_check_NTC_count = 0;
process_check_NTC_statu = 2;//跳到状态2处理
}
break;
case 2://只有断电才能恢复process_check_NTC_statu为0
if (process_check_NTC_count >= 250){//执行NTC故障报警,500ms翻 //转LED状态
PIN_LED_BUBBLE_RED = !PIN_LED_BUBBLE_RED;
PIN_LED_BUBBLE_BLUE = !PIN_LED_BUBBLE_BLUE;
process_check_NTC_count = 0;//清楚计时变量
}
break;
default:
break;
}
}
好了,相信大家看完源代码已经清楚了NTC采集温度的处理方法了,是不是觉得很简单啊。采集到了实际奶温后,上面的逻辑控制,温度控制程序就比较好写了。大家有没有注意到使用switch-case语句编程很简单啊,这就是传说中所谓的状态机编程,状态机就是把一个任务切割成一个一个小的部分处理,小的处理完成了,综合起来就变成完整的功能了,而且使用状态机编程,程序结构清晰明了,容易找BUG。下一讲我会讲按键逻辑部分代码,希望大家喜欢。
由于这里面不太好编辑文档,大家可以下载附件阅读。
文章评论(0条评论)
登录后参与讨论