完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
设计目的
本次设计为STM32初学成品,基于STM32F103ZET6的红外遥控电子时钟,采用了战舰开发板配套的TFTLCD显示屏,红外遥控器HS0038等硬件,实现了遥控控制日期时间的更改,闹钟的设置,响铃等功能。 设计原理 该设计运用到两个定时器,定时器3用于1s定时,定时器4用于捕获遥控器发出的红外信号。通过TFTLCD显示屏显示当前日期、当前时间以及自定义的闹钟时间,纯人工定位画点(后来才发现有现成的RCT)。TFTLCD由FSMC(flexible static memory controller)驱动,颜色编码格式RGB565,遥控器仅设置三个按键有效,ALIENTEK控制模式切换,UP控制加一操作,DOWN控制减一操作。 以下有几个重要的概念:
软件设计
#include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "lcd.h" #include "usart.h" #include "remote.h" #include "timer.h" #include "clock.h" #include "beep.h" volatile u32 year=2019; volatile u32 month=12; volatile u32 day=12; volatile u32 hour=23; volatile u32 minute=59; volatile u32 second=50; volatile u32 chour=0; volatile u32 cminute=0; volatile u32 csecond=0; u8 setMode=0;//设置模式 void inc(void)//加1 { switch(setMode) { case 1: { year++; if(year==2100)year=2000; break; } case 2: { month++; if(month==13)month=1; break; } case 3: { day++; if(day==31)day=1; break; } case 4: { hour++; if(hour==24)hour=0; break; } case 5: { minute++; if(minute==60)minute=0; break; } case 6: { second++; if(second==60)second=0; break; } case 7: { chour++; if(chour==24)chour=0; break; } case 8: { cminute++; if(cminute==60)cminute=0; break; } case 9: { csecond++; if(csecond==60)csecond=0; break; } } } void dec(void)//减1 { switch(setMode) { case 1: { year--; if(year==1999)year=2100; break; } case 2: { month--; if(month==0)month=12; break; } case 3: { day--; if(day==0)day=30; break; } case 4: { hour--; if(hour<=0)hour=23; break; } case 5: { minute--; if(minute<=0)minute=59; break; } case 6: { second--; if(second<=0)second=59; break; } case 7: { chour--; if(chour<=0)chour=23; break; } case 8: { cminute--; if(cminute<=0)cminute=59; break; } case 9: { csecond--; if(csecond<=0)csecond=59; break; } } } int main(void) { u8 key; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级 //uart_init(115200); //串口初始化为115200 LED_Init(); //LED端口初始化 BEEP_Init(); //初始化蜂鸣器端口 LCD_Init(); Remote_Init(); //红外接收初始化 TIM3_Int_Init(9999,7199);//10Khz的计数频率,计数到10000为1s while(1) { CLOCK_Show(year,month,day,hour,minute,second,chour,cminute,csecond); if(hour==chour&&minute==cminute&&second==csecond) {//闹钟响 BEEP=1; delay_ms(1000); BEEP=0; } if(Remote_Scan()) { delay_ms(2800);//2000-3000都可 key=Remote_Scan(); switch(key) { case 0://ERROR break; case 162://POWER break; case 98://UP { inc(); break; } case 2://PLAY break; case 226://ALIENTEK { setMode++; if(setMode==10)setMode=0; break; } case 194://RIGHT break; case 34://LEFT break; case 224://VOL- break; case 168://DOWN { dec(); break; } case 144://VOL+ break; case 104://1 break; case 152://2 break; case 176://3 break; case 48://4 break; case 24://5 break; case 122://6 break; case 16://7 break; case 56://8 break; case 90://9 break; case 66://0 break; case 82://DELETE break; } } if(setMode) { LED1=1; LED0=0; } else { LED0=1; LED1=0; } } }
#include "clock.h" void CLOCK_Show(u32 year,u32 month,u32 day,u32 hour,u32 minute,u32 second,u32 chour,u32 cminute,u32 csecond)//初始化日期时间 { POINT_COLOR=RED; //设置字体为红色,默认也是红色 LCD_ShowString(30,50,200,24,24,"DATE:"); LCD_ShowString(90,80,1,24,24,"/");//年60 其他30 符号10 LCD_ShowString(140,80,1,24,24,"/");// LCD_ShowString(30,110,200,24,24,"TIME:"); LCD_ShowString(60,140,1,24,24,":"); LCD_ShowString(110,140,1,24,24,":"); LCD_ShowString(30,170,200,24,24,"CLOCK:"); LCD_ShowString(60,200,1,24,24,":"); LCD_ShowString(110,200,1,24,24,":"); POINT_COLOR=BLUE; BACK_COLOR=(setMode==1)?GRAY:WHITE; LCD_ShowNum(30,80,year,4,24);//行距30 BACK_COLOR=(setMode==2)?GRAY:WHITE; LCD_ShowNum(110,80,month,2,24); BACK_COLOR=(setMode==3)?GRAY:WHITE; LCD_ShowNum(160,80,day,2,24); BACK_COLOR=(setMode==4)?GRAY:WHITE; LCD_ShowNum(30,140,hour,2,24); BACK_COLOR=(setMode==5)?GRAY:WHITE; LCD_ShowNum(80,140,minute,2,24); BACK_COLOR=(setMode==6)?GRAY:WHITE; LCD_ShowNum(130,140,second,2,24); BACK_COLOR=(setMode==7)?GRAY:WHITE; LCD_ShowNum(30,200,chour,2,24); BACK_COLOR=(setMode==8)?GRAY:WHITE; LCD_ShowNum(80,200,cminute,2,24); BACK_COLOR=(setMode==9)?GRAY:WHITE; LCD_ShowNum(130,200,csecond,2,24); BACK_COLOR=WHITE;//字体背景色 }
#ifndef __CLOCK_H #define __CLOCK_H #include "sys.h" #include "lcd.h" extern u8 setMode; void CLOCK_Show(u32 year,u32 month,u32 day,u32 hour,u32 minute,u32 second,u32 chour,u32 cminute,u32 csecond);//初始化日期,时间,闹钟 #endif
#include "timer.h" #include "delay.h" #include "led.h" //通用定时器3中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3! void TIM3_Int_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 //定时器TIM3初始化 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断 //中断优先级NVIC设置 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器 TIM_Cmd(TIM3, ENABLE); //使能TIMx } //定时器3中断服务程序 void TIM3_IRQHandler(void) //TIM3中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查TIM3更新中断发生与否 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中断标志 if(!setMode) { second++; if(second==60) { second=0; minute++; if(minute==60) { minute=0; hour++; if(hour==24) { hour=0; day++; if(day==31) { day=1; month++; if(month==13) { month=1; year++; if(year==3001) { year=2000; } } } } } } } } }
#ifndef __TIMER_H #define __TIMER_H #include "sys.h" extern volatile u32 day,month,year; extern volatile u32 second,minute,hour; extern u8 setMode; void TIM3_Int_Init(u16 arr,u16 psc); #endif 调试结果 图左为正常工作模式(计时模式),图右为设置模式,灰色背景表示当前设置的位置,蓝色数字都可以通过遥控设置。由上往下分别显示当前日期、当前时间、自定义闹钟,按遥控上的ALIENTEK键进入或退出设置模式。 设计总结 本次课程设计调试过程中,TFTLCD对红外遥控按键的反应是循环检测,支持连按的,一时找不到检测松手的入口,索性直接采用延迟反应的笨办法。2000ms过慢,3000ms又过快,因此选择了2800ms延迟按键反应时间。注意蜂鸣器需要三极管驱动,GPIO口输出高电平放大电流。TFTLCD显示的字体背景颜色改变后要切换回默认状态即白色,以保证设置的时候始终只有一个位置是灰色。LED由GPIO输出低电平点亮,在设置模式下DS0(红灯)亮,正常工作模式下DS1(黄灯)亮 。由于时间关系(一天时间太短了莫得办法),闹钟功能简单的由蜂鸣器响铃一秒完成,可后续扩展成为音乐闹铃。红外遥控键盘部分也可以扩展相应要实现的功能,比如数字键盘设置。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1802 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1629 浏览 1 评论
1096 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
735 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1685 浏览 2 评论
1944浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
747浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
580浏览 3评论
602浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
565浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 06:52 , Processed in 0.810832 second(s), Total 76, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号