本次单片机实验,我主要是做了一个简单的智能风扇,风扇可以通过感知外部温度、按键、红外遥控来控制转速,并将转速与外部温度通过lcd显示屏显示。主要就是用了温度传感器DS18B20,红外遥控,lcd显示屏等外设。通过定时器产生PWM波来控制风扇的转速,通过L298N来驱动电机。
关键词:温度传感器DS18B20,红外遥控,PWM,lcd,l298n
主函数代码:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "ds18b20.h"
#include "PWM.h"
#include "key.h"
#include "remote.h"
static int temp=500;
short temperature;
u8 flag=0;
void hander(int change )
{
int result;
result=change/10;
if(result<17)
TIM_SetCompare1(TIM14,500);
else
{
if(result>=17&&result<18)
temp=400;
else if(result>=18&&result<19)
temp=300;
else if(result>=19&&result<20)
temp=250;
else if(result>=20&&result<22)
temp=150;
else if(result>=22)
temp=0;
TIM_SetCompare1(TIM14,temp);
}
}
void IR_Key()
{
u8 key;
key=Remote_Scan();
if(key)
{
LCD_ShowNum(86,170,key,3,16); //显示键值
LCD_ShowNum(86,190,RmtCnt,3,16); //显示按键次数
if(key==104)
temp+=25;
delay_ms(30);
if(key==152)
temp-=25;
delay_ms(30);
if(temp>=500)
temp=425;
else if(temp<0)
{
temp=0;
}
if(key==104||key==152)
{
TIM_SetCompare1(TIM14,temp);
}
delay_ms(10);
}
}
void KEY_Action()
{
u8 key;
key=KEY_Scan(0);
if(key==1)
{
temp=temp+100;
}
if(key==2)
{
temp-=100;
}
if(temp>=500)
{
temp=500;
}
if(temp<10)
{
temp=0;
}
if(key==1||key==2)
{
TIM_SetCompare1(TIM14,temp);
}
}
void flag_mask()
{
if(WK_UP==1)
{
delay_ms(10);//去抖动
if(WK_UP==1)
{
while(WK_UP==1);
flag++;
}
}
}
int main(void)
{
u8 t=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
TIM14_PWM_Init(500-1,84-1);
Remote_Init();
KEY_Init();
LED_Init(); //初始化LED
LCD_Init();
POINT_COLOR=RED;//设置字体为红色
while(DS18B20_Init()) //DS18B20初始化
{
LCD_ShowString(30,130,200,16,16,"DS18B20 Error");
delay_ms(200);
LCD_Fill(30,130,239,130+16,WHITE);
delay_ms(200);
}
LCD_ShowString(30,130,200,16,16,"DS18B20 OK");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(30,150,200,16,16,"Temp: . C");
LCD_ShowString(30,170,200,16,16,"KEYVAL:");
LCD_ShowString(30,190,200,16,16,"KEYCNT:");
LCD_ShowString(30,210,200,16,16,"rev: circle/min");
while(1)
{
flag_mask();
if(t%10==0)//每100ms读取一次
{
temperature=DS18B20_Get_Temp();
if(temperature<0)
{
LCD_ShowChar(30+40,150,'-',16,0); //显示负号
temperature=-temperature; //转为正数
}else LCD_ShowChar(30+40,150,' ',16,0); //去掉负号
LCD_ShowNum(30+40+8,150,temperature/10,2,16); //显示正数部分
LCD_ShowNum(30+40+32,150,temperature%10,1,16); //显示小数部分
LCD_ShowNum(30+32+8,210,(500-temp),3,16);//显示转速
}
if(flag%3==0)
{
KEY_Action();
}
if(flag%3==1)
{
hander(temperature);
}
if(flag%3==2)
{
IR_Key();
}
delay_ms(10);
t++;
if(t==20)
{
t=0;
LED1=!LED1;
}
}
}
PWM代码:
#include "PWM.h"
void TIM14_PWM_Init( u32 Arr,u32 psc )
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed;
GPIO_Init(GPIOF,&GPIO_InitStructure);
TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseStruct.TIM_Period=Arr;
TIM_TimeBaseStruct.TIM_Prescaler=psc;
TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStruct);
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_Low;
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
TIM_OC1Init(TIM14,&TIM_OCInitStruct);
TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM14,ENABLE);
TIM_Cmd(TIM14,ENABLE);
}
其他的代码如:LCD、DS18B20、KEY、REMOTE等代码与标准源码是一样的。