完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
由于近期在准备海洋航行器比赛,正好趁此机会学习一下ARM,看到周围很多同学都在使用32,所以我也买了一块STM32F103ZET6,准备好好地学习一下。
STM32的时钟系统相当的复杂,包含了5个时钟源,分别是HSI HSE LSI LSE PLL,HSI是高速内部时钟、RC振荡器,频率为8M,HSE是高速外部时钟,即晶振,我的核心板上晶振为8M。LSI为低速内部时钟、RC振荡器,频率40k,LSE为低速外部时钟,接32.768kHz晶振,作为RTC时钟源。PLL为锁相环倍频输出,最大不超过72M。 我在学习定时器时先看的是TIM3,它挂载在APB1分频器上,APB1上面挂载的是低速外设,APB2上挂载高速外设。 在system_stm32f10x.c文件下,有默认定义SYSCLK_FREQ_72MHz,同时在SystemInit()函数下调用了SetSysClock(),根据宏定义将时钟设为72M。 读取SystemCoreClock变量即可获得系统时钟频率。 在默认情况下,系统的各个时钟频率如下: SYSCLK:72M AHB:72M APB1(PCLK1):36M APB2(PCLK2):72M PLL:72M 详细的定时器设定如下: ①首先要搞清楚定时器的计数时钟频率,在预分频系数≠1的时候,TIM2~7的时钟频率为APB1的2倍,即72MHz,预分频系数的默认值不是1,但我并未查到该如何设置该值。 ②定时器的设置主要包括定时器的初始化和中断的初始化。 2.1 定时器初始化: 首先定义TIM_TimeBaseInitTypeDef类型的结构体,它包含了如下的内容: typedef struct { uint16_t TIM_Prescaler; uint16_t TIM_CounterMode; uint16_t TIM_Period; uint16_t TIM_ClockDivision; uint8_t TIM_RepetitionCounter; } TIM_TimeBaseInitTypeDef; 第一项TIM_Prescaler是预分频值,它与TIM_Period(重载周期值)的乘积即为计数的总值。 第二项TIM_CounterMode为计数模式,它的内容如下: #define TIM_CounterMode_Up ((uint16_t)0x0000) #define TIM_CounterMode_Down ((uint16_t)0x0010) #define TIM_CounterMode_CenterAligned1 ((uint16_t)0x0020) #define TIM_CounterMode_CenterAligned2 ((uint16_t)0x0040) #define TIM_CounterMode_CenterAligned3 ((uint16_t)0x0060) 后面三项为中心对齐模式,指的是计数到一定的值,产生溢出事件,再向下计数到0。常用的为向上计数模式,即TIM_CounterMode_Up 第四项TIM_ClockDivision为时钟分割,对于时钟分割没有查到太多的描述,一般设定为TIM_CKD_DIV1,或者直接填入0x0000。 第五项TIM_RepetitionCounter为PWM模式的一些设定,一般的定时器不用设置。 除此之外还要设置中断的类型,一般的定时器为更新中断,即由溢出事件产生的中断,设置的方式为:TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE),其中第一项是定时器代号,第二项为类型,这里设定为更新方式,第三项为使能。 根据上述内容我们知道,初始化的过程如下: 3 TIM_TimeBaseInitTypeDef TIM_STR; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//TIM3挂载在APB1上 //由于预分频系数默认不是1,所以TIM3的时钟为2*APB1=72M TIM_STR.TIM_Period=arr; TIM_STR.TIM_Prescaler=psc; //(arr+1)*(psc+1)/TIM时钟=定时器溢出中断触发周期 TIM_STR.TIM_ClockDivision=TIM_CKD_DIV1; TIM_STR.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3,&TIM_STR); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); 2.2 中断初始化: 中断初始化为操作NVIC(嵌套向量中断控制器)函数。 设置方式如下: NVIC_STR.NVIC_IRQChannel=TIM3_IRQn;//设定为TIM3中断 NVIC_STR.NVIC_IRQChannelPreemptionPriority=0;//先占优先级0级 NVIC_STR.NVIC_IRQChannelSubPriority=3;//从优先级3级 NVIC_STR.NVIC_IRQChannelCmd=ENABLE;//IRQ通道时能 NVIC_Init(&NVIC_STR);//中断初始化 TIM_Cmd(TIM3,ENABLE);//TIM3定时器使能 2.3 把这些都封装成一个函数,既可作为TIM3的初始化函数。如下: void TIM3_Init(u16 arr,u16 psc) { //定时时间=(arr+1)*(psc+1)/72 单位为us TIM_TimeBaseInitTypeDef TIM_STR; NVIC_InitTypeDef NVIC_STR; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //初始化定时器 TIM_STR.TIM_Period=arr; TIM_STR.TIM_Prescaler=psc; TIM_STR.TIM_ClockDivision=TIM_CKD_DIV1; TIM_STR.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3,&TIM_STR); TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //初始化中断 NVIC_STR.NVIC_IRQChannel=TIM3_IRQn; NVIC_STR.NVIC_IRQChannelPreemptionPriority=0; NVIC_STR.NVIC_IRQChannelSubPriority=3; NVIC_STR.NVIC_IRQChannelCmd=ENABLE; NVIC_Init(&NVIC_STR); //使能定时器 TIM_Cmd(TIM3,ENABLE); } ③中断服务函数: 中断函数的名字,TIM3的为TIM3_IRQHandler 中断服务函数内包含了:判断是否发生中断、中断发生后执行的内容、清除标志位三部分。 首先是判断是否发生了更新中断,利用库函数TIM_GetITStatus(P1,P2),它的参数P1为代号,这里是TIM3,P2为中断类型,这里为更新中断TIM_IT_Update,当它为1时即发生了更新中断,这里为了增强可读性,采用一个RESET代表0,当函数返回值不是RESET的时候,即发生了置位(中断)。 清除标志位采用的是库函数TIM_ClearITPendingBit(P1,P2),参数与判断的函数一样。 具体函数如下: void TIM3_IRQHandler(void) { if(TIM_GetITStatus(TIM3,TIM_IT_Update)!=RESET) { TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //在这里执行中断内容 } } ④完成调用 只要在main函数里调用TIM3_Init()函数,并填入适当的参数,即可实现精确的定时中断,例如获得一秒,即72M个数字中断一次,可分解为10000*7200,配置如下: TIM3_Init(9999,7199); |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1561 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1501 浏览 1 评论
933 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
665 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1555 浏览 2 评论
1847浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
609浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
503浏览 3评论
507浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
488浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 15:43 , Processed in 0.464516 second(s), Total 45, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号