一、系统方案
 模拟的电风扇的工作状态有3种:自然风、常风及睡眠风。使用三个按键S1-S3设置自然风、常风及睡眠风。
 再使用两个按键S4和S5,S4用于定时电风扇定时时间长短的设置,每按一次S4键,定时时间增加10秒,最长60秒,超过60秒回到0秒重新开始。按下S5键表示定时倒计时开始。
 按下相应的风类键,使用处理器ATmega128定时/计数器的PWM功能生成不同占空比的1KHz的PWM信号来驱动直流电动机MOTOR-DC(模拟电风扇电机)。“自然风”:生成占空比为30%的PWM信号,“睡眠风”: 生成占空比为20%的PWM信号,“常风”:生成占空比为70%的PWM信号.
 使用8LED数码管或液晶显示屏显示电风扇的工作状态、动态显示使用电风扇的定时功能时的剩余定时时间。使用8LED数码管和液晶显示屏LGM12641BS1R时,“自然风”显示“1”、“常风”显示“2”及“睡眠风”显示“3”,使用12864液晶显示屏LGM12641BS1R LM3228时使用中文显示。
 
二、硬件设计
 原理图如下:
 
三、单片机软件设计
 1、首先是系统初始化
 //*************************************************************************
 // 初始化子程序
 //*************************************************************************
 void system_init()
 {
 DDRA=0XFF;
 PORTA=0xff;
 DDRC=0x00; //PC口上拉电阻使能
 PORTC=0xf0; //系统初始化,设置IO口属性
 PORTF = 0xFF; //电平设置
 DDRF = 0xFF; //方向输出
 PORTD=0xFF;
 DDRD=0xFF;
 PORTB=0xFF;
 DDRB=0xFF;
 PORTE=0xFF; //PSB对应于PE2
 DDRE=0xFF;
 }
 2、液晶显示程序
 //延时函数
 void delay()
 {
 unsigned int i ,j ;
 for(i=0;i<10000;i++);
 }
 //判断总线忙
 void LCD_wait_ready()
 {
 check_busy:
 lcd_ddr =0X00; lcd_port=0Xff;
 RW1();asm (“nop”);DI0();
 E1(); _delay_us(10); E0();
 if (lcd_pin & 0x80) goto check_busy;
 }
 //写入命令 
 void LCD_write_command(uchar dat)
 {
 LCD_wait_ready();
 lcd_ddr =0XFF; lcd_port=0XFF;
 RW0();asm (“nop”);DI0();
 lcd_port=dat;
 E1();_delay_us(10);E0();
 }
 //写入数据 
 void LCD_write_data(uchar data)
 {
 LCD_wait_ready();
 lcd_ddr =0XFF; lcd_port=0XFF;
 RW0();asm (“nop”);DI1();
 if(!fxshow) lcd_port=data;else lcd_port=~data;
 E1();_delay_us(10);E0();
 }
 //初始化
 void LCDchushihua()
 {
 LCD_write_command(0x3f);_delay_ms(15); 
 }
 //读取数据线
 uchar LCD_read()
 {
 uchar dat;
 lcd_ddr =0X00; lcd_port=0Xff;
 RW1();asm (“nop”); DI0();
 E1(); _delay_us(10); E0();
 dat=lcd_pin;
 return dat;
 } 
 3、按键程序
 //按键扫描函数
 void scan_key()
 {
 if(key1) //按键1.自然风 
 {
 mode = 0 ;
 update = 1 ;
 SetDuty(1); //设置占空比
 }else if(key2) //按键2,常风
 {
 mode = 1 ;
 update = 1 ;
 SetDuty(2); //设置占空比
 }else if(key3) //按键3,睡眠风
 {
 mode = 2 ;
 update = 1 ;
 SetDuty(0); //设置占空比
 }
 if(key4) //按键4按下
 {
 if(key_delay1<10) //按键消抖计数
 {
 key_delay1++;
 }
 }else
 {
 if(key_delay1>5)
 {
 update = 1 ; //显示更新标志位置位
 if(time<60) //如果定时时间小于60
 {
 time = time + 10 ; //每次按下按键后时间会累加
 }else
 {
 time = 0 ;
 }
 }
 key_delay1 = 0 ;
 }
 if(key5) //按键5按下
 {
 if(key_delay2<10) //消抖计数
 {
 key_delay2++;
 }
 }else
 {
 if(key_delay2>5)
 {
 Start(); //开始工作
 flag = 1 ;
 }
 key_delay2 = 0 ;
 }
 }
 4、核心算法程序
 //***********************************************************************
 // 主程序
 //***********************************************************************
 void main(void)
 {
 uint key_store=0x01;
 system_init(); //系统初始化
 LCDchushihua(); //液晶初始化
 LCDQingPing(); //液晶显示清屏
 Display(); //设置显示屏初始内容
 timer1_init(); //定时器1初始化
 timer3_init(); //定时器3初始化
 ETIMSK=0x04; //设置定时器中断
 SEI(); //开中断
 ledoff();
 beer0();
 Display_MSG(0); //显示内容初始化
 Display_Number(10);
 SetDuty(0);
 while(1)
 {
 scan_key(); //按键扫描
 if(update == 1 ) //如果显示更新标志位为1
 {
 update = 0 ; //标志位清0
 Display_MSG(mode); //显示模式
 Display_Number(time); //显示工作时间
 }
 }
 }
四、 proteus仿真设计
 Proteus软件是一款应用比较广泛的工具,它可以在没有硬件平台的基础上通过自身的软件仿真出硬件平台的运行情况,这样就可以通过软件仿真来验证我们设计的方案有没有问题,如果有问题,可以重新选择器件,连接器件,直到达到我们设定的目的,避免我们搭建实物的时候,如果当初选择的方案有问题,我们器件都已经焊接好了,再去卸载下去,再去焊接新的方案的器件,测试,这样会浪费人力和物力,也给开发者带来一定困惑,Proteus仿真软件就很好的解决这个问题,我们在设计之初,就使用该软件进行模拟仿真,测试,选择满足我们设计的最优方案。最后根据测试没问题的仿真图纸,焊接实物,调试,最终完成本设计的作品。
 