STM32F103RCT6开发板M3单片机教程06--定时器中断

news2024/11/27 3:41:48

前言


除非特别说明,本章节描述的模块应用于整个STM32F103xx微控制器系列,因为我们使用是STM32F103RCT6开发板是mini最小系统板。
本教程使用是(光明谷SUN_STM32mini开发板
 


STM32F10X定时器(Timer)基础


首先了解一下是STM32F10X定时器(Timer)


 

注:

小容量产品是指闪存存储器容量在16K至32K字节之间的STM32F101xx, STM32F102xx和STM32F103xx微控制器。
中容量产品是指闪存存储器容量在64K至128K字节之间的STM32F101xx, STM32F102xx和STM32F103xx微控制器。
大容量产品是指闪存存储器容量在256K至512K字节之间的STM32F101xx和STM32F103xx微控制器。

定时器类型


大容量的STM32F103xx增强型系列产品包含最多2个高级控制定时器、 4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器。
下表比较了高级控制定时器、普通定时器和基本定时器的功能:



高级控制定时器(TIM1和TIM8)


两个高级控制定时器(TIM1TIM8)可以被看成是分配到6个通道的三相PWM发生器,它具有带死区插入的互补PWM输出,还可以被当成完整的通用定时器。四个独立的通道可以用于:
● 输入捕获
● 输出比较
● 产生PWM(边缘或中心对齐模式)
● 单脉冲输出
配置为16位标准定时器时,它与TIMx定时器具有相同的功能。配置为16PWM发生器时,它具有全调制能力(0~100%)
在调试模式下,计数器可以被冻结,同时PWM输出被禁止,从而切断由这些输出所控制的开关。
很多功能都与标准的TIM定时器相同,内部结构也相同,因此高级控制定时器可以通过定时器链接功能与TIM定时器协同操作,提供同步或事件链接功能。


通用定时器(TIMx)


STM32F103xC、 STM32F103xDSTM32F103xE增强型系列产品中,内置了多达4个可同步运行的标准定时器(TIM2、 TIM3、 TIM4TIM5)。每个定时器都有一个16位的自动加载递加/递减计数器、一个16位的预分频器和4个独立的通道,每个通道都可用于输入捕获、输出比较、 PWM和单脉冲模式输出,在最大的封装配置中可提供最多16个输入捕获、输出比较或PWM通道。
它们还能通过定时器链接功能与高级控制定时器共同工作,提供同步或事件链接功能。在调试模式下,计数器可以被冻结。任一标准定时器都能用于产生PWM输出。每个定时器都有独立的DMA请求机制。
这些定时器还能够处理增量编码器的信号,也能处理13个霍尔传感器的数字输出。


基本定时器-TIM6和TIM7


2个定时器主要是用于产生DAC触发信号,也可当成通用的16位时基计数器。


独立看门狗


独立的看门狗是基于一个12位的递减计数器和一个8位的预分频器,它由一个内部独立的40kHzRC振荡器提供时钟;因为这个RC振荡器独立于主时钟,所以它可运行于停机和待机模式。它可以被当成看门狗用于在发生问题时复位整个系统,或作为一个自由定时器为应用程序提供超时管理。通过选项字节可以配置成是软件或硬件启动看门狗。在调试模式下,计数器可以被冻结。


窗口看门狗


窗口看门狗内有一个7位的递减计数器,并可以设置成自由运行。它可以被当成看门狗用于在发生问题时复位整个系统。它由主时钟驱动,具有早期预警中断功能;在调试模式下,计数器可以被冻结。


系统时基定时器


这个定时器是专用于实时操作系统,也可当成一个标准的递减计数器。它具有下述特性:
● 24位的递减计数器
● 自动重加载功能
● 当计数器为0时能产生一个可屏蔽系统中断
● 可编程时钟源
 


高级控制定时器框图



了解基本概念后,今天用通用定时器(TIM2), 写一个定时中断的程序
 

编写代码

建工程写代码


复制上节工程文件夹打开(这个方法比较方便)
 

  • 新建源文件,编辑代码
    编辑main.c, 在上节基础上增加TIM配置及中断服务函数。
    /**********************************************************************************
    
    * Sun STM32 mini Demo
    
    *   Description  
    
        TIM2 Interrupt Demo
    
       
    
    * Version    Date       Auther      Reversed History
      ----------------------------------------------------------------------------
    
      V1.0.0    2021-11-07  Lojam Fan  Fisrt Created
    
      
    
    * (C) Sunshine Silicon Corporation
    
    *  Website: http://www.sunsili.com  http://sunsili.taobao.com http://bbs.sunsili.com
    
    *  E-Mail : fan@sunsili.com
    
    **********************************************************************************/
    
    
    
    #include "stm32f10x.h"
    #include "usart.h"
    #include "SysTick.h"
    #include "led.h"
    #include "key.h"
    #include <stdio.h>
    
    static u8 flag;
    static u8 tim2_tick;
    
    void Timer2_Init_Config(void);
    void RCC_Configuration(void);
    
    
    /*******************************************************************************
    * 函数名  : main
    * 描述    : 主函数,用户程序从main函数开始运行
    
    * 输入    : 无
    * 输出    : 无
    
    * 返回值  : int:返回值为一个16位整形数
    
    * 说明    : 无
    
    *******************************************************************************/
    
    int main(void)
    {
        u8 keyVal;
    
        RCC_Configuration();
        SysTick_Init_Config();
            USART1_Init_Config(115200);//USART1初始化配置
        LED_GPIO_Config();
        Key_GPIO_Config();
        Timer2_Init_Config();        //Timer2初始化配置
    
        printf ("*===================================================*\n");
        printf ("*  *  Name: Sun STM32 mini Demo Code.    *************\n");
        printf ("*  * (C) Sunshine Silicon Corporation    *************\n");
        printf ("*  *  Website: http://www.sunsili.com    *************\n");
        printf ("*  *   E-Mail : fan@sunsili.com          *************\n");
        printf ("*===================================================*\n");
        printf ("* Sun STM32 mini TIM2 Interrupt Demo code .*\n");
    
       
    
            while (1)
            {
            if(tim2_tick)
            {
    
                tim2_tick = 0;
    
                if(flag)
                {
                    printf("LED ON\n");               
    
                }
                else
                {
                    printf("LED OFF\n");
                }
    
            }
            }
    }
    
    
    
    /*******************************************************************************
    
    * 函数名  : Timer2_Init_Config
    * 描述    : Timer2初始化配置
    
    * 输入    : 无
    * 输出    : 无
    
    * 返回    : 无
    
    * 说明    : 无
    
    *******************************************************************************/
    
    void Timer2_Init_Config(void)
    {
    
            TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
            NVIC_InitTypeDef NVIC_InitStructure;       
    
            RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);                //使能Timer2时钟      
    
            TIM_TimeBaseStructure.TIM_Period = 4999;                                        //设置在下一个更新事件装入活动的自动重装载寄存器周期的值(计数到5000为500ms)
            TIM_TimeBaseStructure.TIM_Prescaler = 7199;                                        //设置用来作为TIMx时钟频率除数的预分频值(10KHz的计数频率)
            TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;                //设置时钟分割:TDTS = TIM_CKD_DIV1
            TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;        //TIM向上计数模式
            TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);                                //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    
            /*中断优先级NVIC设置*/
            NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                                //TIM2中断
            NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        //先占优先级1级
            NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                        //从优先级1级
            NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能IRQ通道
            NVIC_Init(&NVIC_InitStructure);                                                         //初始化NVIC寄存器         
    
            TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE );                                 //使能TIM2指定的中断      
    
            TIM_Cmd(TIM2, ENABLE);                                                                          //使能TIMx外设
    }         
    
    
    
    /*******************************************************************************
    * 函数名  : TIM2_IRQHandler
    * 描述    : 定时器2中断服务函数
    * 输入    : 无
    * 输出    : 无
    
    * 返回    : 无
    
    * 说明    : 无
    
    *******************************************************************************/
    
    void TIM2_IRQHandler(void)   //TIM2中断服务函数
    {
        tim2_tick = 1;
    
            if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
            {
                    TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx更新中断标志
    
                    if(flag)
                    {
                            LED4_ON();
                            flag=0;
    
                    }
                    else
                    {
                            LED4_OFF();
                            flag=1;
    
                    }
            }
    }
    
    
    
    /*******************************************************************************
    * 函数名  : RCC_Configuration
    * 描述    : 设置系统时钟为72MHZ(这个可以根据需要改)
    
    * 输入    : 无
    * 输出    : 无
    
    * 返回值  : 无
    
    * 说明    : STM32F107x和STM32F105x系列MCU与STM32F103x系列MCU时钟配置有所不同
    
    *******************************************************************************/
    
    void RCC_Configuration(void)
    {
      ErrorStatus HSEStartUpStatus;               //外部高速时钟(HSE)的工作状态变量  
    
      RCC_DeInit();                               //将所有与时钟相关的寄存器设置为默认值
      RCC_HSEConfig(RCC_HSE_ON);                  //启动外部高速时钟HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟(HSE)稳定
    
      if(SUCCESS == HSEStartUpStatus)             //如果外部高速时钟已经稳定
      {
        /* Enable Prefetch Buffer */
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Flash设置
    
        /* Flash 2 wait state */
        FLASH_SetLatency(FLASH_Latency_2);  
    
        RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置AHB时钟等于系统时钟(1分频)/72MHZ
        RCC_PCLK2Config(RCC_HCLK_Div1);  //设置APB2时钟和HCLK时钟相等/72MHz(最大为72MHz)
        RCC_PCLK1Config(RCC_HCLK_Div2);  //设置APB1时钟是HCLK时钟的2分频/36MHz(最大为36MHz)
    
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz
    
        RCC_PLLCmd(ENABLE); //使能PLL
    
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //等待PLL稳定
    
    
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);          //设置系统时钟的时钟源为PLL
    
        while(RCC_GetSYSCLKSource() != 0x08);               //检查系统的时钟源是否是PLL
    
        RCC_ClockSecuritySystemCmd(ENABLE);                 //使能系统安全时钟
    
       
    
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO,ENABLE);
    
      }
    }
    
    
    
    
    /******************* (C) COPYRIGHT SUNSHINE SILICON  **************************
    
    ********************        END OF FILE main.c        *******************/

    编译调试程序

编译调试


保存直接编译,发现编译出错, 因为未添加tim库。解决方法添加库文件stm32f10x_tim.c
重新编译,通过。

调试


方法不再重复,经过前两节练习,大家应该是会了.
看到效果是, LED 1s闪烁一次,  uart1 定时打印LED状态

总结课后练习
改变TIM定时中断频率


工程源码

查看原文,可下载工程源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1319096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity中URP下的菲涅尔效果实现(URP下的法线和视线向量怎么获取)

文章目录 前言一、实现思路二、实现原理我们可以由下图直观的感受到 N 与 L夹角越小&#xff0c;点积越接近&#xff08;白色&#xff09;1。越趋近90&#xff0c;点积越接近0&#xff08;黑色&#xff09; 三、实现URP下的菲涅尔效果1、我们新建一个Shader&#xff0c;修改为最…

机器学习笔记 - 时间序列分析基础概念解释

一、简述 时间序列分析是一种统计方法,可检查定期收集的数据点以揭示潜在的模式。该技术与各个行业高度相关,因为它可以根据历史数据做出决策和预测。通过了解过去并预测未来,时间序列分析在金融、医疗保健、能源、供应链管理、天气预报、营销等领域发挥着至关重要的作用。 …

关于mysql存储过程中N/A和null的使用注意事项

oracle和mysql的存储过程大同小异&#xff0c;但是一些细节还是需要留意的。最近发现mysql的N/A和null在存储过程中容易忽略的一点&#xff0c;这会导致我们的存储过程提前结束。今天突然想起来了就记录一下。   mysql的N/A和null区别网上也说得很详细了&#xff0c;我就不赘…

频谱论文:面向频谱地图构建的频谱态势生成技术研究

#频谱# [1]李竟铭.面向频谱地图构建的频谱态势生成技术研究.2019.南京航空航天大学,MA thesis.doi:10.27239/d.cnki.gnhhu.2019.000556. &#xff08;南京航空航天大学&#xff09; 频谱地图是对无线电环境的抽象表达&#xff0c;它可以直观、多维度地展现频谱态势信息&…

部署智能合约以及 javascript 调用合约函数(Web3项目二实战之三)

在上一篇 智能合约是Web3项目的核心要务(Web3项目二实战之二) ,我们已然为项目编写了智能合约,在攥写完智能合约后,该项目将完成了一大部分,剩下无非就是用户界面交互的内容。 然而,在码完了智能合约代码后,起着承前启后关键性的便是,前端界面与智能合约的交互。 智能…

scroll-behavior属性使用方法

定义和用法&#xff1a; scroll-behavior 属性规定当用户单击可滚动框中的链接时&#xff0c;是否平滑地&#xff08;具动画效果&#xff09;滚动位置&#xff0c;而不是直线跳转。 <style>element{/* 核心代码 */scroll-behavior: smooth;} </style> 属性值&am…

gitlab ci pages

参考文章 gitlab pages是什么 一个可以利用gitlab的域名和项目部署自己静态网站的机制 开启 到gitlab的如下页面 通过gitlab.ci部署项目的静态网站 # build ruby 1/3: # stage: build # script: # - echo "ruby1"# build ruby 2/3: # stage: build …

翻译: 如何分析你的工作是否被AI替代 比如程序员、律师 Additional job analysis examples

我发现对于许多职业角色&#xff0c;人们心中都有一个标志性的任务&#xff0c;这个任务独特地定义了那个职业角色。例如&#xff0c;计算机程序员编写代码。医生可能会看病人。律师去法庭上争论案件。我认为当人们考虑人工智能的机会时&#xff0c;通常会本能地问&#xff0c;…

力扣200. 岛屿数量(java DFS解法)

Problem: 200. 岛屿数量 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 该问题可以归纳为一类遍历二维矩阵的题目&#xff0c;此类中的一部分题目可以利用DFS来解决&#xff0c;具体到本题目&#xff1a; 1.我们首先要针对于二维数组上的每一个点&#xff0c;尝试展…

基于AT89C52单片机的计算器设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/88637995?spm1001.2014.3001.5503 源码获取 B 源码仿真图课程设计51 摘 要 计算器一般是指“电子计算器”,能进行数学运算的手持机器&#xff0c;拥有集成电路芯…

【Qt图书管理系统】4.系统设计与详细设计

文章目录 核心流程图软件架构设计流程图软件开发类图及功能点 核心流程图 用户登录图书查询图书借阅图书归还账户管理 软件架构设计 流程图 软件开发类图及功能点 Dlg_Login 登录界面 Cell_Main 主窗体 Cell_MyBook 我的书籍 Cell_BookMgr 书籍管理 Cell_RecoredMgr 借阅记录…

ASP.NET MVC实战之权限拦截Authorize使用

1&#xff0c;具体的实现方法代码如下 public class CustomAuthorizeAttribute : FilterAttribute, IAuthorizationFilter{/// <summary>/// 如果需要验证权限的时候&#xff0c;就执行进来/// </summary>/// <param name"filterContext"></par…

C# WPF上位机开发(知识产权ip保护)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 上位机软件如果是和硬件模块搭配开发&#xff0c;这个时候大部分上位机基本上都是白送的&#xff0c;不会收取相关的费用。但是&#xff0c;如果上…

气候灾害组织:全球红外降水站数据

气候灾害组织红外降水站数据-Prelim (CHIRPS-Prelim) 气候灾害中心红外降水站数据 Prelim (CHIRPS-Prelim) 融合了 CHIRPS 数据与原位降水数据&#xff0c;以消除数据偏差并提高其准确性。生成 CHIRPS-Prelim 的过程与 CHIRPS 过程类似&#xff0c;主要区别在于它仅依赖于近实…

【Unity自动寻路】使用Navigation系统实现物体自动寻路绕开障碍物

知识点流程图 自动导航Navigation系统 我们在游戏场景中经常会有一些障碍物、墙壁、树木等等&#xff0c;如果我想要让角色或者怪物去墙的另一边&#xff0c;我直接在墙另一边点击左键&#xff0c;我希望角色自动跑过去&#xff0c;但是他不能直接穿透墙&#xff0c;他需要“智…

【具身智能评估3】具身视觉语言规划(EVLP)度量标准汇总

参考论文&#xff1a;Core Challenges in Embodied Vision-Language Planning 论文作者&#xff1a;Jonathan Francis, Nariaki Kitamura, Felix Labelle, Xiaopeng Lu, Ingrid Navarro, Jean Oh 论文原文&#xff1a;https://arxiv.org/abs/2106.13948 论文出处&#xff1a;Jo…

华媒舍:怎样利用旅游业发展媒体套餐宣传推广分析7个经典案例

1.分析经典案例在旅游业发展中&#xff0c;依靠媒体套餐开展宣传推广成为了一种常见的方法。下面将详细介绍7个经典案例&#xff0c;从这当中我们可以得出一些宝贵经验。 案例一&#xff1a;目标市场定位成功宣传推广一定要明确市场定位&#xff0c;针对不同的受众群体制定合理…

力扣刷题-二叉树-找树左下角的值

513 找树左下角的值 给定一个二叉树的 根节点 root&#xff0c;请找出该二叉树的 最底层 最左边 节点的值。 假设二叉树中至少有一个节点。 示例 1&#xff1a; 示例 2&#xff1a; 思路 层序遍历 直接层序遍历&#xff0c;因为题目说了是最底层&#xff0c;最左边的值&a…

MATLAB图像处理技巧

MATLAB图片处理------动态绘图 1. 动态绘图2. XXXXX 1. 动态绘图 主要用到四个函数&#xff0c;分别为getframe、frame2im、rgb2ind以及imwrite&#xff1a; 1.getframe&#xff1a;获取当前绘图窗口的图片作为影片帧&#xff1b; 2.frame2im&#xff1a;从单个影片帧 F 返回索…

【JavaEE】多线程(5) -- 阻塞队列

目录 1.阻塞队列是什么? 2.生产者消费者模型 3.标准库中的阻塞队列 4.阻塞队列的实现 1.阻塞队列是什么? 阻塞队列是⼀种特殊的队列. 也遵守 "先进先出" 的原则 阻塞队列能是⼀种线程安全的数据结构, 并且具有以下特性: 当队列满的时候, 继续⼊队列就会阻塞, …