标题:
基于stm32f103c8t6的温度检测程序-涂益豪
[打印本页]
作者:
涂益豪
时间:
2020-7-25 14:19
标题:
基于stm32f103c8t6的温度检测程序-涂益豪
一、实现的功能
1.OLED 屏幕显示温度变化和进行温度阈值设置;
2.不同的阈值对应不同的电风扇转速(电风扇烧坏了,电机没买,用舵机代替,转动不同的角度对应的占空比)
3.高于阈值风扇启动和蜂鸣器响,可以通过按键关闭这两个
二.矩阵键盘功能
1
2
3
重置阈值
4
5
6
关闭蜂鸣器
7
8
9
关闭风扇
确认
0
.
三、接线
舵机的pwm口接PB5;
蜂鸣器的I/O口接PB13;
矩阵键盘接PA0-PA7;
OLED 屏幕的SCL接PB10,SDA接PB11
四、演示的视频太大了,需要的私聊
单片机源程序如下:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "oled.h"
#include "myiic.h"
#include "stm32f10x.h"
#include "keyscan.h"
#include "stdio.h"
#include "stdlib.h"
#include <string.h>
#include "ds18b20.h"
#include "timer.h"
#define uchar unsigned char
#define uint unsigned int
uchar num,i,sign,j;
short temperature;
float temp_1,temp_2,temp_3;
uchar temp[16]; //最大输入16个
uchar flag_2,flag_buzz,flag_blow,flag_swt,flag_bit;
uchar tt,dd;
float a,m=0,n=0;
uchar w[16],t[16],d[16],h[16];
uchar s,c;
void set_temp(void);
void buzzer_init(void);
void blower_init(void);
void blower_opr(void);
int main(void)
{
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
TIM3_PWM_Init(1999,719); //PWM频率=72000000/(719+1)/(1999+1)=50hz=20mS
delay_init(72); //初始化延时函数
LED_Init(); //初始化LED端口
IIC_Init();
OLED_Init();
DS18B20_Init();
buzzer_init();
a=29;
/**下面是通过直接操作库函数的方式实现IO控制**/
while(1)
{
blower_opr();
temperature=DS18B20_Get_Temp();
temp_1= temperature/10;temp_2=temperature%10;
temp_3=temp_1+temp_2*0.1;sprintf((char *)d,"%g",temp_3);
tt++;dd++;
if(tt==10){
tt=0;
OLED_P8x16Str(80,0,(unsigned char*)d);
}
if(dd==6)
{if(flag_bit==0)flag_bit=1;
else if(flag_bit==1)flag_bit=0;
dd=0;
}
num=keyscan();
if((temp_3>=a)&&(flag_swt!=10)){ blower_init();}
else if((temp_3<a)){flag_blow=0;flag_swt=0;}
else if(flag_swt==10){flag_blow=0;}
if((temp_3>=a)&&(flag_buzz==0)){ GPIO_ResetBits(GPIOB, GPIO_Pin_13);}
else if((temp_3<a)){GPIO_SetBits(GPIOB, GPIO_Pin_13);flag_buzz=0;}
else if(flag_buzz==1){GPIO_SetBits(GPIOB, GPIO_Pin_13);}
OLED_P16x16Ch(0,0,0);
OLED_P16x16Ch(18,0,1);
OLED_P16x16Ch(36,0,2);
OLED_P16x16Ch(54,0,3);
OLED_P16x16Ch(0,3,4);
OLED_P16x16Ch(18,3,5);
OLED_P16x16Ch(36,3,6);
OLED_P16x16Ch(54,3,7);
OLED_P8x16Str(70,0,(unsigned char*)":");
OLED_P8x16Str(70,3,(unsigned char*)":");
if(num!=0xff)
{
set_temp();
if(num=='-'){flag_buzz=1;}
if(num=='x'){flag_swt=10;}
}
}
}
void set_temp()
{
if((1==i)&& (temp[0]=='0') )//如果第一个字符是0,判读第二个字符
{
if((num=='.')&&(flag_2==0)) //如果是小数点则正常输入,光标位置加1
{
temp[1]='.';
OLED_P8x16Str(88,3,(unsigned char*)".");
i++;
flag_2=1;
}
else
{
temp[0]=num+'0'; //如果是1-9数字,说明0没有用,则直接替换第一位0
m=num;
for(s=0;s<16;s++) //赋值完成后把缓冲区清零,防止下次输入影响结果
w[s]=0;
sprintf((char *)w,"%g",m);
OLED_P8x16Str(80,3,(unsigned char*)w); //输出数据
}
}
else if((num!='=')&&(num!='+')&&(num!='-')&&(num!='x')&&(num!='/'))
{
if(num!='.'){
temp[i]=num+'0';
n=num;
for(s=0;s<16;s++) //赋值完成后把缓冲区清零,防止下次输入影响结果
t[s]=0;
sprintf((char *)t,"%g",n);
OLED_P8x16Str(80+i*8,3,(unsigned char*)t); //输出数据
i++;
if(i>3){i=3;} }//输入数值累加
else if((num=='.')&&(flag_2==0))
{
temp[i]=num;
OLED_P8x16Str(80+i*8,3,(unsigned char*)".");//输出数据
i++;if(i>3){i=3;}
flag_2=1;
}
}
if(num=='=')
{
sscanf((char *)temp,"%f",&a);
OLED_P16x16Ch(0,6,8);
OLED_P16x16Ch(18,6,9);
OLED_P16x16Ch(36,6,10);
OLED_P16x16Ch(54,6,11);
delay_ms(1000);
for(s=0;s<16;s++){h[s]=' ';
OLED_P8x16Str(0,6,(unsigned char*)h);}
for(s=0;s<16;s++){h[s]=0;}
}
if(num=='+')
{
i=0;flag_2=0;
for(s=0;s<6;s++){temp[s]=' ';
OLED_P8x16Str(80,3,(unsigned char*)temp);}
for(s=0;s<16;s++){temp[s]=0;}
}
}
void buzzer_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void blower_init()
{
if(a<29.3){flag_blow=1;}
else if((a>=29.3)&&(a<30)){flag_blow=2;}
else flag_blow=3;
}
void blower_opr()
{
if(flag_blow==0){ TIM_SetCompare2(TIM3,1750);}
else if(flag_blow==1){
if(!flag_bit)
TIM_SetCompare2(TIM3,1750);
else if(flag_bit)
TIM_SetCompare2(TIM3,1800); }
else if(flag_blow==2)
{
if(!flag_bit)
TIM_SetCompare2(TIM3,1750);
else if(flag_bit)
TIM_SetCompare2(TIM3,1850);
}
else if(flag_blow==3){
if(!flag_bit)
TIM_SetCompare2(TIM3,1750);
else if(flag_bit)
TIM_SetCompare2(TIM3,1900);}
}
复制代码
所有程序51hei提供下载:
I2C_OLED.7z
(206.97 KB, 下载次数: 57)
2020-7-25 14:59 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
涂益豪
时间:
2020-7-25 14:21
蜂鸣器和舵机的供电记得用5v稳压管,记得与单片机共地
作者:
涂益豪
时间:
2020-7-25 21:07
补充一点,温度传感器用的是DS18B20,进行i2c协议的I/O口是PB0
作者:
wang_01809
时间:
2020-7-25 23:34
学习了,代码能多点备注就好了
作者:
涂益豪
时间:
2020-7-26 10:12
wang_01809 发表于 2020-7-25 23:34
学习了,代码能多点备注就好了
好滴,继续改进
作者:
涂益豪
时间:
2020-7-26 10:16
有两个器件用到了i2c,分别是ds18b20,oled屏幕。这两个都是通过软件模拟i2c
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1