前言
本次增加功能:
通过一个按钮,可设置选择三种风扇温度阈值
一、基于18B20的温度控制板新增功能的方案介绍
1、利用了GD32F330的外部中断功能,下降沿触发,在中断程序中累加计数;
2、外中断的累加计数更新显示内容,同时更新风扇温度阈值;
3、风扇阈值预设三个,35℃、40℃和45℃,每次按动按键后,显示器都会在“当前温度->阈值35℃->阈值40℃->->阈值45℃“循环切换;
4、显示的同时,改变风扇启动阈值;
5、定时中断优先级高于外中断优先级;
6、电路板原理图详见:18B20温度控制板电路板原理图
7、程序下载:程序项目源代码
功能演示如下:
18b20温度控制板增加按键选择温度功能
二、关键程序介绍
1.主函数
int main(void)
{ /* initialize KEY and LED, configure SysTick */
gd_eval_key_init(KEY_USER, KEY_MODE_EXTI);
systick_config();
delay_init(72);
/* enable the LED GPIO clock */
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
/* led 和风扇输出 GPIO 初始化 */
gpio_mode_set(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
gpio_bit_reset(GPIOA, GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
gpio_bit_reset(GPIOB, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12);
ds18b20_get_temperature();
ds18b20_get_temperature();
timer2_init(1200 - 1, 500 - 1);
while(1) {
delay_us(2);
/* ① 10ms刷新一次LED:
定时器2中断10ms,在中断中FlagLed被置位;
然后执行 ShowLED( TenPlace, OnePlace , dip, LedEn)
使能LedEn常为1,常亮;
*/
if(FlagLed == 1) //① 10ms刷新一次LED
{
FlagLed = 0;
ShowLED( TenPlace, OnePlace , dip, LedEn);
}
/* ② 每间隔1s更新一次温度:
ds18b20_get_temperature();在进入主函数前先执行两次了,因为第一次会得到85℃的结果
这个数据会影响风扇的开启判断;
TempInteger就是当前温度,与阈值温度 SetingTemp比较,高于阈值开启风扇,设置回差5℃
*/
if(FlagGetTemp == 1)
{
FlagGetTemp = 0;
CurrentTemp = ds18b20_get_temperature();
TempInteger = CurrentTemp / 10;//去掉小数点后面的数
//更新温度同时,对温度数据判断,决定是否启停风扇
if(TempInteger > SetingTemp)
{
gpio_bit_write(GPIOB, GPIO_PIN_12, SET);
//若超过设定阈值,就启动该风扇
}
else if (TempInteger < SetingTemp - 5 )
{
gpio_bit_write(GPIOB, GPIO_PIN_12, RESET);
//通过降温,待温度回到低于阈值5℃时,停止风扇
}
}
/* ③ 每次按键,更换一次显示内容,顺序是:
* 当前温度->阈值35℃->阈值40℃->->阈值45℃->当前温度
* 按键次数KeyCount在外中断程序里更新 ,即0—>1—>2—>3—>0循环
* 在新的阈值显示界面停留3秒后,更新阈值温度,并且回到当前温度显示
* 阈值显示加小数点,当前温度显示没有小数点,以便区分
*/
if (KeyCount == 0)
{
TenPlace = TempInteger / 10; //得到十位的数
OnePlace = TempInteger % 10; //得到个位的数
dip = 0;//显示阈值时候,加点,表示区分
}
else if (KeyCount == 1)
{
SetingTemp = SetingTemp35;
TenPlace = SetingTemp35 / 10; //得到十位的数
OnePlace = SetingTemp35 % 10; //得到个位的数
dip = 1;//显示阈值时候,加点,表示区分
FlagKey = 1;//计时,显示3秒钟后恢复显示到当前温度
if (count300 == 1)
{
KeyCount = 0;count300=0;count=0; FlagKey = 0;
}
}
else if (KeyCount == 2)
{
SetingTemp = SetingTemp40;
TenPlace = SetingTemp40 / 10; //得到十位的数
OnePlace = SetingTemp40 % 10; //得到个位的数
dip = 1;//显示阈值时候,加点,表示区分
FlagKey = 1;//计时,显示3秒钟后恢复显示到当前温度
if (count300 == 1)
{
KeyCount = 0;count300=0;count=0; FlagKey = 0;
}
}
else if (KeyCount == 3)
{
SetingTemp = SetingTemp45;
TenPlace = SetingTemp45 / 10; //得到十位的数
OnePlace = SetingTemp45 % 10; //得到个位的数
dip = 1;//显示阈值时候,加点,表示区分
FlagKey = 1;//计时,显示3秒钟后恢复显示到当前温度
if (count300 == 1)
{
KeyCount = 0;count300=0;count=0; FlagKey = 0;
}
}
else break;
}
}
2.外中断程序
/*!
\brief this function handles external lines 4 to 15 interrupt request
\param[in] none
\param[out] none
\retval none
*/
extern uint8_t KeyCount;
void EXTI4_15_IRQHandler(void)
{
if(RESET != exti_interrupt_flag_get(EXTI_15))
{
count300 = 0;
count = 0;
if( KeyCount < 3)
{
KeyCount = KeyCount + 1;
}
else
{
KeyCount = 0;
}
}
exti_interrupt_flag_clear(EXTI_15);
}
3.定时器2中断函数
/* TIMER2 中断服务函数
* 参数:无
* 返回值:无
功能:中断定时10ms;产生各种标志,主程序查询标志位并处理
*/
extern uint8_t FlagGetTemp;
extern uint8_t FlagLed, FlagKey;
extern uint16_t count , count300;
void TIMER2_IRQHandler(void)
{
static uint8_t k = 0;
if(timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP))
{
/* 清除TIMER2 中断标志位 */
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
//① 10ms刷新一次数码管;
FlagLed = 1;//在此置标志位,在main中查询并做显示处理
//② 计数到3s时给出标志
if (FlagKey == 1)
{
while(++count == 300)
{
count = 0; count300 = 1;
}
}
//③ 1000ms读一次18b20
while(++k == 100)
{
k = 0; FlagGetTemp = 1;
}
}
}
总结
1、本次改变,增加了按键功能,并使用和了解了外中断资源;
2、完整的程序项目文件提供下载:程序项目源代码