系统概述
STM32F103VET6模拟家用热水器,使用了DS18B20、lcd12864、蜂鸣器、直流电机、按键、小灯模块,除检测温度外,该系统在温度低于设定温度(系统初始设置50摄氏度)时电机旋转并且温度越低转速越快、核心板上的小灯按照特定规律(先由led0到led15逐个点亮再反向逐个熄灭再正向单个点亮)点亮;温度低于20度时增加蜂鸣器报警功能;独立按键可以调节用户设定温度大小。
流程图
主函数main.c
#include "STM32F103_Config.h"
#include "delay.h"
#include "ds18b20.h"
#include "lcd.h"
#include "stdio.h"
#define KEY0_PRES 3
#define KEY1_PRES 3
int main()
{
short temp;
int a=50;
int count=0,sum=0;
u8 key;
u8 temperatureh,temperaturel;
char str_data[2];
int j=0;//LED
GPIOE->BSRR=0xffff;//LED
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
Led_Init();
Delay_init();
Lcd_Init();
DS18B20_Init();
beep_Init();
Key_Init();
CH451_Init();
//uart
RCC_Configuration();
GPIO_Configuration();
USART_Configuration();
//pwm
TIM1_PWM_Init(719, 99); //pwm初始化 频率=72*10^6/(719+1)/(99+1)=1KHz,设定在1KHz
while (1)
{
//DS18B20
temp = DS18B20_Get_Temp();
//调整设定温度
if(Key0_Scan()==KEY0_PRES) {a++;count++;}
if(Key1_Scan()==KEY1_PRES) {a--;sum++;}
DisStr(2, 0, "加次数:");DisInt(2, 5, count);
DisStr(3, 0, "减次数:");DisInt(3, 5, sum);
//lcd
DisStr(0, 0, "水温");
DisStr(1, 0, "设定温度:");
DisInt(1, 5, a);
DisStr(1,7,"℃");
if(temp<0)
{
temp=-temp;
DisStr(0,2,":-"); //显示负号
}else DisStr(0,2,": "); //去掉负号
temperatureh=temp/10;
temperaturel=temp%10;
DisInt(0,3,temperatureh); //显示温度整数部分
sprintf(str_data,"%s%1d",".",temperaturel);
DisStr(0,4,str_data);
DisStr(0,6,"℃");
Delay_ms(1000);
//上位机
if(temp<0)
{
printf("-"); //显示负号
}else printf(" ");
printf("\n%d",temperatureh);
printf(".");
printf("%d\n",temperaturel);
Delay_ms(600);
if(temperatureh<a)
{
//led
for(j=0;j<=15;j++)//正向逐个点亮
{
GPIOE->BRR=(0x0001<<j);
Delay_ms(100);
}
for(j=0;j<=15;j++)//逆向逐个熄灭
{
GPIOE->BSRR=(0x8000>>j);
Delay_ms(100);
}
for(j=0;j<15;j++)//正向单个点亮
{
GPIOE->BSRR=(0x00020001<<j);
Delay_ms(100);
}
//电机
TIM_SetCompare1(TIM1, temp+719-500); //调节占空比,考虑电机驱动散热问题,长时间运行建议占空比最大不要超过20%;第二个数范围0-719
}
//蜂鸣器
if(temperatureh<20)
beep_alarm();
}
}
delay.c
#include "delay.h"
static u8 fac_us = 0; //us延时倍乘数
static u16 fac_ms = 0; //ms延时倍乘数
void Delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us = SystemCoreClock / 8000000; //为系统时钟的1/8
fac_ms = (u16)fac_us * 1000; //每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数.
void Delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD = nus*fac_us; //时间加载
SysTick->VAL = 0x00; //清空计数器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开始倒数
do
{
temp = SysTick->CTRL;
} while ((temp & 0x01) && !(temp&(1 << 16)))
; //等待时间到达
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL = 0X00; //清空计数器
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=