/**===========================================================================
@file board_timer.c
@brief 本文件是基本定时器TIM6的驱动
@author 青梅煮久
@version r0.1
@date 2021/01/15
----------------------------------------------------------------------------
Remark: (备注描述)
给串口2的接收提供定时,再一次中断内(1ms)接收数据的长度不变则认为接收
完成。
----------------------------------------------------------------------------
History
----------------------------------------------------------------------------
| | |
-------------|-----------|----------------|---------------------------------
2021/01/15 | r0.1 | 青梅煮久 | 创建
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
-------------|-----------|----------------|---------------------------------
| | |
============================================================================*/
/*********************************************************************
* INCLUDES
*/
#include "main.h"
#include "board_timer.h"
#include "board_uart.h"
#define BASIC_TIM_IRQHandler TIM6_IRQHandler
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/**
@brief NVIC初始化(使用TIM6基本定时器)
@param 无
@return 无
*/
void BASIC_TIM_NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
// 设置中断组为 2
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
@brief 定时器中断配置(使用TIM6基本定时器)
@param 无
@return 无
*/
void BASIC_TIM_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
/*
可以从上图看出基本定时器和通用定时器使用APB1总线,
高级定时器使用APB2总线。
*/
// 开启定时器时钟,即内部时钟 CK_INT=72M
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
/*
预分频将输入时钟频率按1~65536之间的值任意分频,分频值决定了计数频率。
计数值为计数的个数,当计数寄存器的值达到计数值时,产生溢出,发生中断。
如系统时钟为72MHz,预分频 TIM_Prescaler = 71,
计数值 TIM_Period = 1000,
则 TIM_Period * (TIM_Prescaler + 1) / 72000000 = 0.001,
即每1ms产生一次中断。
*/
// 自动重装载寄存器周的值(计数值)
TIM_TimeBaseStructure.TIM_Period = 1000;
// 累计 TIM_Period 个频率后产生一个更新或者中断
// 时钟预分频数为 71,
// 则驱动计数器的时钟 CK_CNT = CK_INT / (71+1)=1M
TIM_TimeBaseStructure.TIM_Prescaler = 71;
// 时钟分频因子 ,基本定时器没有,不用管
//TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数器计数模式,基本定时器只能向上计数,没有计数模式的设置
//TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 重复计数器的值,基本定时器没有,不用管
//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
/*
完成时基设置
*/
// 初始化定时器
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
/*
为了避免在设置时进入中断,这里需要清除中断标志位。
如果是向上计数模式(基本定时器采用向上计数),
则采用函数 TIM_ClearFlag(TIM6, TIM_FLAG_Update),
清除向上溢出中断标志。
*/
// 清除计数器中断标志位
TIM_ClearFlag(TIM6, TIM_FLAG_Update);
// 使能计数器
TIM_ITConfig(TIM6,TIM_IT_Update,ENABLE);
// 开启计数器
TIM_Cmd(TIM6, ENABLE);
// 暂时关闭定时器的时钟,等待使用
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, DISABLE);
}
/**
@brief 定时器中断(使用TIM6基本定时器)
@param 无
@return 无
*/
void BASIC_TIM_IRQHandler(void)
{
if(TIM_GetITStatus(TIM6, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM6, TIM_FLAG_Update);
if(g_currentLength == g_receiveLength)
{
// 接收完成
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, DISABLE);
printf("接收完成\n");
memcpy(g_manageBuffer, g_receiveBuffer, g_receiveLength);
g_rxFlag = 0;
g_receiveLength = 0;
memset(g_receiveBuffer, 0, sizeof(g_receiveBuffer));
g_rxFinish = 1;
}
else
{
g_currentLength = g_receiveLength;
}
}
}
//使用微库(平台式keil-MDK),点击“魔术棒” Target标签下有个Use MicroLIB—勾选
//重定向c库函数printf到USART2
/**
@brief 重定向c库函数printf到USART2
@param 无
@return 无
*/
int fputc(int ch, FILE *f)
{
USART_SendData(USART2,(u8)ch);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
return (ch);
}