查看: 1536|回复: 0

STM32L496 Discovery kit时钟和串口

[复制链接]

该用户从未签到

发表于 2018-2-2 13:57:14 | 显示全部楼层 |阅读模式
分享到:
代码还是从stm32cubel4开始说起吧,该封装包括微控制器底层(LL)和硬件抽象层(HAL),另外每一个开发板还有支持板子特性的封装(BSP),这三类构成了底层软件,通过中间件就可以到上层应用。
然后开始看我的第一个工程LED,选择的代码阅读工具是sourceinsight,该工具可以方便地定位代码。

硬件相关的代码都是从启动代码开始,也就是板子一上电开始执行的代码位置,在stm32系列微控制器中一般是startup_stm32xxxxx.s文件名,根据处理器类型在这里是startup_stm32l496xx.s文件。启动文件主要的作用是:
设置初始化堆栈指针SP
设置初始程序计数器PC
设置异常向量表入口
设置C库的__mian分支,最终调用主函数main()
Reset异常,也是上电之后会进入的异常,执行系统初始化,进入主函数
Reset_HandlerPROC
EXPORTReset_Handler[WEAK]
IMPORTSystemInit
IMPORT__main
LDRR0, =SystemInit
BLXR0
LDRR0, =__main
BXR0
ENDP
void SystemInit(void)位于system_stm32l4xx.c文件中,用于设置微控制器系统。像FPU、RCC的设置。
然后就会跳到主函数,也是自己创建的C入口,一般文件名是main.c。在LED工程中,使用HAL来配置和使用GPIO控制LED等的亮与灭。因此在操作GPIO之前需要对HAL库初始化,并且在系统时钟初始化之前调用HAL_StatusTypeDef HAL_Init(void),主要作用是:
配置Flash预读取使能,指令和数据缓存使能
配置滴答计时器作为时间基准
设置向量中断控制器分组优先级
底层硬件初始化
在主函数里面配置系统时钟为80MHz,系统时钟源是PLL。时钟的具体配置在之后详细介绍,主要是设置PLL为时钟源,对RCC Oscillators配置,CPU, AHB 和APB总线时钟配置。
然后就进入到外设功能模块的设置,void BSP_LED_Init(Led_TypeDef Led),首先是对LED对应引脚设置,使能对应GPIO时钟,设置为输出模式,默认关闭LED。
最后在一个无限循环中开启LED1,关闭LED2,延时500ms,关闭LED1,开启LED2,延时500ms。对应的LED开关为void BSP_LED_On(Led_TypeDef Led),void BSP_LED_Off(Led_TypeDef Led),延时函数使用void HAL_Delay(uint32_t Delay)。
接下来就在此工程基础上实现其他功能。
另外上一节发现的不添加stm32l4xx_it.c和对应的头文件LED灯就跑不起来,究其原因,主要是在stm32l4xx_it.c中有一个中断void SysTick_Handler(void)处理滴答时钟,与时钟有很大的关系。当然stm32l4xx_it相关的头文件和源文件可以不使用而是把SysTick_Handler中断处理放在其他文件中。
然后细致分析一下STM32L496的时钟树和对应的时钟配置。时钟控制器可以从不同的振荡器配置内核和外设的时钟。时钟控制器管理低功耗模式的时钟选通和确保时钟的鲁棒性。特点包括:时钟预分频、安全切换时钟源、时钟管理、系统时钟源、RC48时钟恢复系统(HSI48)、辅助时钟源(32.768kHz低速振荡器(LSE)和32kHz低速内部RC(LSI))、外设时钟源、启动时钟、时钟安全系统(CSS)、时钟输出性能。四种系统时钟源用来驱动SYSCLK,包括4-48MHz高速外部晶振或者陶瓷谐振器(HSE)应用于PLL,在bypass模式HSE可以配置为一种外部时钟;16MHz高速内部RC振荡器(HSI16),软件微调,可以应用于PLL;多速内部RC振荡器(MSI),软件微调,可以产生100kHz到48MHz 的12种频率,当32.768kHz时钟源在系统中可用(LSE),MSI频率可以通过硬件自动调整达到大约±0.25% 的精度,MSI可以应用于PLL;由HSE,HSI16或者MSI产生的系统PLL最大频率可达80MHz。几个预分频器允许配置AHB频率、高速APB(APB2)和低速APB(APB1)。AHB和APB的最大频率是80MHz。
代码在启动的时候进入void SystemInit(void),该函数对Reset and clock control(RCC)进行复位配置到默认的复位状态,主要操作是:

  • 1.设置控制寄存器CR的MSION位,置1,使能MSI时钟


  • 2.复位时钟配置寄存器CFGR,所有位设置为0


  • 3.HSEON, [url=]CSSON[/url] , HSION, PLLON位复位


  • RCC->CR &= (uint32_t)0xEAF6FFFF;


  • 1110 1010 1111 0110 1111 1111 1111 1111
第16位,使能HSE时钟
第19位,使能时钟安全系统CSSON
第24位,使能PLL
第26位,使能SAI1 PLL
第28位,使能SAI2 PLL


  • 4.复位PLL配置寄存器PLLCFGR,RCC-&gtLLCFGR = 0x00001000;

00000 00 0 0 00 0 0 0 0 0 0 [url=]0010000[/url] 0 000 0 0 00
从低位到高位解析
PLLSRC:00 关闭PLL, PLLSAI1和PLLSAI2的时钟源
PLLM:000 设置为1
PLLN:001000016
PLLPEN:0 失能PLLSAI3CLK
PLLP:PLLSAI3CLK (SAI1 and SAI2 clock)分频系数 0->7 1->17
PLLQEN:失能PLL48M1CLK输出
PLLQ:PLL48M1CLK分频系数 00->2
PLLREN:失能PLLCLK输出
PLLR:PLLCLK(系统时钟)分频系数 00->2
PLLPDIV:PLLSAI3CLK00000-&gtLLSAI3CLK由PLLP控制
PLL的计算方式
f(VCO clock) = f(PLL clock input) × (PLLN / PLLM)
f(PLL_P) = f(VCO clock) / PLLP
f(PLL_Q) = f(VCO clock) / PLLQ
f(PLL_R) = f(VCO clock) / PLLR


  • 5.CR的HSEBYP复位,设置为0,不饶过HSE振荡器


  • 6.时钟中断使能寄存器CIER,禁止所有时钟中断
以上就是一开始对时钟的reset配置。
在处理器启动起来之后进入应用就要重新对时钟进行配置。void SystemClock_Config(void)就是在运行应用前的一种配置。在分析SystemClock_Config之前,先看看HAL_StatusTypeDef HAL_Init(void)中对时钟的初始化配置,在时钟配置之前应该先调用HAL_Init。HAL_Init调用HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)函数使用SysTick作为时间基准源,并且配置1ms的滴答声(MSI)。HAL_InitTick函数配置时钟基准源包括配置SysTick为1ms的中断,配置SysTick中断优先级。MSI为SYSCLK的时钟源,并且默认值为4MHz,复位的时候使用的是默认值并且没有改变,systick没有分频,时钟源是AHB,这样就可以设置systick的RELOAD值为(4000-1)。
然后进入SystemClock_Config配置,主要是系统时钟配置:
系统时钟源PLL(MSI)
SYSCLK 80MHz,HCLK 80MHz,AHB分频1,APB1分频1, APB2分频1,MSI 4MHz,PLL_M 1,PLL_N 40,PLL_R 2,PLL_P 7,PLL_Q 4,Flash延迟(WS) 4
除了在线调试外,常用的方式就是打印信息到串口,分析串口的输出信息来调试代码。首先分析stm32l4xx_hal_uart.c文件
UART_HandleTypeDef:串口相关结构,像波特率,传输位数,停止位等等
HAL_UART_MspInit():用来初始化底层资源
HAL_UART_Init():异步模式初始化串口寄存器
HAL_HalfDuplex_Init():半双工模式初始化串口寄存器
HAL_LIN_Init():本地互联模式初始化串口寄存器
HAL_MultiProcessor_Init():多处理器模式初始化串口寄存器
HAL_RS485Ex_Init():RS485驱动使能模式初始化串口寄存器
该文件函数定义之前有一个宏#ifdef HAL_UART_MODULE_ENABLED,因此要使用包含的函数,必须定义对应的宏,HAL的宏均在一个指定的文件stm32l4xx_hal_conf.h定义。stm32l4xx_hal_conf.h文件定义了HAL的大部分功能宏,如果要使用对应的功能只需要取消宏的注释即可。然后把stm32l4xx_hal_uart.c加入到工程中,编译工程会出现未定义HAL_UARTEx_WakeupCallback,该函数在tm32l4xx_hal_uart_ex.c中,添加再编译没问题。

接下来开始串口的功能实现。由于开发板上没有USB转串口功能,因此需要外加一个USB转串口模块把数据传输到PC上。
开发板发送IO口TX对应到GPIO PB6,接收IO RX对应到GPIO RX。对应的串口初始化包括串口协议像波特率,数据位,奇偶校验设置、底层硬件配置和接收中断处理。



可惜最后开发板只能发送数据而不能接收数据,经验证并没有触发串口接收中断,具体改进待下一步验证。

file:///C:/Users/FUCK/AppData/Local/Temp/msohtmlclip1/01/clip_image016.jpg
回复

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /2 下一条

手机版|小黑屋|与非网

GMT+8, 2024-4-20 22:00 , Processed in 0.118598 second(s), 17 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.