0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM8的PWM风扇控制程序分享

jf_eqg0Ui2u 来源:懂事电子设计 2023-06-29 15:04 次阅读

炎炎夏日没有空调怎么办

找来了两个电脑DC12V的CPU散热器风扇。风扇一共四根线,红色:电源+、黑色:电源-、黄色:转速信号线、蓝色:PWM信号线。

后面又找了红外遥控、数码管STM8最小板、红外热释电传感器。准备做一个简易的遥控风扇(让这个夏天清凉一下)。

单片机模块用的1117-3.3V稳压器,而风扇需要使用12V供电传感器模块需要使用5V供电,所以第一步就是在单片机模块输入端加一个78M05,产生一个5V直流给外设模块供电。

然后再把红外信号接收管焊接上。

再然后就是数码管模块和红外热释电传感器(中间忘记拍照了就不贴图了)。最后的最后给它弄个外壳。

效果就是上面图的样子。

然后就是程序部分,风扇速度就不检测了,但是调速还是要弄的。调速的原理就是发PWM波,通过改变PWM波的占空比来实现调速。这里就利用STM8的定时器PWM功能产生两个频率为25KHz的方波。然后检测IO和定时器完成红外遥控信号的接收及解码。红外解码原理都烂大街了,这里就不解释了。红外解码程序也是用的网络大神的。然后就是红外热释电传感器的检测,就是普通IO信号的检测,也没什么好多说的。

下面贴的是主程序部分。

/**
  ******************************************************************************
  * @file    Project/main.c 
  * @author  MCD Application Team
  * @version V2.1.0
  * @date    18-November-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * 

© COPYRIGHT 2011 STMicroelectronics

****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm8s.h" #include "TM1637.h" #include "math.h" /* Private defines -----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ //#define LED_GPIO_PORT (GPIOB) //#define LED_GPIO_PINS (GPIO_PIN_5) //红外解码IO #define IR_IN GPIOA->IDR & (GPIO_PIN_2) //红外热释电 #define PIR_IN GPIOD->IDR & (GPIO_PIN_2) uint16_t sleep_cnt = 0 ; uint16_t i=0; uint8_t sample_flag = 0 ; uint8_t sample_cnt = 0 ; #define CCR1_Val ((uint16_t)800) // uint8_t fan1_speed = 0 ; uint8_t fan2_speed = 0 ; // uint8_t fan1_state = 0 ; uint8_t fan2_state = 0 ; uint8_t display_buff[5] = {0,0,0,0,0}; uint8_t enable_display = 0 ; uint8_t fan1_buff = 0xff ; uint8_t fan2_buff = 0xff ; uint8_t mode = 0 ; uint16_t PIR_Delay = 0 ; uint8_t PIR_REG = 0 ; uint8_t PIR_OFF = 0 ; //**********************红外解码部分变量 uint16_t LongKeyCount ; uint8_t IrData[20]; uint8_t IrOkFlag ; uint8_t IrTime ; uint16_t Time1msCount ; uint16_t DelayTime ; //****************************************************************************// /* Private defines -----------------------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/ /* Private functions ---------------------------------------------------------*/ //IO初始化 void Init_GPIO(void) { GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST); GPIO_Init(GPIOA, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT); GPIO_Init(GPIOD, GPIO_PIN_4, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_OUT_PP_HIGH_FAST); GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_IN_PU_NO_IT); } //定时器4初始化 void Init_Timer4(void) { /*TIM4_UpdateDisableConfig(ENABLE);//允许更新事件 TIM4_ARRPreloadConfig(ENABLE);//自动重装 TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);//中断配置,更新中断 TIM4_SetCounter(0xff);//计数器初值 TIM4_SetAutoreload(0xFF);//计数器自动重装的初值 TIM4_PrescalerConfig(TIM4_PRESCALER_128, TIM4_PSCRELOADMODE_UPDATE);//预分频值 */ TIM4_TimeBaseInit(TIM4_PRESCALER_16, 0x32); //定时器4,50us中断定时 /* Clear TIM4 update flag */ TIM4_ClearFlag(TIM4_FLAG_UPDATE); /* Enable update interrupt */ TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE); TIM4_Cmd(ENABLE); } /*************************************** * TIMER2初始化 * 检测外部频率和脉冲 ***************************************/ void timer2_init(void) { TIM2_DeInit(); TIM2_TimeBaseInit(TIM2_PRESCALER_16, 40-1); TIM2_OC1Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 0, TIM2_OCPOLARITY_HIGH); TIM2_OC2Init(TIM2_OCMODE_PWM1, TIM2_OUTPUTSTATE_ENABLE, 0, TIM2_OCPOLARITY_HIGH); /* TIM1 counter enable */ TIM2_Cmd(ENABLE); } uint8_t get_value(uint8_t spd) { uint8_t buf ; switch(spd) { case 0 : buf = 0 ; break ; case 1 : buf = 20 ;break ; case 2 : buf = 22 ;break ; case 3 : buf = 24 ;break ; case 4 : buf = 28 ;break ; case 5 : buf = 30 ;break ; case 6 : buf = 32 ;break ; case 7 : buf = 34 ;break ; case 8 : buf = 36 ;break ; case 9 : buf = 39 ;break ; default : buf = 0 ; } return buf ; } //设置两个风扇速度 void set_speed(uint8_t spd1,uint8_t spd2) { uint8_t pwm_dat1,pwm_dat2; pwm_dat1 = get_value(spd1); pwm_dat2 = get_value(spd2); TIM2_SetCompare1(pwm_dat1); TIM2_SetCompare2(pwm_dat2); } void fan_run(void) { display_buff[0] = (fan1_buff>>7)&0x01|((fan1_buff>>1)&0x38); display_buff[1] = 0x0f&fan1_buff ; display_buff[2] = (fan2_buff>>7)&0x01|((fan2_buff>>1)&0x38); display_buff[3] = 0x0f&fan2_buff ; } //遥控按键处理函数 void key_handling(uint8_t key_value) { switch(key_value) { case 0x43 : enable_display = 1 ; break ; case 0x09 : enable_display = 0 ; break ; case 0x44 : fan1_state = 1 ; fan1_speed=9;set_speed(fan1_speed,fan2_speed);break ; case 0x40 : fan2_state = 1 ; fan2_speed=9;set_speed(fan1_speed,fan2_speed);break ; case 0x07 : fan1_state = 0 ; fan1_speed=0;set_speed(fan1_speed,fan2_speed);PIR_OFF = 0 ;break ; case 0x15 : fan2_state = 0 ; fan2_speed=0;set_speed(fan1_speed,fan2_speed);PIR_OFF = 0 ;break ; case 0x46 : mode = 0 ; break ; case 0x45 : if(fan1_state==1)mode = 1 ; break ; case 0x47 : if(fan2_state==1)mode = 2 ; break ; case 0x19 : fan1_state = 1 ; fan1_speed=9;fan2_state = 1 ; fan2_speed=9;set_speed(fan1_speed,fan2_speed);break ; case 0x0d : fan1_state = 0 ; fan1_speed=0;fan2_state = 0 ; fan2_speed=0;set_speed(fan1_speed,fan2_speed);break ; case 0x16 : if(mode==1) fan1_speed = 0 ; else if(mode==2) fan2_speed = 0 ;set_speed(fan1_speed,fan2_speed); break ; case 0x0c : if(mode==1) fan1_speed = 1 ; else if(mode==2) fan2_speed = 1 ;set_speed(fan1_speed,fan2_speed); break ; case 0x18 : if(mode==1) fan1_speed = 2 ; else if(mode==2) fan2_speed = 2 ;set_speed(fan1_speed,fan2_speed); break ; case 0x5e : if(mode==1) fan1_speed = 3 ; else if(mode==2) fan2_speed = 3 ;set_speed(fan1_speed,fan2_speed); break ; case 0x08 : if(mode==1) fan1_speed = 4 ; else if(mode==2) fan2_speed = 4 ;set_speed(fan1_speed,fan2_speed); break ; case 0x1c : if(mode==1) fan1_speed = 5 ; else if(mode==2) fan2_speed = 5 ;set_speed(fan1_speed,fan2_speed); break ; case 0x5a : if(mode==1) fan1_speed = 6 ; else if(mode==2) fan2_speed = 6 ;set_speed(fan1_speed,fan2_speed); break ; case 0x42 : if(mode==1) fan1_speed = 7 ; else if(mode==2) fan2_speed = 7 ;set_speed(fan1_speed,fan2_speed); break ; case 0x52 : if(mode==1) fan1_speed = 8 ; else if(mode==2) fan2_speed = 8 ;set_speed(fan1_speed,fan2_speed); break ; case 0x4a : if(mode==1) fan1_speed = 9 ; else if(mode==2) fan2_speed = 9 ;set_speed(fan1_speed,fan2_speed); break ; default: ; } } //红外解码处理函数,在定时器4中断中调用,移植自网络 void Time4InitFun (void) { static unsigned char TimeL,TimeH; static unsigned char IoState,UpState; static unsigned char RxData[4]; static unsigned char BitCount,ByteCount; static unsigned char Task; unsigned char i; //TIM4_SR=0; //清标志 IoState =IR_IN; if(IoState){ if(TimeH<250)TimeH++; } else{ if(TimeL<250)TimeL++; } if((!IoState)&&(UpState)){ if(Task==0){ //收同步头 if((TimeL<=(180+30))&&(TimeL>=(180-30))&&(TimeH<=(87+10))&&(TimeH>=(43-10))){ BitCount=0; ByteCount=0; if(LongKeyCount)LongKeyCount=3; Task++; } } else if(Task==1){ //收数据 if((TimeL<=(12+5))&&(TimeL>=(12-5))){ if((TimeH<=(12+5))&&(TimeH>=(12-5))) RxData[ByteCount] &= ~(1<=(32-8))) RxData[ByteCount] |= (1<=8){ BitCount=0; ByteCount++; if(ByteCount>=4){ ByteCount=0; for(i=0;i<4;i++){ IrData[i]=RxData[i]; IrOkFlag=1; Task=0; IrTime=5; LongKeyCount=3; //长键采样 } } } } else{ Task=0; } } else{ Task=0; } TimeH=0; TimeL=0; } UpState=IoState; if(Time1msCount<250)Time1msCount++; if(DelayTime)DelayTime--; return; } //主函数 void main(void) { // ErrorStatus clk_return_status; //FlagStatus flag_status; u16 display_cnt = 0 ; uint8_t cnt = 0 ; /* Configuration -----------------------------------------*/ CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //不分频 CLK_HSICmd(ENABLE); //开始内部高频RC Init_Timer4(); enableInterrupts(); GPIO_init(); TM1637_OFF(); timer2_init(); set_speed(fan1_speed,fan2_speed); sleep_cnt = 0 ; mode = 0 ; while (1) { if(PIR_IN) { display_buff[1] = display_buff[1]|0x80; PIR_REG = 1 ; if(PIR_OFF) { PIR_OFF = 0 ; fan1_speed=9; fan2_speed=9; fan1_state = 1 ; fan2_state = 1 ; set_speed(fan1_speed,fan2_speed); } }else { display_buff[1] = display_buff[1]&0x7f; PIR_REG = 0 ; } //********************************************************************** if(sample_flag==1) //20毫秒执行一次 { sample_flag = 0 ; display_cnt++; } //********************************************************************** if(IrOkFlag==1) { IrOkFlag = 0 ; key_handling(IrData[2]); } //********************************************************************** if(display_cnt>10) { display_cnt=0; if((fan1_state==1||fan2_state==1)) { if(PIR_REG==0) { PIR_Delay++; } if(PIR_Delay>=1000) { fan1_state = 0 ; fan2_state = 0 ; fan1_speed=0; fan2_speed=0; set_speed(fan1_speed,fan2_speed); PIR_OFF = 1 ; } }else { PIR_Delay = 0 ; } if(enable_display) { TM1637_DHex(display_buff); }else { TM1637_OFF(); } cnt ++ ; if(cnt>=8) { cnt =0 ; } if(mode==0) { if(fan1_state) { fan1_buff = 0xff & (~(0x01< 审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6001

    文章

    43978

    浏览量

    620871
  • 空调
    +关注

    关注

    11

    文章

    1185

    浏览量

    58112
  • cpu
    cpu
    +关注

    关注

    68

    文章

    10446

    浏览量

    206574
  • PWM
    PWM
    +关注

    关注

    114

    文章

    4901

    浏览量

    209930
  • 风扇
    +关注

    关注

    4

    文章

    397

    浏览量

    36879

原文标题:基于STM8的PWM风扇控制程序分享

文章出处:【微信号:懂事电子设计,微信公众号:懂事电子设计】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    PID控制程序

    有哪位好心人帮忙编一道PID控制程序,注意位数等的范围,并要求附上Kp,Ti,Td的范围。谢谢!
    发表于 05-03 14:49

    舵机控制程序

    舵机控制程序,仅供参考{:soso_e113:}
    发表于 05-16 14:46

    求单片机控制的自动门PWM控制程序

    求单片机控制的自动门PWM控制程序,平滑启动,本人用的是直流无刷电机,红外感应器,单位的项目,让我写程序,要求能平滑启动。谢谢各位大侠。
    发表于 11-14 10:37

    请问有没有编过模糊PID控制程序或神经网络控制程序

    各位大神,请问有没有编过模糊PID控制程序或神经网络控制程序
    发表于 01-12 10:50

    如何将stm32的控制程序转成51的程序?

    如何将stm32的控制程序转成51的程序,用的是意法的传感器,给的控制程序也是32的
    发表于 11-03 08:07

    红外遥控灯电路及控制程序

    红外遥控灯电路及控制程序
    发表于 03-11 09:41 199次下载

    机器人控制程序(舵机型)

    机器人控制程序(舵机型)机器人控制程序(舵机型)
    发表于 11-12 17:23 16次下载

    单片机按键控制程序【汇编版】

    单片机按键控制程序【汇编版】单片机按键控制程序【汇编版】单片机按键控制程序【汇编版】单片机按键控制程序【汇编版】
    发表于 12-29 11:04 0次下载

    单片机按键控制程序【C语言】

    单片机按键控制程序【C语言】单片机按键控制程序【C语言】单片机按键控制程序【C语言】单片机按键控制程序【C语言】
    发表于 12-29 11:04 29次下载

    多舵机控制程序

    多舵机控制程序
    发表于 03-21 15:43 12次下载

    手势控制程序

    这个是小车的手势控制程序,通过单片机可以控制小车来进行活动,比如前进或者后退。
    发表于 05-11 11:30 22次下载

    3种单按钮起挺控制程序

    三菱PLC(可编程逻辑控制器)编程实例项目例程——3种单按钮起挺控制程序
    发表于 11-08 16:03 6次下载

    直流无刷电机控制程序

    直流无刷电机控制程序(现代电源技术杜少武扫描版)- 直流无刷电机控制程序,可用在直流变频空调上
    发表于 09-28 12:28 153次下载
    直流无刷电机<b class='flag-5'>控制程序</b>

    STM32f10xc8t6L智能小车蓝牙避障完整PWM控制程序

    STM32f10xc8t6L智能小车蓝牙避障完整PWM控制程序
    发表于 12-23 17:06 8次下载

    快速掌握PLC控制程序的设计

    快速掌握PLC控制程序的设计
    发表于 03-17 09:42 267次阅读