实验要求:
(1)过程中反馈的数据需要反馈到串口助手上面来——完成
(2)散热方式为舵机往复360度旋转、散热模式选择(低速(25,27]、中速[28,30]、高速(30,+00)根据异常温度的区间来变化旋转速度)——完成
(3)OLED界面展示:
主界面实时显示温度,并显示:温度正常、风扇工作状态、风扇的转速。——完成
实验知识点要求:
(1)掌握串口收发的使用(特别是汉字的打印、数据换行、sprintf的使用)
(2)PWM:工作原理与调试
这里对定时器的初始化需要:T = 20ms
(3) ds18b20温度传感器的使用
(4)SG90舵机的使用
舵机的控制就是通过一个固定的频率,给其不同的占空比的,来控制舵机不同的转角
舵机的频率一般为频率为50HZ,也就是一个20ms左右的时基脉冲,而脉冲的高电平部分一般为0.5ms-2.5ms范围。来控制舵机不同的转角
500-2500us的PWM高电平部分对应控制180度舵机的0-180度
以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
(所有的驱动江科协都有提供)
main.c:
#include "stm32f10x.h"
#include "GPIO.H"
#include "Delay.h"
#include "Serial.h"
#include "TIMer.h"
#include "OLED.H"
#include "ds18b20.h"
/*
以温度区间为条件的自动散热系统
要求:
(1)过程中反馈的数据需要反馈到串口助手上面来——完成
(2)散热方式为舵机往复360度旋转、散热模式选择(低速(25,27]、中速[28,30]、高速(30,+00)根据异常温度的区间来变化旋转速度)
(3)OLED界面展示:
主界面实时显示温度,并显示:温度正常、风扇工作状态、风扇的转速。——完成
*/
/*
初始化函数
*/
void all_init(void)
{
gpio_init();
PWM_Init();
Serial_Init();
OLED_Init();
}
/*=====================================*/
/*
反馈
*/
char *strNormal = "温度正常\r\n";
char *strAbnormal = "温度异常\r\n";
char *works = "开始降温\r\n";
char *working = "降温中...\r\n";
char *worked = "降温完毕\r\n";
char *strover = "降温完毕\r\n";
int wrok_Statu = 0; //工作状态标志位
int work_v = 0; //工作速度标志位
int send_chinese(int x)
{
if (x == 0)
{
Serial_SendString(strNormal);
}
else
{
Serial_SendString(strAbnormal);
}
}
int led(int x)
{
if (x == 0)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
}
else
{
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
}
/*=====================================*/
/*=====================================*/
/*
温度采集与现象处理
*/
float temperature;
int temp(void)
{
DS18B20_Start();
Delay_ms(750);
temperature = DS18B20_Get_Temp(); // 温度精度为00.0,例如:200代表温度 20
return DS18B20_Get_Temp();
}
int work(uint8_t x)
{
switch (x)
{
case 0:
send_chinese(0); //温度正常
break;
case 1:
Serial_SendString(working);
for(int CCR = 5 ;CCR < 25; CCR++)
{
TIM_SetCompare1(TIM8,CCR);
Delay_ms(500);
TIM_SetCompare1(TIM8,CCR);
Delay_ms(500);
}
break;
case 2:
Serial_SendString(working);
for(int CCR = 5 ;CCR < 25; CCR++)
{
TIM_SetCompare1(TIM8,CCR);
Delay_ms(250);
TIM_SetCompare1(TIM8,CCR);
Delay_ms(250);
}
break;
case 3:
Serial_SendString(working);
for(int CCR = 5 ;CCR < 25; CCR++)
{
TIM_SetCompare1(TIM8,CCR);
Delay_ms(200);
TIM_SetCompare1(TIM8,CCR);
Delay_ms(200);
}
break;
}
}
/*=====================================*/
/*=====================================*/
/*
OLED界面显示
*/
int OLED_show(int s,int v)
{
OLED_ShowString(1, 1, "temp:");
OLED_ShowNum(1, 6, temperature/10, 3);
OLED_ShowString(2, 1, "Statu:");
switch(s)
{
case 1:
OLED_ShowString(2, 8, "NO ");
break;
case 2:
OLED_ShowString(2, 8, "YES");
break;
}
Delay_ms(100);
OLED_ShowString(3, 1, "V:");
switch(v)
{
case 0:
OLED_ShowString(3, 3, " No speep");
break;
case 1:
OLED_ShowString(3, 3, "low speep");
break;
case 2:
OLED_ShowString(3, 3, "Medium speed");
break;
case 3:
OLED_ShowString(3, 3, "high speep");
break;
}
}
/*=====================================*/
int main(void)
{
all_init();
char buffer[32];
temperature = temp();
OLED_show(1,0);
while(1)
{
led(1);//正常状态显示
temp() ; // 开始读取温度
Delay_us(100);
sprintf(buffer, "当前温度: %.2f摄氏度\r\n", temperature/10);
Serial_SendString(buffer); // 发送温度信息
Delay_ms(500);
if(temperature<=250)
{
//send_chinese(0); //发送信息提醒
sprintf(buffer, "当前温度: %.2f摄氏度\r\n", temperature/10);
Serial_SendString(buffer); // 发送温度信息
work(0);
}
else
{
send_chinese(1); //发送信息提醒
OLED_show(2,1);
Delay_ms(500);
Serial_SendString(works); //发送开始工作信息
if(temperature>25&&temperature<=27) //低速
{
work(1);
OLED_show(2,1);
}
else if(temperature>=28&&temperature<=30) //中速
{
work(2);
OLED_show(2,2);
}
else if(temperature>30) //高速
{
work(3);
OLED_show(2,3);
}
Delay_ms(3000);
//降温过后的温度
Serial_SendString(worked);
sprintf(buffer, "当前温度: %.2f摄氏度\r\n", temperature/10);
Delay_ms(100);
OLED_show(0,0);
}
Delay_s(1);
}
}
现象:
自动降温系统演示视频-1
自动降温系统演示视频-2