精华内容
下载资源
问答
  • 2020-12-18 19:37:50

    一、实现的功能

    1.实现STM32进入停止模式,并利用外部中断线唤醒来推出停止模式。

    2.实现外部按键和RTC报警两个外部中断来唤醒进入停止模式的STM32。

    二、实验操作及现象

    1.双击PWR.eww打开工程文件,然后进行编译。

    2.用Flash Loader将程序下载到ARM内,或者利用JLINK等仿真器进行仿真。

    3.程序运行后可根据4个LED灯来判断STM32当前的运行状态:

    LD1亮、LD4灭表示处于运行状态;

    LD1灭、LD4亮表示处于停止模式;

    LD2的取反状态代表由外部中断9(User按键)来唤醒STM32;

    LD3的取反状态代表由外部中断17(RTC报警)来唤醒STM32;

    三、电源管理学习

    STM32的电源组成,其主要由3个部分:独立的A/D供电电压和参考电压、备份电压、电压调节器。

    1.A/D供电电压和参考电压

    为了提高转换的精确度,ADC使用一个独立的电源供电(VDDA,范围:2.4V~3.6V),过滤和屏蔽来自PCB上的毛刺干扰。

    参考电压VREF+和VREF-分别是正和负极,一般VREF-接地,VREF+的范围为VREF-~VDDA,这个电源100脚封装芯片和其他封装芯片不同,100脚的这个电压和A/D供电电压是独立的,而其他封装它们是内部直接连接的。

    2.备份电压

    备份电压指的是备份域使用的供电电源,也就是VBAT引脚的供电,使用电池或其他电源连接到VBAT脚上,当VDD断电时,可以保存备份寄存器的内容。VBAT脚也为RTC供电,这保证当主要电源被切断时RTC能继续工作。如果应用中没有使用外部电池,VBAT必须连接到VDD引脚上。

    3.电压调节器

    电压调节器为STM32提供所需的1.8V电源,也就是内部把你提供的3.3V转换成1.8V,供STM32使用,其主要有三种工作模式:

    -运行模式:以正常功耗模式提供1.8V 电源(内核,内存和外设)。

    -停止模式:以低功耗模式提供1.8V 电源,以保存寄存器和SRAM 的内容。

    -待机模式:停止供电。除了备用电路和备份域外,寄存器和SRAM 的内容全部丢失。

    4.电源管理器(PVD)

    电源管理器的第1部分是上电复位(POR)和掉电复位(PDR):当电源小于POR和/或PDR门限时,系统处于复位状态,其他时间处于正常工作状态。

    电源管理器的第2部分是可编程电压监测器:

    -用户可以利用PVD对VDD电压与电源控制寄存器中的PLS[2:0]位进行比较来监控电源,这几位选择监控电压的阀值。

    -通过设置PVDE位来使能PVD。

    -电源控制/状态寄存器中的PVDO标志用来表明VDD是高于还是低于PVD的电压阀值。该事件在内部连接到外部中断的第16线。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。这一特性可用于用于执行紧急关闭任务。

    电源管理器的第3部分是低功耗模式,共有睡眠、停止、待机3种低功耗模式。

    睡眠模式:在睡眠模式下,CPU时钟处于停止状态,但是所有的外设继续运行(除非它们被关闭)电源功耗相应地减少。任一中断或唤醒事件可将微处理器从睡眠模式中唤醒。在睡眠模式下,所有的SRAM和寄存器内的内容被保存下来。睡眠模式有2种,一种是通过执行WFI进入睡眠模式,任意一个被嵌套向量中断控制器响应的外设中断都能将系统从睡眠模式唤醒 ;令一种是执行WFE 指令进入睡眠模式,外设控制寄存器中被使能的中断事件,但该中断事件未被嵌套向量中断控制器使能,或者设置为事件模式的外部中断线上的事件可以将系统从睡眠模式唤醒。

    停止模式:停止模式是在Cortex-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE,RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。

    进入停止模式:

    – 设置Cortex-M3系统控制寄存器中的SLEEPDEEP位

    – 清除电源控制寄存器(PWR_CR)中的PDDS位

    - 通过设置PWR_CR中LPDS位选择电压调节器的模式

    在以上条件下执行行WFI或WFE指令进入停止模式。

    退出停止模式:

    如果是使用WFI进入的停止模式,则任一外部中断线产生中断可以唤醒系统,如果是使用WFE禁止的停止模式,则任一外部中断线产生事件可以唤醒系统。

    待机模式:待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。

    进入待机模式

    在以下条件下执行WFI或WFE指令进入待机模式:

    – 设置Cortex-M3系统控制寄存器中的SLEEPDEEP位

    – 设置电源控制寄存器(PWR_CR)中的PDDS位

    – 清除电源控制/状态寄存器(PWR_CSR)中的WUF位被

    退出待机模式

    当一个外部复位(NRST引脚)、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件发生时,微控制器从待机模式退出。

    最后是低功耗模式下的自动唤醒:RTC可以唤醒低功耗模式下的微控制器(自动唤醒模式)。RTC可以按照可编程周期从停止或待机模式下唤醒微控制器。通过对备份区域控制寄存器的RTCSEL[1:0]位的编程,三个RTC时钟源中的二个可以选作实现此功能:

    -低功耗32.768kHz 外部晶振(LSE OSC)

    -低功耗内部RC 振荡器(LSI RC)

    为了用RTC闹钟事件将微处理器从停止模式下唤醒,必须进行如下操作:

    -配置外部中断线17 为上升沿触发。

    -配置RTC 使其可产生RTC 闹钟事件。

    如果要从待机模式中唤醒,不必配置外部中断线17。

    四、程序流程分析

    程序流程见附件《STM32例程之PWR流程图.pdf》

    五、代码例程(不包括库文件)

    程序的IAR例程工程见附件“PWR.rar”

    更多相关内容
  • stm32数码管显示实时时间并有闹钟功能

    千次阅读 热门讨论 2021-06-20 21:18:15
    stm32数码管显示实时时间并有闹钟功能功能描述数码管介绍数码管芯片段选与位选驱动数码管显示stm32开发板介绍完整代码main.h 功能描述 数码管介绍 数码管芯片 段选与位选 驱动数码管显示 stm32开发板介绍 完整代码 ...

    功能描述

    通过stm32开发板上面的按键来实现时钟的调节和闹钟调节并响铃

    数码管介绍

    2个74HC595来驱动8位共阳数码管
    共阳数码管0-9编码表:0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90

    数码管芯片

    74HC595是串行输入,并行输出的锁存器在这里插入图片描述
    DS:14脚,串行数据输入引脚
    OE:13脚,输出使能控制脚,它是低电才使能输出,所以接GND
    ST_CP:12脚,存储寄存器时钟输入引脚。上升沿时,数据从移位寄存器转存带存储寄存器。
    SH_CP:11脚,移位寄存器时钟引脚,上升沿时,移位寄存器中的数据整体后移,并接受新的数据(从DS输入)
    MR:10脚,低电平时,清空移位寄存器中已有的数据,一般不用,接高电平即可。
    Q7’:9脚,串行数据输出引脚。当移位寄存器中的数据多于8位时,会把已有的位“挤出去”,就是从这里出去的。用于595的级联
    Q1-Q7:1到7脚,并行输出引脚
    74HC595具体介绍

    段选与位选

    位选:选择哪一个数码段点亮
    段选:选择点亮的数码管显示什么数字
    进行位选和段选时,要先进行透明在进行锁存,这样才能进行显示。

    驱动数码管显示代码

    void Smg_Diaplay()
    {
    	u8 i;
    	for(i=0;i<8;i++)
    	{
    		GPIOA->ODR=~(1<<i);//选择哪一个数码管亮
    		GPIO_SetBits(GPIOA,GPIO_Pin_8);//位透明模式
    		GPIO_ResetBits(GPIOA,GPIO_Pin_8);//段锁存模式
    		GPIOA->ODR=DisPlayData[i];//数据输入
    		GPIO_SetBits(GPIOA,GPIO_Pin_9);//位透明
    		GPIO_ResetBits(GPIOA,GPIO_Pin_9);//段锁存
    	}
    }
    

    实验思路

    1、让数码管亮,能直接在代码中设置数字让其显示
    2、让数码管的1、2,4、5,7、8位分别显示秒,分,时的数字;3、5位显示短线表示分割
    3、设置定时器3,让其定时1秒,控制秒的改变,进而控制分和时
    4、设置按键,控制分和时的增加,从而改变当前时间。此时应该停止定时器3的计数,方便进行调整
    5、在设置一个定时器2定时1秒来控制闹钟的计数
    6、设置按键,控制闹钟分和时的改变,此时应该让定时器2停止定时,定时器3继续计数
    7、设置一个函数来计算设置的闹钟时间与当前时间的差值,让定时器进行计数,当计数值达到差值时,蜂鸣器响,否则不响

    完整代码

    Led.h

    #ifndef __LED_H
    #define __LED_H	 
    
    void LED_Init(void);//初始化
    			    
    #endif
    

    Led.c

    #include "led.h"
    #include "stm32f10x.h"
    
    //LED IO初始化
    void LED_Init(void)
    {
     
     GPIO_InitTypeDef  GPIO_InitStructure;
     	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);	
    	
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
     GPIO_Init(GPIOB, &GPIO_InitStructure);			
    	
     GPIO_SetBits(GPIOB,GPIO_Pin_5);//输出高
    
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED1
     GPIO_Init(GPIOE, &GPIO_InitStructure);	
    	
     GPIO_SetBits(GPIOE,GPIO_Pin_5);  //输出高 
    }
    

    Key.h

    #ifndef __KEY_H
    #define __KEY_H	 
    
    void Key_Init(void);
    				    
    #endif
    

    Key.c

    #include "stm32f10x.h"
    #include "key.h"
    
    extern u8 sec,min,hour;
    								    
    void Key_Init(void)
    { 
     	GPIO_InitTypeDef GPIO_InitStructure;
     
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOE,ENABLE);
    
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4 | GPIO_Pin_3;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
     	GPIO_Init(GPIOE, &GPIO_InitStructure);
    
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉	  
    	GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    }
    

    beep.h

    #ifndef __BEEP_H
    #define __BEEP_H	    
    
    void Beep_Init(void);	//初始化
    		 				    
    #endif
    

    beep.c

    #include "beep.h"
    #include "stm32f10x.h"   
    
    void Beep_Init(void)
    {
     
     GPIO_InitTypeDef  GPIO_InitStructure;
     	
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
     
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOB, &GPIO_InitStructure);
     
     GPIO_ResetBits(GPIOB,GPIO_Pin_8);//关闭蜂鸣器输出
    }
    

    smg.h

    #ifndef __SMG_H
    #define __SMG_H			
    
    #include "stm32f10x.h"
    
    //#define RCLK PBout(10)//时钟脉冲信号——上升沿有效
    //#define SCLK PBout(11)//打入信号————上升沿有效
    //#define DIO  PAout(8)//串行数据输入
    
    void Smg_Init(void);
    void Smg_DisPlay(void);
    void Display_Data(u8 hour,u8 min,u8 sec);// Smg显示
    void Smg_OUT(u8 X);// Smg单字节串行移位函数
    
    #endif 
    

    smg.c

    #include "smg.h"
    #include "stm32f10x.h"
    #include "delay.h"
    
    extern u8 sec,min,hour;
    u16 smgduan[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
    //u16 smgduan[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
    u8 DisPlayData[8];
    
    void Smg_Init(void) //IO初始化 
    { 
     	GPIO_InitTypeDef GPIO_InitStructure;
     
     	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);//使能PORTA,PORTB时钟
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
      	GPIO_Init(GPIOB, &GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
      	GPIO_Init(GPIOB, &GPIO_InitStructure);
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
     	GPIO_Init(GPIOA, &GPIO_InitStructure);
    }	
    
    void Smg_DisPlay(void)
    {
    	u8 i;
    	for(i=0;i<8;i++)
    	{
    		Smg_OUT(DisPlayData[i]);			
    		Smg_OUT(0x01<<i);	
    		
    		//RCLK
    		GPIO_SetBits(GPIOB,GPIO_Pin_10);//位透明模式
    		GPIO_ResetBits(GPIOB,GPIO_Pin_10);//锁存模式
    		
    		delay_ms(1);
    	}
    }
    
    void Display_Data(u8 hour,u8 min,u8 sec)
    {
    	DisPlayData[0] = smgduan[sec%10];//秒
    	DisPlayData[1] = smgduan[sec/10];
    	
    	DisPlayData[2] = 0xbf;
    	
    	DisPlayData[3] = smgduan[min%10];//分
    	DisPlayData[4] = smgduan[min/10];
    	
    	DisPlayData[5] = 0xbf;
    	
    	DisPlayData[6] = smgduan[hour%10];//时
    	DisPlayData[7] = smgduan[hour/10];
    }
    
    void Smg_OUT(u8 x)
    {
    	u8 i;
    	for(i=8;i>=1;i--)
    	{
    		if(x&0x80) 
    			GPIO_SetBits(GPIOA,GPIO_Pin_8);
    		else 
    			GPIO_ResetBits(GPIOA,GPIO_Pin_8);
    		x<<=1;
    		//SCLK
    		GPIO_SetBits(GPIOB,GPIO_Pin_11);//段透明模式
    		GPIO_ResetBits(GPIOB,GPIO_Pin_11);
    	}
    }
    
    /*
    void Showtime()//时间显示
    {
    	u8 i;
    	delay_init();
    	for(i=0;i<8;i++)
    	{
    		GPIOA->ODR=~(1<<i);//选位
    		GPIO_SetBits(GPIOA,GPIO_Pin_8);//透明模式
    		GPIO_ResetBits(GPIOA,GPIO_Pin_8);//锁存模式
    		GPIOA->ODR=DisPlayData[i];
    		GPIO_SetBits(GPIOA,GPIO_Pin_9);//透明模式
    		GPIO_ResetBits(GPIOA,GPIO_Pin_9);
    		delay_ms(1);
    	}
    }
    */
    

    timer.h

    #ifndef __TIMER_H
    #define __TIMER_H
    
    #include "stm32f10x.h"
    
    void Timer3_Init(u16 arr,u16 pse);
    void Timer2_Init(u16 arr,u16 pse);
    void TimeZJ();
    int CountTime(u8 h,u8 m);
    
    #endif
    

    timer.c

    #include "timer.h"
    #include "delay.h"
    #include "stm32f10x.h"
    #include "smg.h"
    
    extern u8 sec,min,hour;
    extern u16 count;
    
    //定时1s 4999 7199
    void Timer3_Init(u16 arr,u16 pse)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    	NVIC_InitTypeDef NVIC_InitStruct;
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    	
    	TIM_TimeBaseInitStruct.TIM_Period =  arr;
    	TIM_TimeBaseInitStruct.TIM_Prescaler =  pse;
    	TIM_TimeBaseInitStruct.TIM_CounterMode =  TIM_CounterMode_Up;
    	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
    	
    	NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority =2;
    	NVIC_Init(&NVIC_InitStruct);
    	
    	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
    	
    	TIM_Cmd(TIM3,ENABLE);
    }
    
    void Timer2_Init(u16 arr,u16 pse)
    {
    	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    	NVIC_InitTypeDef NVIC_InitStruct;
    	
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    	
    	TIM_TimeBaseInitStruct.TIM_Period =  arr;
    	TIM_TimeBaseInitStruct.TIM_Prescaler =  pse;
    	TIM_TimeBaseInitStruct.TIM_CounterMode =  TIM_CounterMode_Up;
    	TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    	TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);
    	
    	NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
    	NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
    	NVIC_InitStruct.NVIC_IRQChannelSubPriority =2;
    	NVIC_Init(&NVIC_InitStruct);
    	
    	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
    	
    	TIM_Cmd(TIM2,DISABLE);
    }
    
    //时钟定时
    void TIM3_IRQHandler()
    {	
    	sec++;
    	TimeZJ();
    	TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    }
    
    //闹钟定时
    void TIM2_IRQHandler()
    {	
    	count++;
    	TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
    }
    
    void TimeZJ()
    {
    	if(sec >= 60)
    	{
    		sec=0;
    		min++;
    		if(min >= 60) 
    		{
    			min=0;
    			hour++;
    			if(hour >= 24) 
    			{
    				hour = 0;
    			}
    		}	
    	}
    }
    
    int CountTime(u8 h,u8 m)
    {
     if(h > hour)
    	 return (h - hour - 1) * 3600 + (60 - min + m) * 60;
     else if(h < hour)
    	 return (23 - hour + h) * 3600 + (60 - min + m) * 60;
     else
    	 if(m >= min)
    		 return (m - min) * 60;
    	 else
    		 return (23 - hour + h) * 3600 + (60 - min + m) * 60;
    }
    

    main.c

    #include "stm32f10x.h"
    #include "Key.h"
    #include "Led.h"
    #include "delay.h"
    #include "smg.h"
    #include "timer.h"
    #include "delay.h"
    #include "beep.h"
    
    u8 sec,min,hour;//时钟
    u8 h,m,s;//闹钟
    u8 setflag;//时间设置
    u8 a = 0;
    u16 count;
    u8 countflag;//闹钟设置
    u8 flag;//响铃
    
    int main()
    {
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    	Timer3_Init(9999,7199);
    	Timer2_Init(9999,7199);
    	LED_Init();
    	Key_Init();
    	delay_init();
    	Smg_Init();
    	Beep_Init();
    	
    	hour = 12;
    	min = 14;
    	sec = 15;
    	
    	h = 0;
    	m = 0;
    	s = 0;
    	
    	while(1)
    	{		
    		//实时时间显示
    		Smg_DisPlay();
    		Display_Data(hour,min,sec);
    		
    		//时间设置
    		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)//WK_UP
    		{
    			delay_ms(10);
    			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
    			{
    				while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)));
    				setflag = 1;
    				TIM_Cmd(TIM3,DISABLE);
    			}
    		}
    		while(setflag)
    		{
    			GPIO_ResetBits(GPIOB,GPIO_Pin_5);//亮 LED0
    			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
    			{
    				//退出
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
    				{
    					//消抖
    					while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)));
    					setflag = 0;
    					TIM_Cmd(TIM3,ENABLE);
    					GPIO_SetBits(GPIOB,GPIO_Pin_5);//灭
    					break;
    				}
    			}
    			if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)//KEY1 hour
    			{
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)
    				{
    					while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)));
    					hour++;
    					if(hour == 24)
    						hour = 0;
    				}
    			}
    			if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)//KEY0 min
    			{
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)
    				{
    					while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)));
    					min++;
    					if(min == 60)
    						min = 0;
    				}
    			}
    			Smg_DisPlay();
    			Display_Data(hour,min,sec);
    		}
    	
    		//闹钟设置
    		if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)//KEY0
    		{
    			delay_ms(10);
    			if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)
    			{
    				while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)));
    				countflag = 1;//进入设置闹钟模式
    				if(a == 0)
    				{
    					a = 1;
    					TIM_Cmd(TIM2,DISABLE);
    				}
    				else
    				{
    					a = 0;
    					countflag = 0;//退出定时模式
    					TIM_Cmd(TIM2,ENABLE);//开启定时器
    					count = 0;
    				}
    			}
    		}
    		while(countflag)
    		{
    			GPIO_ResetBits(GPIOE,GPIO_Pin_5);//亮 LED1
    			if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)//KEY0
    		  {
    				//退出设置闹钟模式 进入时钟运行模式
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4) == 0)
    				{
    					while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)));
    					countflag = 0;
    					flag = 1;
    					TIM_Cmd(TIM2,ENABLE);//开启定时器2定时
    					GPIO_SetBits(GPIOE,GPIO_Pin_5);//灭
    					break;
    				}
    		  }
    			if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)//KEY1 h
    			{
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)
    				{
    					while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)));
    					m++;
    					if(m == 60)
    						m = 0;
    				}
    			}
    			if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)//WK_UP m
    			{
    				delay_ms(10);
    				if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 1)
    				{
    					while((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)));
    					h++;
    					if(h == 24)
    						h = 0;
    				}
    			}
    			Smg_DisPlay();
    			Display_Data(h,m,s);
    		}
    		
    		//响铃
    		while(flag)
    		{
    			Smg_DisPlay();
    			Display_Data(hour,min,sec);
    			if(count == CountTime(h,m))
    			{
    				GPIO_SetBits(GPIOB,GPIO_Pin_8);//开
    				GPIO_ResetBits(GPIOB,GPIO_Pin_5);//LED0 亮
    				delay_ms(100);
    				if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)//KEY1
    				{
    					delay_ms(10);
    					if(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3) == 0)
    					{
    						while(!(GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)));
    						flag = 0;
    						GPIO_ResetBits(GPIOB,GPIO_Pin_8);//关
    						GPIO_SetBits(GPIOB,GPIO_Pin_5);//灭 LED0
    						TIM_Cmd(TIM2,DISABLE);
    						break;
    					}
    				}
    			}
    		}
    	}
    	return 0;
    }
    

    实验难点

    1、在进行闹钟设置时,会与当前的时钟产生矛盾,设置闹钟会改变时钟;
    2、如何让闹钟的时间与当前时间进行比较;
    3、当闹钟响铃时,按下按键还会响不会停或者闹钟响铃关闭时钟时间回到初始状态。

    解决方法

    1、在进行闹钟设置时在使用一个定时器来专门控制闹钟;一个定时器控制时钟。
    2、使用一个函数来计数当前时间到闹钟的时间一共有多少秒,用一个定时器来进行计数并于这个时间进行比较,当两则相等时则表示闹钟一个响铃。在遇到闹钟问题时去询问了同学。
    3、闹钟响铃时与时钟设置和闹钟设置时一样放入一个while()函数,但是在进入此函数和退出此函数是要进行变量设置,而且闹钟响铃后关闭闹钟的定时器。

    总结

    在进行时钟定时时,定时器的预分频系数和重装载值要设置正确,要为1秒。遇到问题时要去询问同学或查找相关资料。闹钟设置时一个难点,进行设置时要与时钟的设置区分开,否则很容易两则产生矛盾。

    源码获取

    GitHub stm32 mini版
    GitHub stm32 精英版

    展开全文
  • STM32F103系列的单片机一共有11个定时器,其中:2个高级定时器4个普通定时器2个基本定时器2个看门狗定时器1个系统嘀嗒定时器除去看门狗定时器和系统滴答定时器的八个定时器列表;8个定时器分成3个组;TIM1和TIM8是...

    STM32F103系列的单片机一共有11个定时器,其中:

    2个高级定时器

    4个普通定时器

    2个基本定时器

    2个看门狗定时器

    1个系统嘀嗒定时器

    除去看门狗定时器和系统滴答定时器的八个定时器列表;

    e83d60175dd9344daa2b67b14974017a.png

    8个定时器分成3个组;

    TIM1和TIM8是高级定时器

    TIM2-TIM5是通用定时器

    TIM6和TIM7是基本的定时器

    这8个定时器都是16位的,它们的计数器的类型除了基本定时器TIM6和TIM7都支持向上,向下,向上/向下这3种计数模式

    计数器三种计数模式

    向上计数模式:从0开始,计到arr预设值,产生溢出事件,返回重新计时

    向下计数模式:从arr预设值开始,计到0,产生溢出事件,返回重新计时

    中央对齐模式:从0开始向上计数,计到arr产生溢出事件,然后向下计数,计数到1以后,又产生溢出,然后再从0开始向上计数。(此种技术方法也可叫向上/向下计数)

    基本定时器(TIM6,TIM7)的主要功能:

    只有最基本的定时功能,。基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动

    通用定时器(TIM2~TIM5)的主要功能:

    除了基本的定时器的功能外,还具有测量输入信号的脉冲长度( 输入捕获) 或者产生输出波形( 输出比较和PWM)

    高级定时器(TIM1,TIM8)的主要功能:

    高级定时器不但具有基本,通用定时器的所有的功能,还具有控制交直流电动机所有的功能,你比如它可以输出6路互补带死区的信号,刹车功能等等

    通用定时器的时钟来源;

    a:内部时钟(CK_INT)

    b:外部时钟模式1:外部输入脚(TIx)

    c:外部时钟模式2:外部触发输入(ETR)

    d:内部触发输入(ITRx):使用一个定时器作为另一个定时器的预分频器

    通用定时期内部时钟的产生:

    从截图可以看到通用定时器(TIM2-7)的时钟不是直接来自APB1,而是通过APB1的预分频器以后才到达定时器模块。

    当APB1的预分频器系数为1时,这个倍频器就不起作用了,定时器的时钟频率等于APB1的频率;

    当APB1的预分频系数为其它数值(即预分频系数为2、4、8或16)时,这个倍频器起作用,定时器的时钟频率等于APB1时钟频率的两倍。

    自动装在寄存器arr值的计算:

    Tout= ((arr+1)*(psc+1))/Tclk;

    Tclk:TIM3的输入时钟频率(单位为Mhz)。

    Tout:TIM3溢出时间(单位为us)。

    计时1S,输入时钟频率为72MHz,加入PSC预分频器的值为35999,那么:

    ((1+psc )/72M)*(1+arr )=((1+35999)/72M)*(1+arr)=1秒

    则可计算得出自动窗装载寄存器arr=1999

    通用定时器PWM工作原理

    以PWM模式2,定时器3向上计数,有效电平是高电平,定时器3的第3个PWM通道为例:

    定时器3的第3个PWM通道对应是PB0这引脚,三角顶点的值就是TIM3_ARR寄存器的值,上图这条红线的值就TIM3_CCR3

    当定时器3的计数器(TIM3_CNT)刚开始计数的时候是小于捕获/比较寄存器(TIM3_CCR3)的值,此时PB0输出低电平,随着计数器(TIM3_CNT)值慢慢的增加,当计数器(TIM3_CNT)大于捕获/比较寄存器(TIM3_CCR3)的值时,这时PB0电平就会翻转,输出高电平,计数器(TIM3_CNT)的值继续增加,当TIM3_CNT=TIM3_ARR的值时,TIM3_CNT重新回到0继续计数,PB0电平翻转,输出低电平,此时一个完整的PWM信号就诞生了。

    PWM输出模式;

    STM32的PWM输出有两种模式:

    模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。区别如下:

    110:PWM模式1,在向上计数时,一旦TIMx_CNT

    在向下计数时,一旦TIMx_CNT》TIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。

    111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。

    由以上可知:

    模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式

    PWM的输出管脚:

    不同的TIMx输出的引脚是不同(此处设计管脚重映射)

    TIM3复用功能重映射:

    注:重映射是为了PCB的设计方便。值得一提的是,其分为部分映射和全部映射

    PWM输出频率的计算:

    PWM输出的是一个方波信号,信号的频率是由TIMx的时钟频率和TIMx_ARR这个寄存器所决定的输出信号的占空比则是由TIMx_CRRx寄存器确:

    占空比=(TIMx_CRRx/TIMx_ARR)*100%

    PWM频率的计算公式为:

    其中

    F就是PWM输出的频率,单位是:HZ;

    ARR就是自动重装载寄存器(TIMx_ARR);

    PSC 就是预分频器(TIMx_PSC);

    72M就是系统的频率;

    STM32 高级定时器PWM的输出

    一路带死区时间的互补PWM的波形图

    STM32F103VC这款单片机一共有2个高级定时器TIM1和TIM8

    这2个高级定时器都可以同时产生3路互补带死区时间的PWM信号和一路单独的PWM信号,

    具有刹车输入功能,在紧急的情况下这个刹车功能可以切断PWM信号的输出

    还具有支持针对定位的增量(正交)编码器和霍尔传感器电路

    高级控制定时器(TIM1 和TIM8) 由一个16位的自动装载计数器组成,它由一个可编程的预分频器驱动

    它适合多种用途,包含测量输入信号的脉冲宽度( 输入捕获) ,或者产生输出波形(输出比较、PWM、嵌入死区时间的互补PWM等)。

    使用定时器预分频器和RCC时钟控制预分频器,可以实现脉冲宽度和波形周期从几个微秒到几个毫秒的调节。

    高级控制定时器(TIM1 和TIM8) 和通用定时器(TIMx) 是完全独立的,它们不共享任何资源死区时间

    H桥电路为避免由于关断延迟效应造成上下桥臂直通,有必要设置死区时间死区时间可有效地避免延迟效应所造成的一个桥臂未完全关断,而另一桥臂又处于导通状态,避免直通炸开关管。

    死区时间越大,电路的工作也就越可靠,但会带来输出波形的失真以及降低输出效率。死区时间小,输出波形要好一些,但是会降低系统的可靠性,一般这个死区时间设置为us级元器件死区时间是不可以改变的,它主要是取决于元器件的制作工艺和材料!

    原则上死区时间当然越小越好。设置死区时间的目的,其实说白了就是为了电路的安全。最佳的设置方法是:在保证安全的前提下,设置的死区时间越小越好。以不炸功率管、输出不短路为目的。

    STM32死区时间探究设置寄存器:就是刹车和死区控制寄存器(TIMx_BDTR)

    这个寄存器的第0—7位,这8个位就是用来设置死区时间的,使用如下:

    以TIM1为例说明其频率是如何产生的。

    定时器1适中产生路线:

    系统时钟-》 AHB预分频 -》 APB2预分频 –》 TIM1倍频器–》 产生TIM1的时钟系统流程图看可以看出,要想知道TIM1的时钟,就的知道系统时钟,AHB预分频器的值,还有APB2预分频器的值,只要知道了这几个值,即可算出TIM1的时钟频率?

    这些值从何来,在“SystemInit()”这个时钟的初始化函数中已经给我们答案了,在这个函数中设置的系统时钟是72MZ,AHB预分频器和APB2预分频器值都是设置为1,由此可算出:TIM1时钟频率:72MHZ了,TDTS=1/72MHZ=13.89nsTdtg死区时间步进值,它的值是定时器的周期乘以相应的数字得到的

    下面看看官方给的公式如何使用,如下:DTG[7:5]=0xx=》DT=DTG[6:0]×Tdtg,Tdtg=TDTS

    首先由DTG[7:5]=0xx可以知道的是:DTG的第7位必须为0,剩余的0~6这7位可配置死区时间,假如TIM1的时钟为72M的话,那么由公式Tdtg=TDTS可计算出:TDTS=1/72MHZ=13.89ns。

    有了这个值,然后通过公式DT=DTG[6:0]×Tdtg即可计算出DT的值。

    如果DTG的第0~6位均为0的话,DT=0

    如果DTG的第0~6位均为1的话,DT=127*13.89ns=1764ns

    如果TIM1的时钟为72M的话,公式1可设置的死区时间0~1764ns,也就是说:如果你的项目需要输出的PWM信号要求的死区时间是0——1764ns的时候你就可以用公式1同样可计算出4个公式的死去区间,如下:

    公式1:DT=0~1764ns

    公式2:DT=1777.9ns~3528.88ns

    公式3:DT=3555.84ns~7000.56ns

    公式4:DT=7111.68ns~14001.12ns

    死区时间的设置:

    假如我们设计了一个项目要求输出的PWM信号中加入一个3us的死区时间因为3us这个值在第二个公式决定的死区范围之内所以选择第二个公式。3000/(13.89*2)=108,所以DTG[5:0]=108-64=44所以DTG=127+44+32=203=0XCB,TIM1-》BDTR“=0Xcb

    这里为什么要在加上一个32那?在公式2中DTG的第5位是一个X,也就是说这一位可以设置为高电平,也可以设置为低电平,在这里我们将这一位设置为了高电平,所有要在加上一个32.如此而已!

    展开全文
  • OLED 屏幕显示时间,温度。时间可以校准,屏幕通过取模,可以显示汉字。
  • STM32闹钟 STM32 闹钟的 Keil uVision4 项目。 流程图
  • STM32CubeMX 实现 LED 亮灭----中断模式 文章目录STM32CubeMX 实现 LED 亮灭----中断模式1、了解中断2、EXTI—外部中断/事件控制器3、中断模式实现 LED 亮灭3.1 利用CubeMX 生成工程3、2添加代码3、3编译,烧录3、4...

    STM32CubeMX 实现 LED 亮灭----中断模式

    1、了解中断

    中断全过程

    中断发生 当CPU在处理某一事件A时,发生了另一事件B,请求 CPU迅速去处理

    中断处理 CPU暂停当前的工作,转去处理事件B

    中断返回 当CPU将事件B处理完毕后,再回到事件A中被暂停的 地方继续处理事件A

    中断程序执行过程示意图

    image-20211103233932787

    中断优先级

    处理器根据不同中 断的重要程序设置 不同的优先等级。 不同优先级中断的 处理原则是:高级 中断可以打断低级 中断;低级中断不 能打断高级中断

    image-20211103234144118

    中断服务程序

    在响应一个特定中断的时候,处理器会执行一个函数,该函数一般称为 中断处理程序或者中断服务程序

    中断通道

    微控制器片内集成了很多外设,对于单个外设而言,它通常具备若干个可以 引起中断的中断源,而该外设的所有中断源只能通过指定的中断通道向内核 申请中断

    2、EXTI—外部中断/事件控制器

    何为EXTI

    EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20 个中断/事件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿 检测和下降沿的检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为 中断或者事件,以及触发事件的属性

    外部中断控制器

    1、管理23个外部中断线(EXTI Line)

    2、 0~15号外部中断线用于由GPIO引脚触发的外部中断

    3、 16~22号外部中断线用于RTC闹钟事件、以太网唤醒事件和 USB唤醒事件等

    4、 当对应GPIO引脚与外部中断线连接后,GPIO引脚才具备外部 中断的功能,可以设置外部中断的触发方式

    EXTI 功能框图

    image-20211104000038703

    红色虚线指示的电路流程。它是一个产生中断的线路,最终信 号流入到 NVIC 控制器内。

    image-20211104000606472

    绿色虚线指示的电路流程。它是一个产生事件的线路,最终输出一 个脉冲信号

    image-20211104000934233

    产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功 能,这样是软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且 是电路级别的信号传输,属于硬件级的。

    中断/事件线

    EXTI 有 20 个中断/事件线,每个 GPIO 都可以被设置为输入线,占用 EXTI0 至 EXTI15, 还有另外七根用于特定的外设事件,

    image-20211104001409989

    EXTI0 至 EXTI15 用于 GPIO,通过编程控制可以实现任意一个 GPIO作为 EXTI的输入源,EXTI0 可以通过 AFIO 的外部中断配置寄存器 1(AFIO_EXTICR1)的 EXTI0[3:0]位选择配置为 PA0、PB0、PC0、PD0、PE0、PF0、PG0、PH0 或者 PI0

    image-20211104001644613

    3、中断模式实现 LED 亮灭

    用 STM32F103 核心板的 GPIOA 端一管脚接一个 LED,采用中断模式编程(即外部中断),当开关(GPIOB)接高电平时,LED 亮灯;接低电平时,LED 灭灯

    3.1 利用CubeMX 生成工程

    步骤如下

    1、创建新工程

    image-20211026202042382

    2、选择芯片

    image-20211026202224147

    3、点击下方的已经选择好的芯片进入工程

    image-20211026202530122

    4、在Pinout &Configuration 栏里,配置系统调试接口SYS,选择 Serial Wire

    image-20211026202838599

    5、配置外设,RCC设置,选择 HSE (外部高速时钟)为 Crystal/Ceramic Resonator

    image-20211026203008621

    6、GPIO 配置

    选择 LED 灯引脚 PA6,设置引脚为输出模式 GPIO_Output;
    选择作为外部中断的引脚 PB14,设置为与中断线 GPIO_EXTI14 连接

    image-20211104004024088

    7、GPIO 配置

    image-20211104005604153

    image-20211104005901672

    image-20211104010030652

    image-20211104011832770

    image-20211104012155789

    3、2添加代码

    将下面代码写入图中 main.c 的对应位置处

     void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 
    { 
    	if( GPIO_Pin == BEXTI_Pin ) // 判断外部中断源
    		{
    			HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); // 翻转LED状态
    		}
    }
    
    

    image-20211104013848370

    3、3编译,烧录

    image-20211104014942828

    image-20211104121936091

    3、4效果展示

    在这里插入图片描述

    4、总结

    本次实验中断模式控制 LED 亮灭,有利用CubeMX 来生成相关代码,节约许多时间。

    5、参考资料

    零死角玩转 STM32F103—指南者

    展开全文
  • 基于STM32的智能万年历设计

    万次阅读 多人点赞 2020-06-25 22:00:03
    其中以 STM32 内部的 RTC(实时时钟) 实现日历和时间的功能,通过修改计 数器的值可以重新设置系统的当前时间和日期。综上所述,此电子时钟具有读取方便、 显示直观、功能多样、电路简洁、成本低廉等诸多优点,...
  • 利用STM32内部RTC实现定时中断及断电工况下的定时脉冲输出背景功能描述实现过程 背景 利用内部RTC替换外部RTC,RTC采用单独的电源供电,实现在单片机主电源VDD断电情况下,单片机的一个特殊引脚能够输出固定频率的...
  • 基于STM32的电子时钟设计

    千次阅读 2021-10-21 16:49:53
    基于STM32的电子时钟设计1、设计目的2、设计具体要求3、proteus仿真4、程序代码 1、设计目的 (1)掌握使用KEIL MDK5进行软件开发的具体流程; (2)掌握硬件电路的设计方法; (3)掌握STM32微控制器的程序设计及...
  • STM32F10x RTC闹钟无效不触发的原因和解决方案 本篇文章希望通过自己解决RTC闹钟的问题经验帮助到您。 RTC闹钟原理 STM32F10x系列的RTC闹钟不同于STM32L系列,只有一个计数器。需要外部有一个RTC作为时钟晶振,...
  • STM32-时钟系统详解

    千次阅读 2022-03-02 10:19:17
    本节主要对STM32时钟系统进行讲解,我们从原理框图入手,对每一个时钟线路进行来源和去向的分析,介绍了时钟配置的相关寄存器以及STM32时钟的软件配置,最后通过SysTick定时器来编写延时函数。
  • 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能...
  • STM32 中断

    2022-02-16 18:56:53
    STM32 中断 1. 基础知识 1. Cortex-M3支持 256 个中断,其中包含了 16 个内核中断,240个外部中断。 2. STM32只有 84 个中断,包括 16 个内核中断和 68 个可屏蔽中断。 3. STM32F103上只有 60 个可屏蔽中断,F107上才有 ...
  • 2 方案选择 本设计选择了STM32F407ZET6作为主控芯片,这是因为该芯片最高能以168MHz工作,且直接内置晶振、模数转换器和数模转换器,便于简化设计电路,专注于实现系统的功能。 人体感应模块、身高测量模块、坐姿...
  • 传统的唤醒仪器,如普通闹钟,在闹铃工作的时候难以恰巧遇到被唤醒者的浅睡眠周期,而人在深度睡眠,如果受到外界突然且强烈的声音、光线等刺激,被唤醒的同时往往会对人体造成一定的危害,产生不良的影响。...
  • PS:连接到STM32开发板时,一定要记住不得将DHT11的VCC和GND短接,只要短接一下下就会烧掉、废了用不了。 2. 无线传输 推荐ESP8266模组(一个流行的WiFi模块),可以选用ESP-01S、也可以选用ESP-01,采用STA模式...
  • 本工程实现了在显示屏上显示...本工程使用的处理芯片为stm32f103rct6,显示屏芯片为ST7735S,WIFI模块为HC-25串口WIFI; 主要流程1显示屏的驱动程序编写,添加GUI显示库、Font.h来实现字符、汉字、图片的显示。 ...
  • 一、STM32外部中断介绍 STM32的每一个IO口都可以作为外部中断的中断输入口。STM32F103的中断控制器支持19个外部中断/事情请求。每个中断都设有状态位,每个中断/事件都有独立的触发和屏蔽设置。 STM32F103的19个...
  • 本次主要讲解STM32的外部中断以及使用STM32CubeMX编写中断程序,实现按键按下点亮LED灯。 STM32的中断介绍 中断是什么 我们可以暂时认为单片机的执行流程是单向的,这件事做完做下一件事。而中断顾名思义,就是当...
  • 基于STM32的“智能家居”课程设计

    万次阅读 2021-10-27 19:19:10
    基于STM32的“智能家居系统”课程设计
  • 龙源期刊网http://www.qikan.com.cn基于STM32的电子...本系统利用STM32内部RTC实时时钟模块,通过相应的软件配置和算法设计,实现电子万年历的功能,可以在LCD12864显示屏上实时显示当前的年、月、日、时、分、秒、...
  • STM32学习

    千次阅读 2022-03-21 09:01:51
    STM32功能强大、性能优异、片上资源丰富、功耗低,是一款经典的嵌入式微控制器 51单片机是8位,而STM3232位的,性能更优 STM32F103C8T6芯片示例如下: 二、开发 1、使用软件 Keil5 MDK ...
  • 本文以 STM32F429 单片机为例对 RT_Thread 的 RTC-Alarm 的使用方法进行详细分析
  • 先来看看STM系列手册为例看看STM32的几种工作模式,小飞哥最近用到STM32G0系列的MCU,就拿G0的手册来聊一聊吧,其他的都类似,功耗方面有些差别 测试代码连接在文末评论区,可以下载测试 STM32系列MCU的几种工作...
  • STM32外部中断实验

    2021-09-29 17:28:21
    STM32 的每个 IO 都可以作为外部中断 的中断输入口,这点也是 STM32 的强大之处。STM32F103 的中断控制器支持 19 个外部中断/ 事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32F103 的 ...
  • stm32电子钟设计-课程设计报告.doc

    千次阅读 2020-12-21 13:59:20
    成绩成绩课程论文题 目: 基于STM32的多功能电子时钟学生姓名: 梁健学生学号: 1008050120系 别: 电气信息工程系专 业: 电子信息科学与技术年 级: 2010级任课教师: 郑晓东电气信息工程学院制2013年3月PAGE 4 .....
  • STM32中断——总结及实操一、中断是什么?1.1 中断的含义1.2 中断的作用(了解即可)1.3 中断的流程二、中断资源2.1 NVIC中断控制器2.2 NVIC寄存器三、优先级的概念四、中断编程 一、中断是什么? 1.1 中断的含义 ...
  • 1. STM32的外部中断线 2.外部中断线与IO引脚对应关系 3. 中断向量与服务函数 4.EXTI功能框图 三.外部中断配置(CUBEMX) 1.思维导图 2.工程配置 3.代码详解 一.外部中断介绍 首先我们要理解什么是中断。...
  • 目录STM32F1系列使用HAL库RTC时钟唤醒低功耗STOP和STANDBY模式(一)低功耗模式介绍1、睡眠模式2、停止模式3、待机模式4、快速应用了解(二)RTC周期闹钟唤醒STOP模式 不会使用HAL库驱动RTC可以先看这里:...
  • STM32-外部中断

    千次阅读 2021-10-02 22:07:22
    EXTI(External interrupt/event controller)—外部中断/事件控制器,和在STM32NVIC中断优先级管理(中断向量表)讲述的CM3内核的外部中断不同。特指的是,在中断向量表的EXTI的外部中断。STM32的每个IO都可以...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 246
精华内容 98
关键字:

stm32中实现闹钟功能的流程图