今天在本地找到了个2k+的嵌入式实习,明天开始上班了,希望在那个小公司里能学到真本事。
今天用的是TIM6定时器,属于基本定时器。
TIM6模块具有以下特点和功能:
1.基本计数模式:TIM6以指定的时钟频率递增计数器。当计数器达到预设的值时,会生成中断请求或触发其他事件。
2.预分频器:TIM6具有一个可配置的预分频器,可将输入时钟频率分频为较低的计数频率。这样可以调整定时器的计数速率。
3.自动重装载寄存器(ARR):TIM6具有一个自动重装载寄存器,当计数器达到该值时,会重新加载计数器的初始值,并触发中断或事件。
4.中断请求:TIM6可以配置为在计数器达到预设值时生成中断请求。通过中断处理程序,可以执行特定的操作,例如更新数据、生成PWM信号、触发其他模块等。
5.DMA请求:TIM6还可以配置为在计数器达到预设值时生成DMA请求,将数据传输到外部设备,实现高效的数据传输。
先上代码:tim6.c的
#include "bsp_tim6.h"
uint16_t TIM6Counter;
void TIM6_Init(void)
{
NVIC_InitTypeDef N;
TIM_TimeBaseInitTypeDef T;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_TIM6EN,ENABLE);
N.NVIC_IRQChannel = TIM6_IRQn;
N.NVIC_IRQChannelPreemptionPriority =1;
N.NVIC_IRQChannelSubPriority = 1;
N.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&N);
TIM_Cmd(TIM6,DISABLE);//不使能
T.TIM_Prescaler = 71;
T.TIM_Period = 999;
TIM_TimeBaseInit(TIM6,&T);
TIM_ClearFlag(TIM6,TIM_FLAG_Update);// 清除计数器中断标志位
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE); // 开启更新中断(只是开启功能,未工作)
}
需要用到中断,配置中断的代码就不解释了,前面写过的;配置TIM6的代码中,TIM的结构有5个,,由于TIM6是基本定时器,所以只用配置两个。
Prescaler预分频系数,这里写71,分频下来的结果就是(72/(71+1))得1MHz,例如1分频,结果就是36MHz;2分频结果就是72/3=24MHz。
Period自动重装载数值,和之前systick中的LOAD有点相似(设置目标值),我写的值是999,是因为计数是从0开始计数的;
为什么设置999呢;因为分频过后TIM6的时钟频率是1MHz,1s---10^6次;1ms---1000次;
void TIM6_Start(void)
{
TIM6Counter = 0; // 中断计数清0
TIM6->CNT=0; // 计数寄存器清0
TIM6->CR1 |= 0x01; // 开关;使能TIM6, 立即开始工作
}
void TIM6_IRQHandler(void)
{
TIM6->SR &= (uint16_t)~0x01; // 清0更新中断标志位
TIM6Counter ++ ; // 计数+1
}
Start就不解释了。
IRQHanler,在TIM6计数到了目标值就会触发中断,随后执行更新标志位,然后Counter值就是自加。
main()函数:
while(1)
{
if(TIM6Counter>=500)
{
LED_RED_TOGGLE;
LED_BLUE_TOGGLE;
TIM6Counter = 0;
}
counter值==500时,说明TIM6计数(1ms/次)完成了500次,对应时间就是0.5s。
!!!!!!!重点!!!!:
TIM6Counter在.h文件中声明extern(关键词,使可以被主函数调用)
在.c文件中还是要声明一次!!!