炎炎夏日沒有空調(diào)怎么辦
找來了兩個(gè)電腦DC12V的CPU散熱器風(fēng)扇。風(fēng)扇一共四根線,紅色:電源+、黑色:電源-、黃色:轉(zhuǎn)速信號(hào)線、藍(lán)色:PWM信號(hào)線。
后面又找了紅外遙控、數(shù)碼管、STM8最小板、紅外熱釋電傳感器。準(zhǔn)備做一個(gè)簡易的遙控風(fēng)扇(讓這個(gè)夏天清涼一下)。
單片機(jī)模塊用的1117-3.3V穩(wěn)壓器,而風(fēng)扇需要使用12V供電,傳感器模塊需要使用5V供電,所以第一步就是在單片機(jī)模塊輸入端加一個(gè)78M05,產(chǎn)生一個(gè)5V直流給外設(shè)模塊供電。
然后再把紅外信號(hào)接收管焊接上。
再然后就是數(shù)碼管模塊和紅外熱釋電傳感器(中間忘記拍照了就不貼圖了)。最后的最后給它弄個(gè)外殼。
效果就是上面圖的樣子。
然后就是程序部分,風(fēng)扇速度就不檢測了,但是調(diào)速還是要弄的。調(diào)速的原理就是發(fā)PWM波,通過改變PWM波的占空比來實(shí)現(xiàn)調(diào)速。這里就利用STM8的定時(shí)器PWM功能產(chǎn)生兩個(gè)頻率為25KHz的方波。然后檢測IO和定時(shí)器完成紅外遙控信號(hào)的接收及解碼。紅外解碼原理都爛大街了,這里就不解釋了。紅外解碼程序也是用的網(wǎng)絡(luò)大神的。然后就是紅外熱釋電傳感器的檢測,就是普通IO信號(hào)的檢測,也沒什么好多說的。
下面貼的是主程序部分。
/** ****************************************************************************** * @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. * ******************************************************************************* */ /* 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); } //定時(shí)器4初始化 void Init_Timer4(void) { /*TIM4_UpdateDisableConfig(ENABLE);//允許更新事件 TIM4_ARRPreloadConfig(ENABLE);//自動(dòng)重裝 TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);//中斷配置,更新中斷 TIM4_SetCounter(0xff);//計(jì)數(shù)器初值 TIM4_SetAutoreload(0xFF);//計(jì)數(shù)器自動(dòng)重裝的初值 TIM4_PrescalerConfig(TIM4_PRESCALER_128, TIM4_PSCRELOADMODE_UPDATE);//預(yù)分頻值 */ TIM4_TimeBaseInit(TIM4_PRESCALER_16, 0x32); //定時(shí)器4,50us中斷定時(shí) /* 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 ; } //設(shè)置兩個(gè)風(fēng)扇速度 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 ; } //遙控按鍵處理函數(shù) 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: ; } } //紅外解碼處理函數(shù),在定時(shí)器4中斷中調(diào)用,移植自網(wǎng)絡(luò) 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; //清標(biāo)志 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){ //收數(shù)據(jù) if((TimeL<=(12+5))&&(TimeL>=(12-5))){ if((TimeH<=(12+5))&&(TimeH>=(12-5))) RxData[ByteCount] &= ~(1<
? COPYRIGHT 2011 STMicroelectronics =(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; } //主函數(shù) 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); //開始內(nèi)部高頻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毫秒執(zhí)行一次 { 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< 審核編輯:湯梓紅
-
單片機(jī)
+關(guān)注
關(guān)注
6037文章
44558瀏覽量
635355 -
空調(diào)
+關(guān)注
關(guān)注
11文章
1228瀏覽量
58586 -
cpu
+關(guān)注
關(guān)注
68文章
10863瀏覽量
211782 -
PWM
+關(guān)注
關(guān)注
114文章
5186瀏覽量
213957 -
風(fēng)扇
+關(guān)注
關(guān)注
4文章
414瀏覽量
37432
原文標(biāo)題:基于STM8的PWM風(fēng)扇控制程序分享
文章出處:【微信號(hào):懂事電子設(shè)計(jì),微信公眾號(hào):懂事電子設(shè)計(jì)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論