第8章 STM32时钟与GPIO设计
stm32数字时钟课程设计
stm32 数字时钟课程设计一、课程目标知识目标:1. 学生能理解STM32的基本结构和工作原理,掌握其编程方法。
2. 学生能掌握数字时钟的基本原理,包括时钟源、分频器、计数器等组成部分。
3. 学生能了解实时时钟(RTC)的功能及其在STM32中的应用。
技能目标:1. 学生能运用C语言编写程序,实现STM32控制数字时钟的功能。
2. 学生能通过调试工具,对程序进行调试和优化,确保数字时钟的准确性。
3. 学生能运用所学知识,设计具有实用价值的数字时钟产品。
情感态度价值观目标:1. 培养学生对电子技术和编程的兴趣,激发其探究精神。
2. 培养学生团队合作意识,使其在项目实施过程中学会相互沟通、协作。
3. 培养学生严谨、细致、负责的工作态度,提高其解决实际问题的能力。
课程性质:本课程为实践性较强的课程,结合STM32和数字时钟知识,培养学生的动手能力和实际操作技能。
学生特点:学生具备一定的电子技术基础和C语言编程能力,对实际操作感兴趣,但可能缺乏项目实践经验。
教学要求:注重理论与实践相结合,引导学生主动探索,提高其分析问题、解决问题的能力。
在教学过程中,关注学生的个体差异,因材施教,使每位学生都能在原有基础上得到提高。
将课程目标分解为具体的学习成果,便于后续教学设计和评估。
二、教学内容本课程教学内容主要包括以下几部分:1. STM32基本原理与编程基础:介绍STM32的内部结构、工作原理,C语言编程基础及其在STM32中的应用。
- 教材章节:第一章至第三章- 内容:微控制器基础、STM32硬件结构、C语言编程基础、STM32编程环境搭建。
2. 数字时钟原理与设计:讲解数字时钟的基本原理、组成部分以及设计方法。
- 教材章节:第四章至第五章- 内容:时钟源、分频器、计数器、实时时钟(RTC)、数字时钟设计方法。
3. STM32实现数字时钟功能:结合STM32和数字时钟知识,指导学生动手实践,实现数字时钟功能。
STM32的IO口设置方法实例
STM32的IO⼝设置⽅法实例STM32的IO⼝设置⽅法实例!通过本节的学习,你将了解到STM32的IO⼝作为输出使⽤的⽅法。
本节分为如下⼏个⼩节:3.1.1 STM32 IO⼝简介3.1.2 硬件设计3.1.3 软件设计3.1.4 仿真与下载3.1.1 STM32 IO简介作为所有开发板的经典⼊门实验,莫过于跑马灯了。
ALIENTEK MiniSTM32开发板板载了2个LED,DS0和DS1,本实验将通过教你如何控制这两个灯实现交替闪烁的类跑马灯效果。
该实验的关键在于如何控制STM32的IO⼝输出。
了解了STM32的IO⼝如何输出的,就可以实现跑马灯了。
通过这⼀节的学习,你将初步掌握STM32基本IO⼝的使⽤,⽽这是迈向STM32的第⼀步。
STM32的IO⼝可以由软件配置成8种模式:1、输⼊浮空2、输⼊上拉3、输⼊下拉4、模拟输⼊5、开漏输出6、推挽输出7、推挽式复⽤功能8、开漏复⽤功能每个IO⼝可以⾃由编程,单IO⼝寄存器必须要按32位字被访问。
STM32的很多IO⼝都是5V兼容的,这些IO⼝在与5V电平的外设连接的时候很有优势,具体哪些IO⼝是5V兼容的,可以从该芯⽚的数据⼿册管脚描述章节查到(I/O Level标FT的就是5V电平兼容的)。
STM32的每个IO端⼝都有7个寄存器来控制。
他们分别是:配置模式的2个32位的端⼝配置寄存器CRL和CRH;2个32位的数据寄存器IDR和ODR;1个32位的置位/复位寄存器BSRR;⼀个16位的复位寄存器BRR;1个32位的锁存寄存器LCKR;这⾥我们仅介绍常⽤的⼏个寄存器,我们常⽤的IO端⼝寄存器只有4个:CRL、CRH、IDR、ODR。
CRL和CRH控制着每个IO⼝的模式及输出速率。
STM32的IO⼝位配置表如表3.1.1.1所⽰:表3.1.1.1 STM32的IO⼝位配置表STM32输出模式配置如表3.1.1.2所⽰:表3.1.1.2 STM32输出模式配置表接下来我们看看端⼝低配置寄存器CRL的描述,如下图所⽰:图3.1.1.1端⼝低配置寄存器CRL各位描述该寄存器的复位值为0X4444 4444,从上图可以看到,复位值其实就是配置端⼝为浮空输⼊模式。
stm32的时钟配置(非常详细)
stm32的时钟配置(⾮常详细)⼤家都知道在使⽤单⽚机时,时钟速度决定于外部晶振或内部RC振荡电路的频率,是不可以改变的。
⽽ARM的出现打破了这⼀传统的法则,可以通过软件随意改变时钟速度。
这⼀出现让我们的设计更加灵活,但是也给我们的设计增加了复杂性。
为了让⽤户能够更简单的使⽤这⼀功能,STM32的库函数已经为我们设计的更加简单⽅便。
在⽐较靠前的版本中,我们需要向下⾯那样设置时钟:ErrorStatus HSEStartUpStatus;void RCC_Configuration(void){RCC_DeInit(); // RCC system reset(for debug purpose)RCC_HSEConfig(RCC_HSE_ON); // Enable HSEHSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is readyif (HSEStartUpStatus == SUCCESS) // 当HSE准备完毕切振荡稳定后{RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLKRCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLKRCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait stateFLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable Prefetch BufferRCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHzRCC_PLLCmd(ENABLE); // Enable PLLwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){; // Wait till PLL is ready}RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock sourcewhile (RCC_GetSYSCLKSource() != 0x08) // Wait till PLL is used as system clock source {;}}}随之函数库的不断升级,到3.0以上时,我们就不⽤再这样编写时钟设置了,我们只要做如下两部即可:第⼀个: system_stm32f10x.c 中 #define SYSCLK_FREQ_72MHz 72000000第⼆个:调⽤SystemInit()说明:在stm32固件库3.0中对时钟频率的选择进⾏了⼤⼤的简化,原先的⼀⼤堆操作都在后台进⾏。
基于STM32的电子时钟设计
第39卷第11期2020年11月绵阳师范学院学报Journal of Mianyang Teachers'CollegeVol.39No.11Nov.2020D01:10.16276/51-1670/g.2020.11.005基于STM32的电子时钟设计郭辛(绵阳师范学院机电工程学院,四川绵阳621000)摘要:随着嵌入式技术的应用与推广.ARM32位处理器已逐步占据电子消费品和工业测控制造领域主导地位.本文以Cortex-M系列产品的典型代表STM32F103RC为平台,采用固件库技术思想为导向,按照CMSIS标准构建工程,将定时器、LCD驱动以及中断系统等各功能模块进行整合,设计一款电子时钟.通过综合设计的应用开发,摸索和总结出一套针对STM32的学习和设计方法,为高端处理器的应用开发提供新思路.关键词:STM32;嵌入式系统;固件库;定时器;LCD显示中图分类号:TN91文献标志码:A文章编号:1672-612X(2020)11-0028-040引言单片机自诞生之日起已走过近半个世纪的历程.随着电子技术和计算机技术的飞速发展,进入21世纪以来以嵌入式系统为代表的新兴技术正在逐渐占据工业控制领域主导地位,并逐步取代以8位处理器为核心的传统测控系统⑴.近年来由于数字信息技术和网络技术的广泛应用,单片机作为主流核心处理器的地位逐步下降,现代电子技术的发展正朝着智能化、网络化和低功耗的方向迈进•新技术的不断更新,需要新的设计思想的注入才能满足技术发展需求•那么,如何将新兴技术融合到传统知识架构体系,将基础理论与工程应用实际相结合,就成为设计人员急需破解的难题•ARM作为一种32位的高性能、低成本的嵌入式RISC微处理器,得到了广泛的应用,STM32系列是意法半导体(STMicroelectronics)集团专为要求高性能、低成本和低功耗的嵌入式应用设计的ARM Cortex-M系列产品的代表作•基于STM32的嵌入式技术已经渗透在工业控制系统、数据采集系统、智能化仪器仪表和办公自动化等诸多领域的应用,甚至在很大程度上正在改变我们现有的商业模式和工作生活方式,如智能手机、导航系统、无人机和平板电脑等,并呈现出明显的系统化、人工智能化和物联网的趋势.目前,Cortex系列处理器已经占据了大部分嵌入式处理器的中高端产品市场,而嵌入式系统的应用开发对从业者要求很高,初学者若要快速掌握其原理并在实际工程中加以应用,必须改变传统的思维方式并构建新的设计理念■本文以STM32F103RC处理器(Cortex-M普通型号之一)为平台,通过对定时器、中断系统和LCD显示模块的组合设计为例,针对基于固件库设计思想的方法进行探讨与总结,以开启嵌入式系统的应用设计学习之门⑵.1固件库概述固件库是指“STM32标准函数库”,它是由ST公司针对STM32提供的函数接口,即API(Application Program Interface),是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征.它是架设在构成部件的寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口⑶.部件的调用和基本操作写成了通用的子函数,对复杂的硬件操作实现了函数封装■在以51单片机为代表的8位机由于硬件系统相对简单,通常采用宜接配置寄存器的方式来进行应用开发;而32位处理器核内系统复杂,外设资源丰富•应用系统若仍旧采用传统的设计方式,不但效率低、可移收稿日期:2020-04-30作者简介:郭辛(1971-),男,四川成都人,讲师,硕士,研究方向:汽车电子控制技术.绵阳师范学院学报(自然科学版)植性差,而且技术难度大,已不能适应较复杂的工程应用•基于固件库的技术思想为解决这一问题提供了新思路:开发者根据具体任务需求按照CMSIS标准构建工程,利用固件库提供的资源,设计和改造相关函数以实现对部件的操作•本文结合综合实验项目的开发——电子时钟的设计为例,首先介绍库函数中主要涉及的定时器和LCD显示驱动的基本结构和工作原理,在此基础上利用现有库资源进行功能设计与系统构建•2定时器概述STM32F1系列中,共有8个定时器TIM1-TIM8,分为基本定时器,通用定时器和高级定时器.基本定时器TIM6和TIM7是一个16位的只能向上计数的定时器,它只能定时,没有外部I/O;通用定时器TIM2/ 3/4/5是一个16位的可以向上/下计数的定时器,可以定时、输出比较和输入捕捉,每个定时器有四个外部I/O;高级定时器TIM1/8是一个16位的可以向上/下计数的定时器,可以定时、输出比较,输入捕捉,以及实现三相电机互补输出信号,每个定时器有8个外部I/O⑷.此例以TIM6作定时器,设计一款LCD屏显电子时钟,计时60min,最小显示值Is.2.1TIM6定时器组成根据STM32参考手册基本定时器的功能结构如图1所示⑶.定时器若要向外提供基本时钟信号,需对相关寄存器进行参数设置:1)时钟源TIM*CLK:根据STM32时钟系统设置,通常挂载APB1时钟总线,默认取值为72MH z[5];2)16位分频器PSC:用于存放预分频值,分频范围1-65536,则时钟周期图1基本定时器功能框图Fig.l Block Diagram of Basic Timer FunctionCK_CLK=(PSC+1)/TIM*CLK(1)即每计1个数的时间间隔3)自动重装载寄存器ARR:用于存放16位计数值,用于设定定时长度Td=CK_CLK*ARR(2)综上所述,首先对定时器初始化,将所预设参数写入到对应的结构体中,赋值包含以下内容:#define BASIC_TIM#define BASIC_TIM_CLK #define BASIC_TIM_ARR #define BASIC_TIM_PSC TIM6RCC_APB1Periph_TIM6 1000-171按照以上参数设置,基本定时时长为:Td=〔(PSC+1)/TIM*C LK〕*A RR=(72/72M)*1000=1ms(3) 2.2电子时钟定时原理如图2所示,内部定时器提供基准时长Td=lms,引入定时中断,每计时1ms中断一次;中断次数time二1000产生Is定时,即LCD显示屏每隔1s更新一次秒位(sec)计数值;每计满60s更新一次分位(min)计数值,并将其分别显示到LCD屏上.2.3LCD显示内部时基信号产生后,还需将结果显示出来,每次中断定时时长为:Td=((PSC+1)/TIM*CLK)*ARRL J701ARR MAX(65535)ls=Td*t ime(中断次数)图2定时原理示意图Fig.2Schematic Diagram of Timing PrincipleSTM32F103实验板配2.8吋16位数据接口液晶屏,控制芯片采用了ILI0341.ILI0341是一个用于TFT液晶郭辛:基于STM32的电子时钟设计显示的单芯片控制驱动器,具有262,144色的240RGBX320像素显示方案;IU0341支持8/9/16/18位数据总线的MCU接口,6/16/18位数据总线的RGB接口以及3/4线的SPI接口⑷,本示例中液晶屏控制器采用了预先配置的8080接口通讯,使用16根数据线的RGB565格式.其相关驱动程序按照IU9341标准编制,主要由如下几步完成:1)初始化LCD数据/控制管脚ILI9341_GPIO_Config().2)点亮背光ILI9341_BackLed_Control(ENABLE).3)初始化控制寄存器ILI9341_REG_Config().4)设置显示模式ILI9341_GramScan(LCD_SCAN_MODE).初始化液晶屏完成后,调用显示驱动函数•5)清屏ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH).6)设置显示字符字体(8x16)、颜色(红字)及背景(黑底)LCD_SetFont(&Font8xl6);LCD_SetColors (RED,BLACK).7)使用c标准库把时间变量转化成字符串并显示sprintf(dispBuff,"time:%d:%d”,y,x);[6]LCD_ ClearLine(LINE(6));ILI9341_DispStringLine_EN(UNE(6),dispBuff).将数据转换成字符串,存放于数组dispBuff并写入指定行•3系统设计在以51单片机为主控单元的系统中,我们往往采用直接配置寄存器控制字的方法来操控硬件,因为MCS-51内部寄存器只有21个,而且功能简单,程序设计宜观简便;而STM32作为系统主控制器,其内部设备多达几十个,而控制这些设备的寄存器有几百个,若要使系统维持基本运转,操作这些寄存器所需的驱动程序代码成千上万行,这对于应用开发者来说逐条写程序是不现实的•芯片厂商将这些外设的驱动源码封装成固件函数包提供给用户,由用户在此基础上进行应用开发,因此以STM32为主控制器的应用系统开发就包括项目搭建和程序设计两部分•3.1固件库文件结构分析1)启动文件startup_stm32fl0x_hd.s:设置堆栈、PC指针和配置系统时钟等.2)时钟配置文件system_stm32fl0x.c:将外部时钟倍频并为各子模块提供配套的时钟源.3)内核相关的驱动文件core_cm3.h:内核的外设寄存器映射;core_cm3.c:内核的夕卜设驱动固件库•NVIC(嵌套向量中断控制器)描述文件:misc.h和misc.c.4)夕卜设相关的库文件stm32fl0x.h:实现了内核之夕卜的寄存器映射;stm32fl0x_xx.c:夕卜设的驱动函数库文件;核外设备:GPIO、USRAT、I2C、SPI、FSMC等驱动文件.5)头文件的配置文件stm32flO X_conf.h头文件的配置文件,将多个外设的头文件进行统一调配管理,如:stm32fl0x_usart.h,stm32fl0x_i2c.h,stm32fl0x_spi.h,stm32fl0x_adc.h, stm32f10x_fsmc.h...对外设描述的结构体,映射地址的头文件都放在stm32fl0x_conf.h中进行声明,使用时只需包含该配置头文件即可,并可通过“宏断言”函数进行选配•6)专门注册中断服务函数的C文件:stm32fl0x_it.c和stm32fl0x_it.h.这些文件按照相应的规贝!]分布在不同的路径下,这个规则就是ST集团与各芯片开发商共同制订的CMSIS标准⑶.3.2工程项目构建参照CMSIS标准创建项目文件以及组文件夹:CMSIS、FWlib、inc、src、Project、Output和User,并将固件库提供的基本源代码拷贝到对应目录下,如:项目文件创建并保存在Project路径下;核外外设的驱动程序复制到src源码目录下;对描述部件的寄存器结构体统一定义在inc头文件目录下;而宜接针对任务而设计的程序文件通常放置在用户目录User中,如main()程序,中断服务程序等等.在本例的电子时钟设计中,根据前面所介绍的定时器和LCD的工作原理,配置相关驱动程序或函数集,并写入预设的定时参数,重新组合、设计功能程序:1)计算并确定定时初值以及另濒器参数;2)LCD初始化机模式配置,设计变量显示程序;3)中断服务程序的数据处理部分程序设计-绵阳师范学院学报(自然科学版)3.3程序设计首先对定时器、中断寄存器、AFIO 引脚以及液晶屏进 行初始化设置,并将设计的参数值写入对应寄存器中;开启 定时时钟和中断系统,主程序实时不间断显示时间——分 位(min)和秒位(sec);中断服务程序完成定时器计数值的 更新和处理,并将其转换成时间变量传回主程序显示,程序 流程图见图3.4结论由于内部时钟源能提供1K~72MHz 时钟信号,误差 为±1%,则时钟误差最小可以控制在0. 01 us 范围内.通 过上述实验教学项目的开发,总结出32位微处理平台在工 程实践中的设计流程:(1)任务分析:根据设计要求明确项 目所需实现功能,提出设计方案主体框架、功能模块构成、 技术实现路线;(2)搭建工程项目:根据STM32平台所提供 资源,确定主控系统模块并搭建项目主体框架;对照现有资 源匹配现有的子模块,制作与主系统的接口函数并确定底 层部件参数;(3)主系统集成:完成主要业务的程序编制并 进行系统整和调试.基于STM32平台的嵌入式系统开发, 应采用立足于对系统资源的整合和集成的思维方式,将各 部件的驱动程序看作一种供开发者使用的函数集合,开发 主程序流程图|清除定時中断标志|开始Itime++I 中断服务流程图图3程序流程图Fig.3 Program Flow Chart 者需要做的是将这些离散、抽象的“程序块”有机地进行组合,以搭积木的方式进行模块化设计,这才是嵌入 式系统应用的本质所在.参考文献:[1]严武军.后PC 时代计算机专业建设的思考和探索[J].现代计算机,2011,23:92-97.[2]张良.Multisim 在“自动控制原理”实验教学中的应用[J].绵阳师范学院学报,2019,11(38):27-32.[3]刘火良.STM32库开发实战指南[M].北京:机械工业出版社,2017:317-403.[4]田泽.ARM9嵌入式开发实验与实践[M].北京:北京航空和航天大学出版社,2006:279-282.[5]Jean brosse .嵌入式实时操作系统|jl C\OS-U [ M].邵贝贝译.北京:北京航天航空大学出版社,2007: 116-121.[6] 苏小红.C 语言大学实用教程[M].北京:电子工业出版社,2011:309-322.The Design of An Electronic Clock Based on STM32GUO Xin(School of Mechanical and Electrical Engineering , Mianyang Teachers x College , Mianyang , Sichuan 621000)Abstract : With the development of the embedded system technology , ARM32 bit processor has gradually taken a dominant position in the field of electronic consumer goods and industrial measurement and control manu facturing. This paper takes The STM32F103RC , a typical representative of Cortex-M series products , as the plat form, adopts the technical thought of firmware library as the guidance , and builds projects according to CMSIS standard , integrates various functional modules such as timer , LCD driver and interrupt system , and designs an e- lectronic clock. Through the application development of comprehensive design , a set of learning and design methods for STM32 is explored and summarized to provide new ideas for the application development of high-end processors.Keywords : STM32, embedded system , firmware library , timer , LCD display(责任编辑:陈桂芳)。
图文详解stm32时钟树
对于广大初次接触STM32的读者朋友(甚至是初次接触ARM器件的读者朋友)来说,在熟悉了开发环境的使用之后,往往“栽倒”在同一个问题上。
这问题有个关键字叫:时钟树。
众所周知,微控制器(处理器)的运行必须要依赖周期性的时钟脉冲来驱动——往往由一个外部晶体振荡器提供时钟输入为始,最终转换为多个外部设备的周期性运作为末,这种时钟“能量”扩散流动的路径,犹如大树的养分通过主干流向各个分支,因此常称之为“时钟树”。
在一些传统的低端8位单片机诸如51,AVR,PIC等单片机,其也具备自身的一个时钟树系统,但其中的绝大部分是不受用户控制的,亦即在单片机上电后,时钟树就固定在某种不可更改的状态(假设单片机处于正常工作的状态)。
比如51单片机使用典型的12MHz晶振作为时钟源,则外设如IO口、定时器、串口等设备的驱动时钟速率便已经是固定的,用户无法将此时钟速率更改,除非更换晶振。
而STM32微控制器的时钟树则是可配置的,其时钟输入源与最终达到外设处的时钟速率不再有固定的关系,本文将来详细解析STM32微控制器的时钟树。
图1是STM32微控制器的时钟树,表1是图中各个标号所表示的部件。
标号图1标号释义1 内部低速振荡器(LSI,40Khz)2 外部低速振荡器(LSE,32.768Khz)3 外部高速振荡器(HSE,3-25MHz)4 内部高速振荡器(HIS,8MHz)5 PLL输入选择位6 RTC时钟选择位7 PLL1分频数寄存器8 PLL1倍频寄存器9 系统时钟选择位10 USB分频寄存器11 AHB分频寄存器12 APB1分频寄存器13 AHB总线14 APB1外设总线15 APB2分频寄存器16 APB2外设总线17 ADC预分频寄存器18 ADC外设19 PLL2分频数寄存器20 PLL2倍频寄存器21 PLL时钟源选择寄存器22 独立看门狗设备23 RTC设备图1 STM32的时钟树在认识这颗时钟树之前,首先要明确“主干”和最终的“分支”。
实验二STM32单片机GPIO程序开发
实验二STM32单片机GPIO程序开发
一.实验目的
1.掌握STM32单片机输入输出接口程序开发
2.掌握用库函数开发STM32单片机程序
二.实验环境
1.TEB-CM5000嵌入式单片机实验系统
2.MDK4.7嵌入式软件开发环境
三.实验内容
1.熟悉TEB-CM5000嵌入式单片机实验系统上的LED灯电路和单
独按钮电路。
2.学习并掌握库函数版本相关的实例程序,主要学习
gpio_key_led实例程序。
3.利用库函数开发出USER2(PD3)按钮控制LD5(PF7)亮灭。
具体
功能:USER2(PD3)按钮按下时,LD5灯闪烁;当USER2(PD3)按钮弹开时,LD5灯停止闪烁。
四.实验要求
1.完成实验要求中提到要完成的所有内容,完成代码并提
交主要代码。
2.对每行主要代码要进行注释,说明其功能。
五.实验提交要求
1.按照实验模板完成实验报告,其中包括实验要求的所有内容。
2.提交电子版报告,撰写程序流程图,并且提交程序主要代码。
3.最终提交形式:制作成压缩rar格式文件,文件命名:班级_组号_学号_姓名_实验一.rar。
stm32芯片时钟(晶振)连接到芯片的 引脚
STM32芯片时钟(晶振)连接到芯片引脚一、引言STM32芯片是一款由STMicroelectronics公司生产的32位微控制器,具有高性能、低功耗、丰富的外设和可扩展性等特点。
在STM32芯片中,时钟(晶振)连接到芯片引脚是一个非常重要的部分,直接关系到芯片的工作频率和稳定性。
二、 STM32芯片时钟STM32芯片的时钟系统包括内部RC振荡器、内部RC振荡器、外部晶体振荡器等,其中晶振作为一种最常用的外部时钟源,具有稳定性高、精度好等优点,因此在实际应用中得到了广泛的应用。
三、连接方式STM32芯片中,晶振可以连接到芯片的多个引脚上,通常采用的是双向连接方式,即一个晶振同时连接到芯片的两个引脚上,以提高时钟信号的稳定性和可靠性。
四、连接引脚STM32芯片的不同系列和不同型号,在连接晶振时会有所不同,但基本的连接原理是相通的。
一般来说,连接引脚包括晶振输入引脚(XTAL1)和晶振输出引脚(XTAL2),分别用来输入晶振的信号和输出晶振的信号,并通过外部电路提供稳定的时钟信号给芯片内部的时钟系统。
五、连接建议在实际应用中,连接晶振时需要注意以下几点:1. 选择合适的晶振型号和频率,根据实际需求选择合适的晶振型号和频率,以保证芯片的工作稳定。
2. 连接线路布局合理,尽量减小晶振到芯片引脚的连接长度,减小外界干扰。
3. 使用合适的外围电路,包括对晶振输入引脚和晶振输出引脚的连接电路、滤波电路等。
六、结语正确连接STM32芯片时钟(晶振)到芯片引脚对于芯片的正常工作和稳定性有着重要的意义,希望本文能为您在实际应用中提供一些帮助。
感谢您的阅读。
七、晶振类型和频率选择在选择晶振类型和频率时,需要根据具体的应用需求进行选择。
一般来说,晶振的频率可以选择从几十kHz到几十MHz不等。
对于低功耗应用,可以选择较低频率的晶振,而对于需要高性能的应用,则需要选择较高频率的晶振。
还需要考虑晶振的负载电容和稳定性等因素,以保证晶振在工作时能够提供稳定可靠的时钟信号。
第八章 STM32定时器
GPIO_ResetBits(GPIOC,GPIO_Pin_0); GPIO_ResetBits(GPIOC,GPIO_Pin_1); GPIO_ResetBits(GPIOC,GPIO_Pin_2); GPIO_ResetBits(GPIOC,GPIO_Pin_3); }
TIM_Perscaler:用户设定的预分频系数, 其值范围从0~65535,为1999
8.7 TIM2应用实例概述
void Timer_Configuration(void) { /*定义TIM结构体变量*/ TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_DeInit(TIM2); TIM_TimeBaseStructure.TIM_Period=35999; TIM_TimeBaseStructure.TIM_Prescaler=1999; TIM_TimeBaseStructure.TIM_ClockDivision =TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode =TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); TIM_ClearFlag(TIM2,TIM_FLAG_Update); TIM_Cmd(TIM2,ENABLE);
8.7 TIM2应用实例概述
4.定时器的初始化
定时时间T的计算公式: T=(TIM_Period+1)*(TIM_Prescaler+1)/TIMxCLK =(35999+1)*(1999+1)/72MHz=1s
stm32时钟概念
stm32时钟概念
在STM32微控制器中,时钟是控制系统时序和同步的重要元件。
时钟通过提供时钟信号来驱动计时器、外设和处理器核心等,实现数据传输和操作的同步。
STM32微控制器使用了多种类型的时钟,包括系统时钟、高
速外设时钟、低速外设时钟和RTC(实时时钟)时钟。
以下
是对每种时钟的概念的简要描述:
1. 系统时钟:
系统时钟(SYSCLK)是微控制器所有部分的主时钟源,它
控制处理器核心以及许多外设的运行。
系统时钟的频率可以通过配置寄存器来选择,通常是通过增加倍频器或分频器来实现。
2. 高速外设时钟(HCLK):
高速外设时钟是系统时钟分频得到的一个时钟,它驱动一些
对实时性要求较高的外设,例如DMA(直接内存访问控制器)和GPIO(通用输入/输出端口)等。
3. 低速外设时钟(PCLK):
低速外设时钟也是通过系统时钟分频得到的一个时钟,它驱
动一些低速外设,如USART(通用异步收发传输器)和I2C (串行通信接口)等。
4. RTC时钟:
RTC时钟是由外部低速晶体振荡器提供的时钟,用于实时时钟和日历功能。
它通常用于实现计时、日期和闹钟等功能。
时钟源的选择和设置可以通过微控制器的时钟控制寄存器来完成,这些寄存器提供了配置时钟的选项。
根据具体的应用需求,可以选择不同的时钟源和频率来优化系统性能和功耗。
STM32GPIO相关寄存器
STM32 GPIO 相关寄存器每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH)分别控制每个端口的高八位和低八位,如果IO口是0-7号的话,则写CRL寄存器,如果IO口是8-15号的话,则写CRH寄存器,两个32位数据寄存器(GPIOx_IDR,GPIOx_ODR)一个是只读作输入数据寄存器,一个是只写作输出寄存器,一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
常用的IO端口寄存器只有四个:CRH,CRL,IDR,ODR.数据手册中列出的每个I/O端口的特定硬件特征, GPIO端口的每个位可以由软件分别配置成多种模式。
每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)。
另外,STM32的每个端口使用前都要将其时钟使能,STM32的GPIO的时钟统一挂接在APB2上,具体的使能寄存器为RCC_APB2ENR,该寄存器的第2位到第8位分别控制GPIOx(x=A,B,C,D,E,F,G)端口的时钟使能,当外设时钟没有启用时,程序不能读出外设寄存器的数值,如打开PORTA 时钟:RCC—>APB2ENR|=1〈<2; //使能PORTA时钟使能外设时钟后,GPIOA的十六位就可以按照设定的状态工作了,之后就是具体设置哪一位了以第八位为例即高位的首位,在GPIOx_CRH寄存器中进行设置,GPIOA的每一位都有该寄存器的四位来设定相应的参数,这四位中的高两位(CNF0,CNF1)设置GPIO的输入输出模式,低两位(MODE0,MODE1)是设置GPIO的输出频率,具体可以参考STM32参考手册。
GPIOA->CRH&=0XFFFFFFF0; //清掉PA8原来的设置,同时屏蔽其它端口,不影响其它端口的设置GPIOA—〉CRH|=0X00000003;//PA8 推挽输出十六进制中的3 换成二进制 00 11 前两位00表示推挽输出,11代表输出频率50Mhz,若CRH|=0x4,表示模拟输入模式(ADC用),0x3表示推挽输出模式(作输出口用,50M速率),0x8表示上/下拉输入模式(做输入口用),0xB表示复用输出(使用IO口的第二功能,50M速率). 这是对一位的操作,当然也可以多位操作,因为STM32对GPIO操作必须是32位全字操作,设置完成后GPIOA的第8位就可以使用了之后给GPIOA—>ODR=0x xxxx xxxx送数据就行了。
stm32数字时钟课程设计
stm32数字时钟课程设计一、课程目标知识目标:1. 学生能理解STM32的内部时钟结构和定时器工作原理;2. 学生能掌握利用STM32设计数字时钟的基本步骤和方法;3. 学生能了解数字时钟的显示原理,并掌握与STM32定时器相结合的编程技巧;4. 学生能解释数字时钟在实际应用中的重要性。
技能目标:1. 学生能运用C语言进行STM32定时器的编程;2. 学生能通过调试工具解决数字时钟编程中的问题;3. 学生能设计并实现一个具有基本功能的数字时钟,包括时、分、秒显示和闹钟功能;4. 学生能对所设计的数字时钟进行测试和优化。
情感态度价值观目标:1. 学生培养对电子制作的兴趣,增强实践操作的自信心;2. 学生培养团队协作意识,学会在项目中相互沟通、共同解决问题;3. 学生通过数字时钟设计,认识到技术与生活的紧密联系,激发创新意识;4. 学生培养严谨的科学态度,注重实验数据的准确性和程序的可维护性。
二、教学内容1. STM32内部时钟结构:介绍STM32的时钟树,讲解时钟源、时钟分频、时钟使能等概念,为学生设计数字时钟提供基础理论知识。
2. 定时器工作原理:详细讲解STM32定时器的工作原理,包括计数器、预分频器、自动重装载寄存器等组成部分,使学生了解定时器在数字时钟中的作用。
3. C语言编程:回顾与定时器编程相关的C语言知识,包括数据类型、运算符、控制语句等,为编写数字时钟程序打下基础。
4. 数字时钟设计步骤:按照以下步骤组织教学内容:a. 硬件设计:讲解如何使用STM32最小系统板,选择合适的显示屏和驱动芯片,连接电路;b. 软件设计:介绍定时器初始化、中断处理、时间计算等编程方法;c. 程序调试:指导学生使用调试工具,如Keil、ST-Link等,进行程序调试;d. 测试与优化:要求学生完成数字时钟设计后进行功能测试,并根据测试结果进行优化。
5. 教材章节关联:教学内容与教材第3章“STM32定时器”和第5章“STM32中断与事件”相关,结合实例进行讲解,使学生更好地掌握相关知识。
基于STM32定时中断的电子闹钟设计
基于定时中断的电子闹钟一、系统主要功能可以通过LCD的输出显示公历和农历时间,通过按键设置时间和闹钟;通过蜂鸣器响应闹钟。
三、电路原理图、接口、硬件构成1.原理图2.接口本次实验使用了串口、定时器、中断接口。
3.硬件组成(1)实验设计程序流程图如图左所示,中断流程图如图右所示。
(2)该设计分为软件设计和硬件设计两大模块,硬件电路由ARM 最小系统电路、时钟显示电路和闹钟提醒电路组成,采用stm32f103RCT6芯片,芯片管脚图示如下。
(3)时钟电路此电路主要是复位电路和时钟电路两部分,其中复位电路采用按键手动复位和上电自动复位组合,电路如图所示:晶振采用的是 8MHz 和 32.786KHz , 8MKz 分别接 STM32 的5 脚和 6 脚, 32.786KHz 分别接 STM32 的 3 脚和 4 脚。
(4)闹钟提醒电路本次实验设计的闹钟提醒电路为蜂鸣器电路,接入芯片的PC7引脚,当时间为设置闹钟时间时,蜂鸣器工作,发出响声,提醒电路如图所示。
四、核心代码(带注释)#include "delay.h"#include "sys.h"#include "lcd.h"#include "dht11.h"#include "ds1302.h"#include "KEY.h"#include "beep.h"u8 temp;u8 humi;u8 t=0;u8 flag=0,flag1=0,flag2=0,flag3=1; u8 a,b,c;int min1=10,hour1=10;DHT11_Data_TypeDef DHT11_Data;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; //TIM中断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, DISABLE); //使能TIMx }void gui0(u8 mode){LCD_ShowPicture(0,0,480,320);if(flag3==1){LCD_ShowPicture3(445,0,479,34);}LCD_ShowChinese(0+40,0,0,BLUE,32,mode);//字LCD_ShowChinese(32+40,0,8,BLUE,32,mode);LCD_ShowChinese(64+40,0,9,BLUE,32,mode);LCD_ShowChinese(96+40,0,10,BLUE,32,mode);LCD_ShowNum(52,40,temp,2,BLUE,32,mode);//温度LCD_ShowChinese(132,40,12,BLUE,32,mode);LCD_ShowChinese(128+80+30,0,0,BLUE,32,mode);LCD_ShowChinese(160+80+30,0,8,BLUE,32,mode);LCD_ShowChinese(192+80+30,0,11,BLUE,32,mode);LCD_ShowChinese(224+80+30,0,10,BLUE,32,mode);LCD_ShowNum(248+30,40,humi,2,BLUE,32,mode);LCD_ShowChar(280+30,40,'%',BLUE,32,mode);LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间 LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode);LCD_ShowChar(200,65,':',BLUE,160,mode);LCD_ShowNum(290,80,min/10,1,BLUE,160,mode);LCD_ShowNum(380,80,min%10,1,BLUE,160,mode);LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);LCD_ShowChinese(64,250,13,BLUE,32,mode);LCD_ShowNum(96,250,month,2,BLUE,32,mode);LCD_ShowChinese(128,250,14,BLUE,32,mode);LCD_ShowNum(160,250,day,2,BLUE,32,mode);LCD_ShowChinese(192,250,15,BLUE,32,mode);LCD_ShowChinese(224,250,16,BLUE,32,mode);LCD_ShowChinese(256,250,week,BLUE,32,mode);LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);LCD_ShowChar(33,283,':',BLUE,32,mode);LCD_ShowNum(50,283,min1,2,BLUE,32,mode);}void keyscan(u8 mode){switch(t){case KEY0_PRES:if(min1==min&&hour1==hour){flag2=1;BEEP(OFF);}switch(flag){case 1: hour++; if(hour>23)hour=0;LCD_ShowPicture2(20,80,190,240);LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode);break;case 2: min++; if(min>59)min=0;LCD_ShowPicture2(290,80,460,240);LCD_ShowNum(290,80,min/10,1,BLUE,160,mode); LCD_ShowNum(380,80,min%10,1,BLUE,160,mode); break;case 3: year++; LCD_ShowPicture2(0,250,64,282);LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);break;case 4: month++; if(month>12) month=1;LCD_ShowPicture2(96,250,128,282); LCD_ShowNum(96,250,month,2,BLUE,32,mode);break;case 5: day++; if(day>31) day=1;LCD_ShowPicture2(160,250,192,282);LCD_ShowNum(160,250,day,2,BLUE,32,mode); break; case 6: week++; if(week>7) week=1;LCD_ShowPicture2(256,250,288,282);LCD_ShowChinese(256,250,week,BLUE,32,mode);break;case 7: hour1++; if(hour1>23)hour1=0;LCD_ShowPicture2(0,283,32,315);LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);break;case 8: min1++;if(min1>59)min1=0;LCD_ShowPicture2(50,283,82,315);LCD_ShowNum(50,283,min1,2,BLUE,32,mo de);break;case 9: flag3=1; LCD_ShowPicture3(445,0,479,34); break;default: break;}break;case KEY1_PRES:if(min1==min&&hour1==hour){flag2=1;BEEP( OFF );}switch(flag){case 1: hour--; if(hour<0)hour=23;LCD_ShowPicture2(20,80,190,240);LCD_ShowNum(20,80,hour/10,1,BLUE,160,mode);//时间LCD_ShowNum(110,80,hour%10,1,BLUE,160,mode); break;case 2: min--; if(min<0) min=59;LCD_ShowPicture2(290,80,460,240);LCD_ShowNum(290,80,min/10,1,BLUE,160,mode);LCD_ShowNum(380,80,min%10,1,BLUE,160,mode); break;case 3: year--; LCD_ShowPicture2(0,250,64,282);LCD_ShowNum(0,250,year+2000,4,BLUE,32,mode);break;case 4: month--; if(month<1) month=12; LCD_ShowPicture2(96,250,128,282);LCD_ShowNum(96,250,month,2,BLUE,32,mode);break;case 5: day--; if(day<1) day=31;LCD_ShowPicture2(160,250,192,282);LCD_ShowNum(160,250,day,2,BLUE,32,mode); break;case 6: week--; if(week<1) week=7;LCD_ShowPicture2(256,250,288,282);LCD_ShowChinese(256,250,week,BLUE,32,mode); break; case 7: hour1--; if(hour1<0)hour1=23;LCD_ShowPicture2(0,283,32,315);LCD_ShowNum(0,283,hour1,2,BLUE,32,mode);break;case 8: min1--;if(min1<0)min1=59;LCD_ShowPicture2(50,283,82,315);LCD_ShowNum(50,283,min1,2,BLUE,32,mo de);break;case 9: flag3=0; LCD_ShowPicture2(445,0,480,36);break;default: break;}break;case WKUP_PRES:cc1();flag++;switch(flag){case 1: TIM_Cmd(TIM3, DISABLE); LCD_DrawLine(20,242,190,243,BLUE);break;case 2: LCD_ShowPicture1(242,243);LCD_DrawLine(290,242,460,243,BLUE); break;case 3: LCD_ShowPicture1(242,243); LCD_DrawLine(0,287,64,288,BLUE);break;case 4: LCD_ShowPicture1(287,288);LCD_DrawLine(96,287,128,288,BLUE);break;case 5: LCD_ShowPicture1(287,288); LCD_DrawLine(160,287,192,288,BLUE); break; case 6: LCD_ShowPicture1(287,288);LCD_DrawLine(256,287,288,288,BLUE); break; case 7: LCD_ShowPicture1(287,288); LCD_DrawLine(0,316,32,317,BLUE);break; case 8: LCD_ShowPicture1(316,317); LCD_DrawLine(50,316,82,317,BLUE);break;case 9: LCD_ShowPicture1(316,317); LCD_DrawLine(445,37,479,38,BLUE);break;case 10: LCD_ShowPicture2(445,37,479,38);ds_wtime();a=sec;b=min;c=hour;TIM_Cmd(TIM3, ENABLE);flag=0;break;default: break;}break;default: delay_ms(5); break;}}int main(void){delay_init();NVIC_Configuration();DHT11_Init ();KEY_Init();BEEP_GPIO_Config();BEEP( OFF );TIM3_Int_Init(9999,7199);ds1302_init();ds_read_time();cc();a=sec;b=min;c=hour;Lcd_Init();LCD_Clear(WHITE);gui0(1);TIM_Cmd(TIM3, ENABLE);while(1){t=KEY_Scan(0);keyscan(1);if( DHT11_Read_TempAndHumidity (&DHT11_Data ) == SUCCESS&&flag==0) {temp=DHT11_Data.temp_int;humi=DHT11_Data.humi_int;LCD_ShowPicture2(52,40,84,72);LCD_ShowPicture2(278,40,310,72);LCD_ShowNum(52,40,temp,2,BLUE,32,1);LCD_ShowNum(278,40,humi,2,BLUE,32,1);}if(flag==0&&min1==min&&hour1==hour&&flag2==0&&flag3==1) {BEEP( ON );}}}。
stm32最小电路设计
stm32最小电路设计
设想我们要设计一个最小的STM32电路,方便使用STM32微控制器进行开发。
这个最小电路设计应该包括以下几个部分:
1. STM32微控制器- 我们可以选择一个适合的STM32微控制器,例如STM32F103C8T6,它是很常用的型号之一。
2. 时钟电路- STM32微控制器需要一个稳定的时钟信号来驱动其内部工作。
我们可以使用一个晶体振荡器或者使用外部的时钟信号。
3. 供电电路- STM32微控制器需要正常的供电电压,一般可以使用5V直流电源。
在电路中需要提供稳压器进行降压和滤波,确保电压稳定。
4. 外部复位电路- 使用一个复位电路来对STM32微控制器进行复位,确保其正常启动。
5. 串口通信电路- 如果需要与计算机或其他外部设备进行通信,可以在电路中添加一个串口电路。
6. 输入输出引脚- 将STM32微控制器的输入输出引脚连接到外部电路,以实现各种功能。
需要特别注意的是,设计最小电路时需要根据具体的应用需求进行定制。
例如,如果需要使用ADC或PWM功能,还需要添加相应电路。
同时,为了方便编程和调试,还需要添加一个编程接口,如SWD或JTAG接口。
总之,设计STM32最小电路时需要根据具体的应用需求和开发目标进行定制,以上列举的是基本组成部分。
STM32的GPIO的总结
CRL 端口配置低寄存器CRH 端口配置高寄存器IDR 端口输入数据寄存器ODR 端口输出数据寄存器BSRR 端口位设置/复位寄存器BRR 端口位复位寄存器LCKR端口配置锁定寄存器EVCR MAPR I/O EXTICR 事件控制寄存器复用重映射和调试配置寄存器外部中断路线0-15配置寄存器GPIO_DeInit将外设GPIOx寄存器重设为缺省值GPIO_AFIODeInit 将复用功能(重映射事件控制和EXTI设置)重设为缺省值 GPIO_Init 根据GPIO_InitStruct中指定的参数初始化外设GPIOx寄存器 GPIO_StructInit把GPIO_InitStruct中的每一个参数按缺省值填入 GPIO_ReadInputDataBit 读取指定端口管脚的输入GPIO_ReadInputData GPIO_ReadOutputDataBit GPIO_ReadOutputData GPIO_SetBits GPIO_ResetBits GPIO_WriteBit GPIO_Write GPIO_PinLockConfig GPIO_EventOutputConfig GPIO_EventOutputCmd GPIO_PinRemapConfig读取指定的GPIO端口输入读取指定端口管脚的输出读取指定的GPIO端口输出设置指定的数据端口位清除指定的数据端口位设置或者清除指定的数据端口位向指定GPIO数据端口写入数据锁定GPIO管脚设置寄存器选择GPIO管脚用作事件输出使能或者失能事件输出改变指定管脚的映射GPIO_EXTILineConfig选择GPIO管脚用作外部中断路线函数8 种模式,可以通过编程选择:1. 浮空输入2. 带上拉输入3. 带下拉输入4. 摹拟输入5. 开漏输出——(此模式可实现 hotpower 说的真双向 IO)6. 推挽输出7. 复用功能的推挽输出8. 复用功能的开漏输出模式 7 和模式 8 需根据具体的复用功能决定。
STM32时钟配置方法详解
STM32时钟配置方法详解STM32是意法半导体(STMicroelectronics)公司推出的一系列32位Flash微控制器,被广泛应用于各种嵌入式系统中。
时钟是STM32微控制器的核心部分,正确配置时钟可以确保系统正常工作并达到预期的性能。
本文将详细介绍STM32时钟配置的方法。
1.时钟源:STM32微控制器提供了多个时钟源,包括内部时钟(HSI、LSI)和外部时钟(HSE、LSE)。
其中,HSI(高速内部时钟)是一个高频率(通常为8MHz)的内部RC振荡器,适用于低功耗应用;LSI(低速内部时钟)是一个低频率(通常为40kHz)的内部RC振荡器,用于RTC(实时时钟)模块;HSE(高速外部时钟)是一个外接的高频晶振,用于提供更精确的时钟信号;LSE(低速外部时钟)是一个外接的低频晶振,适用于RTC模块。
2.主频和系统时钟:主频是指CPU的时钟频率,系统时钟是指STM32微控制器的总线时钟,包括AHB(高性能总线)、APB1(低速外设总线)和APB2(高速外设总线)。
在进行STM32时钟配置之前,需要按照以下几个步骤来完成。
1.启用对应的时钟源:根据具体需求,选择合适的时钟源并启用相应的时钟。
可以通过设置RCC_CR寄存器和RCC_APB1ENR/RCC_APB2ENR寄存器来实现。
例如,要使用HSE作为时钟源,需要首先启用HSE时钟。
2.配置时钟分频器:为了使系统时钟不超过芯片规格要求的最大频率,需要对时钟进行分频。
分频器有两个,即AHB分频器和APB分频器。
可以通过设置RCC_CFGR寄存器来实现。
例如,将AHB分频器设置为8,将APB1和APB2分频器分别设置为4,可以将主频分别分频为8MHz、32MHz和64MHz。
3.等待时钟稳定:当启用外部时钟源时,需要等待时钟稳定。
可以通过读取RCC_CR寄存器的特定标志位来判断时钟是否稳定。
4. 配置Flash存储器的延时:根据主频的不同,需要设置Flash存储器的访问延时,以确保正常读写数据。
stm32外部时钟模式1
stm32外部时钟模式1基础了解时钟选择计数器时钟可由下列时钟源提供:●内部时钟(CK_INT)●外部时钟模式1:外部输⼊脚(TIx)●外部时钟模式2:外部触发输⼊(ETR)●内部触发输⼊(ITRx):使⽤⼀个定时器作为另⼀个定时器的预分频器在平常使⽤中我们系统复位 000 默认使⽤内部时钟源外部时钟源1来⾃定时器⾃⾝输⼊通道1或通道2的输⼊信号,经过极性选择和滤波以后⽣成的触发信号,连接到从模式控制器,进⽽控制计数器的⼯作;来⾃通道1的输⼊信号经过上升沿、下降沿双沿检测⽽⽣成的脉冲信号进⾏逻辑相或以后的信号就是TI1F_ED信号,即TI1F_ED双沿脉冲信号。
//SIGNAL_COUNT(GPIO)#define SIGNAL_COUNT_ENA_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() //PB0#define SIGNAL_COUNT_ENA_GPIO_Port (GPIOB)#define SIGNAL_COUNT_ENA_Pin (GPIO_PIN_0)#define SIGNAL_COUNT_DIR_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() //PA7#define SIGNAL_COUNT_DIR_GPIO_Port (GPIOA)#define SIGNAL_COUNT_DIR_Pin (GPIO_PIN_7)#define SIGNAL_COUNT_DIR_Get_IRQn (EXTI9_5_IRQn) //EXTI7中断//SIGNAL_COUNT(AFIO & TIM)#define SIGNAL_COUNT_PUL_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() //PA6#define SIGNAL_COUNT_PUL_GPIO_Port (GPIOA)#define SIGNAL_COUNT_PUL_Pin (GPIO_PIN_6)#define SIGNAL_COUNT_TIM_CLK_ENABLE() __HAL_RCC_TIM3_CLK_ENABLE() //TIM3#define SIGNAL_COUNT_Get_TIM (TIM3)#define SIGNAL_COUNT_Get_HTIM (htim3)//GPIO输⼊#define SIGNAL_COUNT_READ_DIR_IO() (SIGNAL_DIR_GPIO_Port -> IDR & SIGNAL_DIR_Pin)#define SIGNAL_COUNT_READ_ENA_IO() (SIGNAL_ENA_GPIO_Port -> IDR & SIGNAL_ENA_Pin)//TIM输⼊#define SIGNAL_COUNT_READ_COUNT() (SIGNAL_COUNT_Get_TIM -> CNT)//TIM输出#define SIGNAL_COUNT_UP() (SIGNAL_COUNT_Get_TIM -> CR1 &= ~(TIM_CR1_DIR))#define SIGNAL_COUNT_DOWN() (SIGNAL_COUNT_Get_TIM -> CR1 |= (TIM_CR1_DIR))/*** @brief TIM_SIGNAL_PUL初始化* @param NULL* @retval NULL**/void REIN_TIM_SIGNAL_COUNT_Init(void){/* GPIO初始化 */GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable*/SIGNAL_COUNT_PUL_CLK_ENABLE(); //启⽤SIGNAL_COUNT_PUL端⼝时钟/*Configure GPIO pin*/GPIO_InitStruct.Pin = SIGNAL_COUNT_PUL_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT; //输⼊模式GPIO_InitStruct.Pull = GPIO_NOPULL; //禁⽤上下拉HAL_GPIO_Init(SIGNAL_COUNT_PUL_GPIO_Port, &GPIO_InitStruct);/* TIM初始化 */TIM_SlaveConfigTypeDef sSlaveConfig = {0};TIM_MasterConfigTypeDef sMasterConfig = {0};SIGNAL_COUNT_TIM_CLK_ENABLE(); //启⽤TIM时钟SIGNAL_COUNT_Get_HTIM.Instance = SIGNAL_COUNT_Get_TIM;SIGNAL_COUNT_Get_HTIM.Init.Prescaler = 0; //预分频:0SIGNAL_COUNT_Get_HTIM.Init.CounterMode = TIM_COUNTERMODE_UP; //向上计数SIGNAL_COUNT_Get_HTIM.Init.Period = 65535; //16位周期SIGNAL_COUNT_Get_HTIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; //不分频SIGNAL_COUNT_Get_HTIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; //禁⽤⾃动重新加载if (HAL_TIM_Base_Init(&SIGNAL_COUNT_Get_HTIM) != HAL_OK){Error_Handler();}sSlaveConfig.SlaveMode = TIM_SLAVEMODE_EXTERNAL1; //外部时钟模式sSlaveConfig.InputTrigger = TIM_TS_TI1FP1; //TI1FP1sSlaveConfig.TriggerPolarity = TIM_TRIGGERPOLARITY_RISING; //上升沿触发sSlaveConfig.TriggerFilter = 4; //滤波参数(FDIV2_N6)if (HAL_TIM_SlaveConfigSynchro(&SIGNAL_COUNT_Get_HTIM, &sSlaveConfig) != HAL_OK){Error_Handler();}sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; //主机模式触发复位sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; //禁⽤主机模式if (HAL_TIMEx_MasterConfigSynchronization(&SIGNAL_COUNT_Get_HTIM, &sMasterConfig) != HAL_OK){Error_Handler();}/*begin work*/HAL_TIM_Base_Start(&SIGNAL_COUNT_Get_HTIM);}static void Signal_Count_Capture_Goal(void){//SignalPort获取⽬标//读取En_Pinif(SIGNAL_COUNT_READ_ENA_IO()){if(sg_cut.en_inve)sg_cut.en_valid = true;elsesg_cut.en_valid = false;}else{if(sg_cut.en_inve)sg_cut.en_valid = false;elsesg_cut.en_valid = true;}//采样(对⽐上次的计数值)sg_cut.sampling_count_last = sg_cut.sampling_count;sg_cut.sampling_count = SIGNAL_COUNT_READ_COUNT();sg_cut.sampling_count_sub = sg_cut.sampling_count - sg_cut.sampling_count_last;//采样(缓冲输出)//(采样数/细分数)*Move_Divide_NUM = 电机输出步数sg_cut.interp_out = sg_cut.sampling_count_sub * sg_cut.subdivide_form;//输出if(sg_cut.en_valid){signal_moreio.goal_location = sg_cut.interp_out; //Count模式借⽤⽬标位置存放⽬标位置增量 signal_moreio.goal_disable = false;signal_moreio.goal_brake = false;}else{signal_moreio.goal_location = 0; //Count模式借⽤⽬标位置存放⽬标位置增量signal_moreio.goal_disable = true;signal_moreio.goal_brake = false;}}。
stm32编程课程设计
stm32编程课程设计一、课程目标知识目标:1. 理解STM32的硬件结构和基本原理,掌握其编程基础知识;2. 学会使用C语言进行STM32程序的编写和调试;3. 掌握STM32的外设驱动开发,如GPIO、USART、ADC等;4. 了解嵌入式系统设计的基本流程,具备独立完成简单项目的能力。
技能目标:1. 培养学生运用所学知识解决实际问题的能力;2. 提高学生的程序编写和调试技巧,培养良好的编程习惯;3. 培养学生的团队协作和沟通能力,能够进行项目分工与合作。
情感态度价值观目标:1. 培养学生对嵌入式系统的兴趣和热情,激发学生的学习积极性;2. 培养学生面对困难勇于挑战、持续探究的精神;3. 增强学生的创新意识,培养创新精神和创新能力;4. 培养学生具备良好的职业道德,关注社会发展,为社会进步贡献力量。
分析课程性质、学生特点和教学要求,本课程目标旨在使学生在掌握STM32编程基础知识和技能的基础上,培养其解决实际问题的能力,提高学生的团队协作和创新能力。
通过本课程的学习,学生将能够独立完成简单的嵌入式项目,并为后续深入学习奠定坚实基础。
二、教学内容1. STM32硬件结构和原理:介绍STM32的内部结构、外设接口及工作原理,使学生了解嵌入式硬件基础。
- 教材章节:第1章 嵌入式系统概述,第2章 STM32硬件结构- 内容列举:微控制器概述、STM32内核、外设接口、时钟系统等。
2. C语言编程基础:回顾C语言基础知识,重点讲解与STM32编程相关的语法和技巧。
- 教材章节:第3章 C语言基础- 内容列举:数据类型、运算符、控制语句、函数、指针等。
3. STM32程序编写与调试:学习使用Keil MDK等开发工具进行STM32程序编写、编译和调试。
- 教材章节:第4章 开发工具与环境- 内容列举:Keil MDK安装与使用、程序编译与下载、调试方法等。
4. STM32外设驱动开发:学习GPIO、USART、ADC等外设的编程方法,掌握嵌入式系统外设应用。
STM32时钟配置方法详解
STM32时钟配置方法详解时钟树是STM32微控制器中一系列时钟源和时钟分频器的组成部分。
时钟树包括系统时钟、外设时钟和内核时钟。
系统时钟用于驱动整个微控制器系统的核心,外设时钟用于驱动各种外设,内核时钟用于驱动CPU的运算。
在进行时钟配置之前,首先需要了解系统所需的时钟频率。
在STM32中,系统时钟可以通过多种方式进行配置,例如使用外部晶体、外部时钟、内部RC振荡器或者PLL(锁相环)等方式。
外部晶体是一种常用的时钟源,可以提供高精度的时钟频率。
在使用外部晶体时,首先需要设置PLL的时钟源为外部晶体,并设置PLL输入除频器的分频系数。
然后,再根据系统所需的时钟频率,设置PLL的倍频系数,以得到最终的系统时钟频率。
外部时钟是从外部提供的时钟信号,一般用于测试和调试。
使用外部时钟时,需要设置PLL的时钟源为外部时钟,并设置PLL的倍频系数,以得到所需的系统时钟频率。
内部RC振荡器是一种低成本的时钟源,但是其频率不如外部晶体稳定和精确。
在使用内部RC振荡器时,需要设置PLL的时钟源为内部RC振荡器,并设置PLL的倍频系数,以得到所需的系统时钟频率。
PLL是一种用于产生稳定高频时钟的电路,可以从一个低频时钟源产生一个高频时钟源。
使用PLL时,需要设置其输入时钟源和倍频系数。
系统时钟的分频系数可以通过RCC_CFGR寄存器进行设置。
RCC_CFGR寄存器的各个位域用于配置系统时钟的分频系数,包括分频因子、APB1的分频系数、APB2的分频系数等。
外设时钟是用于驱动外设的时钟,可以由系统时钟分频得到。
外设时钟的分频系数可以通过RCC_CFGR寄存器及各个外设的控制寄存器进行设置。
内核时钟是用于驱动CPU的运算的时钟。
在STM32微控制器中,CPU 时钟可以由系统时钟分频得到,分频系数可以通过RCC_CFGR寄存器和FLASH_ACR寄存器进行设置。
除了上述方法之外,STM32还可以使用时钟配置工具进行时钟配置。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
挂载在APB1上的外设名
#define
RCC_APB1Periph_TIM2 #define RCC_APB1Periph_TIM3 … … #define RCC_APB1Periph_TIM14 #define RCC_APB1Periph_WWDG #define RCC_APB1Periph_SPI2 #define RCC_APB1Periph_SPI3 #define RCC_APB1Periph_USART2 #define RCC_APB1Periph_USART3 #define RCC_APB1Periph_UART4 #define RCC_APB1Periph_UART5 #define RCC_APB1Periph_I2C1 #define RCC_APB1Periph_I2C2 #define RCC_APB1Periph_USB #define RCC_APB1Periph_CAN1 #define RCC_APB1Periph_CAN2 #define RCC_APB1Periph_BKP #define RCC_APB1Periph_PWR #define RCC_APB1Periph_DAC #define RCC_APB1Periph_CEC
嵌入式系统与应用
Embedded System Development
第8章 STM32时钟与GPIO设计
8.1 8.2 8.3 8.4 8.6
时钟设置与开启外设时钟 GPIO简介 GPIO端口配置寄存器 stm32f10x.h库中GPIO代码剖析 GPIO控制LED灯实验
8.1 系统时钟配置与外设时钟开启
((uint32_t)0x00000001) ((uint32_t)0x00000002) ((uint32_t)0x00000100) ((uint32_t)0x00000800) ((uint32_t)0x00004000) ((uint32_t)0x00008000) ((uint32_t)0x00020000) ((uint32_t)0x00040000) ((uint32_t)0x00080000) ((uint32_t)0x00100000) ((uint32_t)0x00200000) ((uint32_t)0x00400000) ((uint32_t)0x00800000) ((uint32_t)0x02000000) ((uint32_t)0x04000000) ((uint32_t)0x08000000) ((uint32_t)0x10000000) ((uint32_t)0x20000000) ((uint32_t)0x40000000)
RCC_APB2Periph_AFIO RCC_APB2Periph_GPIOA RCC_APB2Periph_GPIOB RCC_APB2Periph_GPIOG RCC_APB2Periph_ADC1 RCC_APB2Periph_ADC2 RCC_APB2Periph_TIM1 RCC_APB2Periph_SPI1 RCC_APB2Periph_TIM8 RCC_APB2Periph_USART1 RCC_APB2Periph_ADC3 RCC_APB2Periph_TIM15 RCC_APB2Periph_TIM16 RCC_APB2Periph_TIM17 RCC_APB2Periph_TIM9 RCC_APB2Periph_TIM10 RCC_APB2Periph_TIM11
RCC时钟寄存器组在stm32f10x.h中的定义
typedef struct __IO 宏定义core_cm3.h中: { __IO uint32_t CR; #define __IO volatile; __IO uint32_t CFGR; __IO uint32_t CIR; –volatile,易变的,用变量时需 __IO uint32_t APB2RSTR; 到原地址重新存取。 __IO uint32_t APB1RSTR; uint32_t定义在stdin.h里。 __IO uint32_t AHBENR; __IO uint32_t APB2ENR; typedef unsigned int uint32_t; __IO uint32_t APB1ENR; 知道了结构体首地址就确定RCC __IO uint32_t BDCR; __IO uint32_t CSR; 寄存器组所有32位寄存器的地址, #ifdef STM32F10X_CL 0x04正好是地址偏移量,所以把连 __IO uint32_t AHBRSTR; 续的寄存器组定义为结构。 __IO uint32_t CFGR2; #endif /* STM32F10X_CL */ #if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL) uint32_t RESERVED0; __IO uint32_t CFGR2; #endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */ } RCC_TypeDef;
在startup_stm32f10x_hd.s启动文件中,调用__main函 数之前先调用了SystemInit()初始化函数,其中系统时钟 SYSCLK设置:时钟源、倍频、分频it()定义在system_stm32f10x.c文件中,其他 的配置主要在stm32f10x_rcc.c中。 使用外设时,配置初始化后,必须也要开启外设时钟。
2、SetSysClock()函数如下
此函数中选择调用确定使用频率的函数。 static void SetSysClock(void) {#ifdef SYSCLK_FREQ_HSE SetSysClockToHSE(); #elif defined SYSCLK_FREQ_24MHz SetSysClockTo24(); #elif defined SYSCLK_FREQ_36MHz SetSysClockTo36(); #elif defined SYSCLK_FREQ_48MHz SetSysClockTo48(); #elif defined SYSCLK_FREQ_56MHz SetSysClockTo56(); #elif defined SYSCLK_FREQ_72MHz // 使用此项 SetSysClockTo72(); #endif}
欲深入分析时钟配置,就仔细阅读这些最底层的库函数!
8.1.2 开启关闭外设时钟
外设都是挂在AHB、APB1、APB2总线上,要想使用某个外 设,必须初始化外设后,再开启使用开启外设的时钟, 不用时再关闭外设时钟,从而降低STM32的整体功耗。 stm32f10x_rcc.c文件中有开启和关闭外设时钟的库函数 ,如下: RCC_AHBPeriphClockCmd(外设名,ENABLE|DISABLE) –挂在AHB总线外设的开启与关闭函数,ENABLE开启, DISABLE关闭外设时钟; RCC_APB1PeriphClockCmd(外设名,ENABLE|DISABLE) –挂在APB1总线外设的开启与关闭函数; RCC_APB2PeriphClockCmd(外设名,ENABLE|DISABLE) –挂在APB2总线外设的开启与关闭函数;
8.1.1 时钟设置解析
系统时钟SYSCLK是SystemInit()先将配置时钟相关的 寄存器都复位为默认值,再调用SetSysClock()选择使 用频率,而具体设置是通过宏定义设置的。 函数调用顺序: 启动文件 → SystemInit() → SetSysClock () → SetSysClockTo72()。
挂载在AHB的外设名
stm32f10x_rcc.h中对外设名进行了宏定义,看名即知设 备。
#define #define #define #define #define #define #define #define #define #define #define RCC_AHBPeriph_DMA1 ((uint32_t)0x00000001) RCC_AHBPeriph_DMA2 ((uint32_t)0x00000002) RCC_AHBPeriph_SRAM ((uint32_t)0x00000004) RCC_AHBPeriph_FLITF ((uint32_t)0x00000010) RCC_AHBPeriph_CRC ((uint32_t)0x00000040) RCC_AHBPeriph_FSMC ((uint32_t)0x00000100) RCC_AHBPeriph_SDIO ((uint32_t)0x00000400) RCC_AHBPeriph_OTG_FS ((uint32_t)0x00001000) RCC_AHBPeriph_ETH_MAC ((uint32_t)0x00004000) RCC_AHBPeriph_ETH_MAC_Tx ((uint32_t)0x00008000) RCC_AHBPeriph_ETH_MAC_Rx ((uint32_t)0x00010000)
挂载在APB2上的外设名
#define #define #define … … #define #define #define #define #define #define #define #define #define #define #define #define #define #define
1、SystemInit()
STM32时钟系统的SystemInit()中设置:
–SYSCLK(系统时钟)=72MHz –AHB总线时钟(使用SYSCLK)=72MHz –APB1总线时钟(PCLK1)=36MHz –APB2总线时钟(PCLK2)=72MHz –PLL时钟=72MHz 用到的RCC寄存器复位值: –RCC_CR = 0x0000 xx83; –RCC_CFGR = 0x0000 0000; –RCC_CIR = 0x0000 0000; –RCC_CFGR2 = 0x0000 0000; –… … 这些RCC时钟寄存器组名的宏定义与其他外设寄存器名定 义都在stm32f10x.h文件中。