STM32填坑:时钟使能必须在外设初始化之前

发布者:创意探险最新更新时间:2018-11-30 来源: eefocus关键字:STM32  时钟使能  外设初始化 手机看文章 扫描二维码
随时随地手机看文章

最近在STM32上写了一份串口通信的程序,但下载复位后串口却不能工作,初始化的代码如下:


//发送/接收的GPIO、串口和中断的初始化结构体

GPIO_InitTypeDef GPIO_InitStructureTx;

GPIO_InitTypeDef GPIO_InitStructureRx;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;


//设置发送和接收引脚

GPIO_InitStructureTx.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructureRx.GPIO_Pin = GPIO_Pin_10;

//发送引脚设置为推挽复用、接收引脚设置为浮空输入

GPIO_InitStructureTx.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructureRx.GPIO_Mode = GPIO_Mode_IN_FLOATING;

//设置引脚工作频率

GPIO_InitStructureRx.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructureTx.GPIO_Speed = GPIO_Speed_50MHz;

//引脚初始化

GPIO_Init(GPIOA, &GPIO_InitStructureTx);

GPIO_Init(GPIOA, &GPIO_InitStructureRx);


//波特率

USART_InitStructure.USART_BaudRate = USART_BaudRate;

//数据长度

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

//停止位

USART_InitStructure.USART_StopBits = USART_StopBits_1;

//校验位

USART_InitStructure.USART_Parity = USART_Parity_No;

//流控制

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

//打开发送和接收模式

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

//初始化串口1

USART_Init(USART1, &USART_InitStructure);

 

//时钟使能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

//配置中断优先级

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;

NVIC_InitStructure.NVIC_IRQChannelCmd = state;

//中断初始化

NVIC_Init(&NVIC_InitStructure);

 

//串口1使能

USART_Cmd(USART1, ENABLE);

 

//打开串口1接收中断

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);


可以看到,外设时钟使能放在了GPIO和USART的初始化之后。在网上查了下资料,发现STM32外设未被使能的情况下外设的寄存器无法被设置。引用一个解释:


 “ARM的芯片,外设通常都是给了时钟后才能设置它的寄存器(即才能使用这个外设)。STM32、LPC1XXX等等都是这样,这么做的目的是为了省电,使用了所谓时钟门控的技术。寄存器是基于触发器的,触发器的赋值是一定需要时钟的,而寄存器的时钟是由总线时钟提供的,就是说没有总线时钟的话,你给寄存器值它是不会读入的。”


因此,把外设时钟使能放在GPIO和USART初始化之前,就解决了这个问题,最终代码如下:


//发送/接收的GPIO、串口和中断的初始化结构体

GPIO_InitTypeDef GPIO_InitStructureTx;

GPIO_InitTypeDef GPIO_InitStructureRx;

USART_InitTypeDef USART_InitStructure;

NVIC_InitTypeDef NVIC_InitStructure;

 

//时钟使能(时钟使能放在GPIO和USART初始化之前)

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

 

//设置发送和接收引脚

GPIO_InitStructureTx.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructureRx.GPIO_Pin = GPIO_Pin_10;

//发送引脚设置为推挽复用、接收引脚设置为浮空输入

GPIO_InitStructureTx.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructureRx.GPIO_Mode = GPIO_Mode_IN_FLOATING;

//设置引脚工作频率

GPIO_InitStructureRx.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructureTx.GPIO_Speed = GPIO_Speed_50MHz;

//引脚初始化

GPIO_Init(GPIOA, &GPIO_InitStructureTx);

GPIO_Init(GPIOA, &GPIO_InitStructureRx);


//波特率

USART_InitStructure.USART_BaudRate = USART_BaudRate;

//数据长度

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

//停止位

USART_InitStructure.USART_StopBits = USART_StopBits_1;

//校验位

USART_InitStructure.USART_Parity = USART_Parity_No;

//流控制

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

//打开发送和接收模式

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

//初始化串口1

USART_Init(USART1, &USART_InitStructure);

 

 

//配置中断优先级

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PreemptionPriority;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = SubPriority;

NVIC_InitStructure.NVIC_IRQChannelCmd = state;

//中断初始化

NVIC_Init(&NVIC_InitStructure);

 

//串口1使能

USART_Cmd(USART1, ENABLE);

 

//打开串口1接收中断

USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);


关键字:STM32  时钟使能  外设初始化 引用地址:STM32填坑:时钟使能必须在外设初始化之前

上一篇:stm32f103 rcc时钟寄存器设置和usart寄存器
下一篇:LPC1768菜鸟学习之ADC

推荐阅读最新更新时间:2024-03-16 16:18

stm32串口的flag和it标志位
今天用到stm32的串口,对串口进行配置进行接受数据。之后大家也可以想象到结果是什么,完全没有用哎! 后来慢慢的发现了问题的所在,现做笔记如下: ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT); USART_IT参数: #define USART_IT_PE ((uint16_t)0x0028) #define USART_IT_TXE ((uint16_t)0x0727) #define USART_IT_TC ((uint16_t)0x0626
[单片机]
STM32的各种时钟系统的应用解析
时钟系统是处理器的核心,所以在学习STM32所有外设之前,认真学习时钟系统是必要的,有助于深入理解STM32。 重要的时钟: PLLCLK,SYSCLK,HCKL,PCLK1,PCLK2 之间的关系要弄清楚; 1、HSI:高速内部时钟信号 STM32单片机内带的时钟 (8M频率) 精度较差 2、HSE:高速外部时钟信号 精度高 来源(1)HSE外部晶体/陶瓷谐振器(晶振) (2)HSE用户外部时钟 3、LSE:低速外部晶体 32.768kHz 主要提供一个精确的时钟源 一般作为RTC时钟使用 在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②
[单片机]
STM32 RTC寄存器操作步骤
寄存器操作步骤 1、使能电源时钟和备份区域时钟。 我们要访问 RTC 和备份区域就必须先使能电源时钟 和 备份区域时钟。这个通过RCC_APB1ENR 寄存器来设置。 2、取消备份区写保护。 要向备份区域写入数据,就要先取消备份区域写保护(写保护在每次硬复位之后被使能),否则是无法向备份区域写入数据的。我们需要用到向备份区域写入一个字节,来标记时钟已经配置过了,这样避免每次复位之后重新配置时钟。 3、复位备份区域,开启外部低速振荡器。 在取消备份区域写保护之后,我们可以先对这个区域复位,以清除前面的设置,当然这个操作不要每次都执行,因为备份区域的复位将导致之前存在的数据丢失,所以要不要复位,要看情况而定。然
[单片机]
STM32在MDK中使用外部RAM浅解
使用简介: 开发板 神舟王STM32F207开发板 问题描述: 在使用emwin的时候由于占用的变量较多,出现了STM32F207内部RAM不够用的尴尬局面,开发板自带了4M的外部SRAM,因此考虑速度和存储的平衡,使用芯片内部RAM作为堆栈区使用,外部RAM则用来存储其他变量 修改内容: 启动文件即startup_stm32f2xx.s文件 1.添加标志量:DATA_IN_ExtSRAM EQU 1 ;主要是方便控制切换使用内部和外部RAM 2.修改栈区: IF DATA_IN_ExtSRAM == 1 __initial_sp EQU 0x20000000 + Stack_Size
[单片机]
<font color='red'>STM32</font>在MDK中使用外部RAM浅解
STM32中的独立看门狗和窗口看门狗
一、前言 在早期的MCU中是没有看门狗这种东西的,所以产品就很容易出现死机,跑飞的情况。为了避免这种情况的出现,后期的MCU都集成了看门狗的功能。但是目前看门狗发展到今天基本上分为两大类:独立看门狗和窗口看门狗。 独立看门狗:使用的是外部时钟,即使主频不工作了,看门狗也能正常工作。只要在到达喂狗时间的上限前喂狗即表示程序是正常的,这点和窗口看门狗是有区别的。另外独立看门狗是独立于整个系统之外的,这也是独立看门狗名字的由来,他有自己独立的时钟,不受整个系统的影响,所以独立看门狗主要用来监控硬件上的错误。 窗口看门狗:使用芯片内部时钟。喂狗的时间既有上限又有下限,即喂狗太早或者太晚都不行,比如我要求你在0.8s到0.9s内完成
[单片机]
出货超40亿颗,STM32前景光明
意法半导体(以下简称ST)在MCU领域的地位是毋庸置疑的。 根据IHS 的数据统计显示,2018年,ST MCU(不含汽车和安全MCU)的全球出货量位居全球第二。其通用加汽车MCU在中国的出货量更是高居第一,领先于排名第二的的NXP。 STM 32 过去九年的的出货量 尤其是其STM32 MCU的出货,更是表现惊人。据IHS统计,过去四年,STM32的平均年复合增长率高达30%,去年公司的STM32出货量更是达到了12亿颗。统计2007年到现在的数据,公司的STM32出货量更是超过40亿片,服务的客户也超过四万家。能获得这样的成绩主要得益于公司过去多年来在产品和技术上的投入。 在日前于深圳举办的“STM32中
[单片机]
出货超40亿颗,<font color='red'>STM32</font>前景光明
STM32系统学习——I2C (读写EEPROM)
I2C 通讯协议(Inter-Integrated Circuit)引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。 在计算机科学里,大部分复杂的问题都可以通过分层来简化。如芯片被分为内核层和片上外设;STM32 标准库则是在寄存器与用户代码之间的软件层。对于通讯协议,我们也以分层的方式来理解,最基本的是把它分为物理层和协议层。 物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。简单来说物理层规定我们用嘴巴还是用肢体来交流, 协议层则规定我
[单片机]
<font color='red'>STM32</font>系统学习——I2C (读写EEPROM)
4. stm32启动代码分析(一)
硬件平台: stm32f407ve 软件平台: win10 (OS Name: Microsoft Windows 10 Enterprise OS Version: 10.0.18363 N/A Build 18363) Keil5 5.26.2 HAL库版本: 2.14.0(目前下载的最新的) 库函数的使用要得益于你本身对c语言指针,结构体,及结构体指针的认识。如果你对这些的熟悉程度不够的话,只能说会阻止你进一步前进。 硬件方面,你最好能有基本的数电模电常识,有单片机理论基础,或者微机原理理论,这样你在理解这些硬件组成,或者电路
[单片机]
4. <font color='red'>stm32</font>启动代码分析(一)
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved