通过stm32f103c8t6单片机的定时器3输出四路可调的PWM(TIM3)。 通过按键控制呼吸灯频率以及模式转换。 通过oled12864显示实时时钟,并且可以通过按键修改时间。 通过oled12864屏幕显示信息(显示实时时间以及呼吸频率等级)。 通过HC-05蓝牙模块调节PWM的频率 主要功能: 基于STM32的呼吸灯装置,使用定时器3(TIM3)输出4路PWM。 在屏幕上会显示呼吸频率等级和实时时钟,装置具有三个按键,其中一个为模式转换,按下依次修改年月日时分的数值。另外两个按键为加数和减数,这两个按键共用与按键修改时间和调整呼吸频率。 当模式按键未按下时,加减键修改呼吸频率。 当模式按键按下第一次时,此时为年份修改,通过按键加减修改年份。 当模式按键按下第二次时,此时为月份修改,通过按键加减修改月份 当模式按键按键按下三、四、五次时,分别对应修改日、时、分,通过按键加减修改数值。
另外可以通过蓝牙修改呼吸灯的频率 接线:
引脚 | | | | | IIC 屏幕数据线以及时钟线 分别接入屏幕的SCL SDA | | | | |
清单:
制作出来的实物效果图:
单片机源程序如下:
- #include "stm32f10x.h" //STM32头文件
- #include "sys.h"
- #include "delay.h"//延时
- #include "oled0561.h"//oled屏幕
- #include "NVIC.h"//外部中断
- #include "usart.h"//串口
- #include "key.h"//按键
- #include "i2c.h"
- #include "rtc.h"
- #include "pwm.h"
- void xianshishijian(void);
- void xiugai(void);
- u8 a,dengji=20;
- u8 bya=6;
- int main (void){//主程序
- u8 a,fx=1;
- u32 ti=0;
- RCC_Configuration(); //系统时钟初始化
- TIM3_Init(); //定时器3 pwm
- USART1_Init(9600);//串口1初始化并启动
- KEY_Init();//按键初始化
- KEYPAD1_INT_INIT();//按键中断初始化
- KEYPAD2_INT_INIT();//按键中断初始化
- KEYPAD3_INT_INIT();//按键中断初始化
- RTC_Config();
- I2C_Configuration();//i2c初始化
- OLED0561_Init();//屏幕初始化
- delay_ms(10);
- OLED_DISPLAY_PIC1();//开机动画
- delay_s(1);
- OLED_DISPLAY_CLEAR();
- bya=RTC_Set(2019,12,10,13,34,00);
- delay_s(1);
- printf("%d",dengji);
-
-
- while(1){
- for(a=0;a<8;a++){
- OLED_DISPLAY_16x16(4,a*16,a);//显示信息
- }
-
-
- xianshishijian();
- xiugai();
-
- delay_ms(1);
- if(fx==1)
- {
- ti++;
- if(ti>dengji)
- {
- fx=0;
- }
- }
- else
- {
- ti--;
- if(ti==0)
- {
- fx=1;
- }
- }
- TIM_SetCompare1(TIM3, ti*10);//设置TIMx捕获比较2寄存器值
- TIM_SetCompare2(TIM3, ti*10);
- TIM_SetCompare3(TIM3, ti*10);
- TIM_SetCompare4(TIM3, ti*10);
- }
- }
- void xiugai(void){
- if((jia1==1||jia==1)&&mode==0){
- dengji++;
- printf("%d",dengji);
- jia=0;
- jia1=0;
- }
- if((jian1||jian==1)&&mode==0){
- if(dengji>0){
- dengji--;
- printf("%d",dengji);
- jian=0;
- jian1=0;
- }
- }
-
- switch(mode){
- case 1:
- OLED_DISPLAY_8x16(0,3*8,'_');
- OLED_DISPLAY_8x16(0,4*8,'_');
- OLED_DISPLAY_8x16(0,5*8,'_');
- OLED_DISPLAY_8x16(0,6*8,'_');
- a=ryear/1000+48;
- OLED_DISPLAY_8x16(0,3*8,a);
- a=ryear%1000/100+48;
- OLED_DISPLAY_8x16(0,4*8,a);
- a=ryear%100/10+48;
- OLED_DISPLAY_8x16(0,5*8,a);
- a=ryear%10+48;
- OLED_DISPLAY_8x16(0,6*8,a);
- if(jia==1){
- ryear++;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jia=0;
- }
- if(jian==1){
- ryear--;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jian=0;
- }
- break;
-
- case 2:
- OLED_DISPLAY_8x16(0,8*8,'_');
- OLED_DISPLAY_8x16(0,9*8,'_');
- a=rmon/10+48;
- OLED_DISPLAY_8x16(0,8*8,a);
- a=rmon%10+48;
- OLED_DISPLAY_8x16(0,9*8,a);
- if(jia==1){
- rmon++;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jia=0;
- }
- if(jian==1){
- rmon--;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jian=0;
- }
- break;
-
- case 3:
- OLED_DISPLAY_8x16(0,11*8,'_');
- OLED_DISPLAY_8x16(0,12*8,'_');
- a=rday/10+48;
- OLED_DISPLAY_8x16(0,11*8,a);
- a=rday%10+48;
- OLED_DISPLAY_8x16(0,12*8,a);
- if(jia==1){
- rday++;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jia=0;
- }
- if(jian==1){
- rday--;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jian=0;
- }
- break;
-
- case 4:
- OLED_DISPLAY_8x16(2,4*8,'_');
- OLED_DISPLAY_8x16(2,5*8,'_');
- a=rhour/10+48;
- OLED_DISPLAY_8x16(2,4*8,a);
- a=rhour%10+48;
- OLED_DISPLAY_8x16(2,5*8,a);
- if(jia==1){
- rhour++;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jia=0;
- }
- if(jian==1){
- rhour--;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jian=0;
- }
- break;
-
- case 5:
- OLED_DISPLAY_8x16(2,7*8,'_');
- OLED_DISPLAY_8x16(2,8*8,'_');
- a=rmin/10+48;
- OLED_DISPLAY_8x16(2,7*8,a);
- a=rmin%10+48;
- OLED_DISPLAY_8x16(2,8*8,a);
- if(jia==1){
- rmin++;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jia=0;
- }
- if(jian==1){
- rmin--;
- bya=RTC_Set(ryear,rmon,rday,rhour,rmin,rsec);
- jian=0;
- }
- break;
- default:
- mode=0;
-
-
- }
- }
- void xianshishijian(void){
-
-
-
- //************等级
- OLED_DISPLAY_16x16(6,4*16,14);
- OLED_DISPLAY_16x16(6,5*16,15);
- OLED_DISPLAY_8x16(6,12*8,':');
- a=dengji/10+48;
- OLED_DISPLAY_8x16(6,13*8,a);
- a=dengji%10+48;
- OLED_DISPLAY_8x16(6,14*8,a);
-
-
- RTC_Get(); //读出时间值,同时判断返回值是不是0,非0时读取的值是错误的。
- // printf("%d-%d-%d %02d:%02d:%02d ",ryear,rmon,rday,rhour,rmin,rsec);//显示日期时间
- // printf("%d\r\n",bya);//0为成功
- //****************年
- a=ryear/1000+48;
- OLED_DISPLAY_8x16(0,3*8,a);
- a=ryear%1000/100+48;
- OLED_DISPLAY_8x16(0,4*8,a);
- a=ryear%100/10+48;
- OLED_DISPLAY_8x16(0,5*8,a);
- a=ryear%10+48;
- OLED_DISPLAY_8x16(0,6*8,a);
- OLED_DISPLAY_8x16(0,7*8,'/');
- //****************月
- a=rmon/10+48;
- OLED_DISPLAY_8x16(0,8*8,a);
- a=rmon%10+48;
- OLED_DISPLAY_8x16(0,9*8,a);
- OLED_DISPLAY_8x16(0,10*8,'/');
- //****************日
- a=rday/10+48;
- OLED_DISPLAY_8x16(0,11*8,a);
- a=rday%10+48;
- OLED_DISPLAY_8x16(0,12*8,a);
- //**************时
- a=rhour/10+48;
- OLED_DISPLAY_8x16(2,4*8,a);
- a=rhour%10+48;
- OLED_DISPLAY_8x16(2,5*8,a);
- OLED_DISPLAY_8x16(2,6*8,':');
- //***************分
- a=rmin/10+48;
- OLED_DISPLAY_8x16(2,7*8,a);
- a=rmin%10+48;
- OLED_DISPLAY_8x16(2,8*8,a);
- OLED_DISPLAY_8x16(2,9*8,':');
- //***************秒
- a=rsec/10+48;
- OLED_DISPLAY_8x16(2,10*8,a);
- a=rsec%10+48;
- OLED_DISPLAY_8x16(2,11*8,a);
- }
- /*
- 【变量定义】
- u32 a; //定义32位无符号变量a
- u16 a; //定义16位无符号变量a
- u8 a; //定义8位无符号变量a
- vu32 a; //定义易变的32位无符号变量a
- vu16 a; //定义易变的 16位无符号变量a
- vu8 a; //定义易变的 8位无符号变量a
- uc32 a; //定义只读的32位无符号变量a
- uc16 a; //定义只读 的16位无符号变量a
- uc8 a; //定义只读 的8位无符号变量a
- delay_us(1); //延时1微秒
- delay_ms(1); //延时1毫秒
- delay_s(1); //延时1秒
- */
复制代码
所有资料51hei提供下载:
课题设计.7z
(213.65 KB, 下载次数: 63)
|