找回密码
 注册

QQ登录

只需一步,快速开始

搜索

基于STM32定时中断的电子闹钟设计

[复制链接]
路漫漫 发表于 2020-5-29 01:17:33 | 显示全部楼层 |阅读模式

word格式文档: 基于stm32定时中断的电子闹钟.doc (2.9 MB, 售价: 1 E币)

一、系统主要功能
可以通过LCD的输出显示公历和农历时间,通过按键设置时间和闹钟;通过蜂鸣器响应闹钟。

三、电路原理图、接口、硬件构成

1.原理图

201.001.jpg

2.接口

本次实验使用了串口、定时器、中断接口。

3.硬件组成
(1)实验设计程序流程图如图左所示,中断流程图如图右所示。
201.002.jpg 201.003.jpg

              (2)该设计分为软件设计和硬件设计两大模块,硬件电路由 ARM 最小系统电路、时钟显示电路和闹钟提醒电路组成,采用stm32f103RCT6芯片,芯片管脚图示如下。
201.004.jpg

(3)时钟电路

此电路主要是复位电路和时钟电路两部分,其中复位电路采用按键手动复位和上电自动复位组合,电路如图所示:晶振采用的是 8MHz 和 32.786KHz , 8MKz 分别接 STM32 的 5 脚和 6 脚, 32.786KHz 分别接 STM32 的 3 脚和 4 脚。
201.005.jpg 201.006.jpg
(4)闹钟提醒电路
本次实验设计的闹钟提醒电路为蜂鸣器电路,接入芯片的PC7引脚,当时间为设置闹钟时间时,蜂鸣器工作,发出响声,提醒电路如图所示。
201.007.jpg


四、核心代码(带注释)

  1. #include "delay.h"
  2. #include "sys.h"
  3. #include "lcd.h"
  4. #include "dht11.h"
  5. #include "ds1302.h"
  6. #include "KEY.h"
  7. #include "beep.h"
  8. u8 temp;
  9. u8 humi;
  10. u8 t=0;            
  11. u8 flag=0,flag1=0,flag2=0,flag3=1;
  12. u8 a,b,c;
  13. int min1=10,hour1=10;
  14. DHT11_Data_TypeDef DHT11_Data;
  15. void TIM3_Int_Init(u16 arr,u16 psc)
  16. {
  17.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  18.     NVIC_InitTypeDef NVIC_InitStructure;

  19.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

  20.     //定时器TIM3初始化
  21.     TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载计时器的值   
  22.     TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
  23.     TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
  24.     TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

  25.     TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
  26.     //中断优先级NVIC设置
  27.     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM中断
  28.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
  29.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //从优先级3级
  30.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  31.     NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
  32.     TIM_Cmd(TIM3, DISABLE);  //使能TIMx                    
  33. }
  34. void gui0(u8 mode)
  35. {
  36. LCD_ShowPicture(0,0,480,320);
  37. if(flag3==1)
  38. {
  39. LCD_ShowPicture3(445,0,479,34);
  40. }
  41. LCD_ShowChinese(0+40,0,0,BLUE,32,mode);//字
  42. LCD_ShowChinese(32+40,0,8,BLUE,32,mode);
  43. LCD_ShowChinese(64+40,0,9,BLUE,32,mode);
  44. LCD_ShowChinese(96+40,0,10,BLUE,32,mode);
  45. LCD_ShowNum(52,40,temp,2,BLUE,32,mode);//温度
  46. LCD_ShowChinese(132,40,12,BLUE,32,mode);

  47. LCD_ShowChinese(128+80+30,0,0,BLUE,32,mode);
  48. LCD_ShowChinese(160+80+30,0,8,BLUE,32,mode);
  49. LCD_ShowChinese(192+80+30,0,11,BLUE,32,mode);
  50. LCD_ShowChinese(224+80+30,0,10,BLUE,32,mode);
  51. LCD_ShowNum(248+30,40,humi,2,BLUE,32,mode);
  52. LCD_ShowChar(280+30,40,'%',BLUE,32,mode);

  53. LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间
  54. LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode);
  55. LCD_ShowChar(200,65,':',BLUE,160,mode);
  56. LCD_ShowNum(290,80,min/10,1,BLUE,160,mode);
  57. LCD_ShowNum(380,80,min%10,1,BLUE,160,mode);
  58. LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);
  59. LCD_ShowChinese(64,250,13,BLUE,32,mode);
  60. LCD_ShowNum(96,250,month,2,BLUE,32,mode);
  61. LCD_ShowChinese(128,250,14,BLUE,32,mode);
  62. LCD_ShowNum(160,250,day,2,BLUE,32,mode);
  63. LCD_ShowChinese(192,250,15,BLUE,32,mode);
  64. LCD_ShowChinese(224,250,16,BLUE,32,mode);
  65. LCD_ShowChinese(256,250,week,BLUE,32,mode);

  66. LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);
  67. LCD_ShowChar(33,283,':',BLUE,32,mode);
  68. LCD_ShowNum(50,283,min1,2,BLUE,32,mode);
  69. }
  70. void keyscan(u8 mode)
  71. {
  72. switch(t)
  73.                             {                                                      
  74.                                           case KEY0_PRES:
  75.     if(min1==min&&hour1==hour)
  76.    {
  77.     flag2=1;
  78.     BEEP(OFF);
  79.    }
  80.                                                         switch(flag)
  81.      {
  82.      case 1: hour++; if(hour>23)hour=0;LCD_ShowPicture2(20,80,190,240); LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间
  83. LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode);break;
  84.         case 2: min++;  if(min>59) min=0;LCD_ShowPicture2(290,80,460,240);LCD_ShowNum(290,80,min/10,1,BLUE,160,mode);
  85.                 LCD_ShowNum(380,80,min%10,1,BLUE,160,mode); break;
  86.         case 3: year++; LCD_ShowPicture2(0,250,64,282); LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);break;
  87.         case 4: month++; if(month>12) month=1;LCD_ShowPicture2(96,250,128,282);  LCD_ShowNum(96,250,month,2,BLUE,32,mode);break;
  88.         case 5: day++;   if(day>31) day=1; LCD_ShowPicture2(160,250,192,282);LCD_ShowNum(160,250,day,2,BLUE,32,mode); break;
  89.         case 6: week++; if(week>7)  week=1; LCD_ShowPicture2(256,250,288,282);LCD_ShowChinese(256,250,week,BLUE,32,mode);break;
  90.         case 7: hour1++; if(hour1>23)hour1=0;LCD_ShowPicture2(0,283,32,315); LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);break;
  91.         case 8: min1++;  if(min1>59)min1=0;LCD_ShowPicture2(50,283,82,315);LCD_ShowNum(50,283,min1,2,BLUE,32,mode);break;
  92.         case 9: flag3=1; LCD_ShowPicture3(445,0,479,34); break;
  93.                     default: break;
  94.      }
  95.                                                         break;
  96.                                           case KEY1_PRES:
  97.        if(min1==min&&hour1==hour)
  98.    {
  99.     flag2=1;
  100.     BEEP( OFF );
  101.    }
  102.                                           switch(flag)
  103.      {
  104.         case 1: hour--; if(hour<0)hour=23; LCD_ShowPicture2(20,80,190,240);LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间
  105. LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode); break;
  106.         case 2: min--;  if(min<0) min=59; LCD_ShowPicture2(290,80,460,240);LCD_ShowNum(290,80,min/10,1,BLUE,160,mode);
  107. LCD_ShowNum(380,80,min%10,1,BLUE,160,mode); break;
  108.         case 3: year--; LCD_ShowPicture2(0,250,64,282); LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);break;
  109.         case 4: month--; if(month<1) month=12; LCD_ShowPicture2(96,250,128,282); LCD_ShowNum(96,250,month,2,BLUE,32,mode);break;
  110.         case 5: day--;   if(day<1) day=31; LCD_ShowPicture2(160,250,192,282);LCD_ShowNum(160,250,day,2,BLUE,32,mode);  break;
  111.         case 6: week--; if(week<1)  week=7; LCD_ShowPicture2(256,250,288,282);LCD_ShowChinese(256,250,week,BLUE,32,mode); break;
  112.         case 7: hour1--; if(hour1<0)hour1=23;LCD_ShowPicture2(0,283,32,315); LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);break;
  113.         case 8: min1--;  if(min1<0)min1=59;LCD_ShowPicture2(50,283,82,315);LCD_ShowNum(50,283,min1,2,BLUE,32,mode);break;
  114.         case 9: flag3=0; LCD_ShowPicture2(445,0,480,36);break;
  115.                     default: break;
  116.      }
  117.                                                         break;
  118.                                           case WKUP_PRES:                                         
  119.                                                         cc1();flag++;
  120.            switch(flag)
  121.   {
  122.     case 1:  TIM_Cmd(TIM3, DISABLE); LCD_DrawLine(20,242,190,243,BLUE);break;
  123.     case 2: LCD_ShowPicture1(242,243);LCD_DrawLine(290,242,460,243,BLUE);   break;
  124.     case 3: LCD_ShowPicture1(242,243); LCD_DrawLine(0,287,64,288,BLUE);break;
  125.     case 4: LCD_ShowPicture1(287,288);LCD_DrawLine(96,287,128,288,BLUE);break;
  126.     case 5: LCD_ShowPicture1(287,288);  LCD_DrawLine(160,287,192,288,BLUE); break;
  127.     case 6: LCD_ShowPicture1(287,288);LCD_DrawLine(256,287,288,288,BLUE); break;
  128.     case 7: LCD_ShowPicture1(287,288);  LCD_DrawLine(0,316,32,317,BLUE);break;
  129.     case 8: LCD_ShowPicture1(316,317); LCD_DrawLine(50,316,82,317,BLUE);break;
  130.     case 9: LCD_ShowPicture1(316,317); LCD_DrawLine(445,37,479,38,BLUE);break;
  131.     case 10: LCD_ShowPicture2(445,37,479,38); ds_wtime();a=sec;b=min;c=hour;TIM_Cmd(TIM3, ENABLE);flag=0;break;
  132.                             default:                break;
  133.               }
  134.          break;
  135.    default:               delay_ms(5);              break;
  136. }
  137. }
  138. int main(void)
  139. {
  140.               delay_init();                  
  141.               NVIC_Configuration();              
  142.   DHT11_Init ();
  143.   KEY_Init();
  144.   BEEP_GPIO_Config();            
  145.   BEEP( OFF );
  146.   TIM3_Int_Init(9999,7199);
  147.   ds1302_init();
  148.   ds_read_time();
  149.   cc();
  150.   a=sec;
  151.   b=min;
  152.   c=hour;
  153.   Lcd_Init();                                         
  154.   LCD_Clear(WHITE);
  155.   gui0(1);
  156.   TIM_Cmd(TIM3, ENABLE);
  157.               while(1)
  158. {            
  159. t=KEY_Scan(0);
  160.   keyscan(1);
  161.    if( DHT11_Read_TempAndHumidity (&DHT11_Data ) == SUCCESS&&flag==0)
  162. {
  163.    temp=DHT11_Data.temp_int;
  164.    humi=DHT11_Data.humi_int;
  165. LCD_ShowPicture2(52,40,84,72);
  166. LCD_ShowPicture2(278,40,310,72);
  167. LCD_ShowNum(52,40,temp,2,BLUE,32,1);
  168. LCD_ShowNum(278,40,humi,2,BLUE,32,1);
  169. }
  170. if(flag==0&&min1==min&&hour1==hour&&flag2==0&&flag3==1)
  171. {
  172. BEEP( ON );
  173. }
  174. }
  175. }
复制代码

您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-4-19 21:05

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表