4、蓝牙打印机-定时器驱动
蓝牙打印机实现打印内容,需要先通过定时器发送固定的节拍驱动步进电机转动,从而驱动打印头打印相应的内容。
因此想要实现打印,先要实现定时器功能。
本例采用通用定时器2完成发送节拍功能。
1、硬件
定时器总线
由上图知道TIM2是挂载在APB1总线上的。
RCC的TIM2为APB1ENR寄存器的第0位。
定时器的内部结构图:
定时器时钟源
定时器时钟源选择内部时钟源72M。
APB1进行了2分频,对于APB1其他外设来说是36M;但是对于定时器2-7要看下面,如果分频系数不为1,则还需要频率*2,因此对于定时器2-7来说,频率还是72M.
预分频器
计数器
2、软件
定时器初始化函数
{
时钟源选择
预分频器、计数器设置
计数器清零、清除中断标识位
使能定时器更新中断 - 模块中断开启
核心中断
使能定时器
}
定时器服务函数
{
}
定时器要使用中断,不然会影响其他程序运行。
定时器timer.c
#include "timer.h"
#include "led.h"
/********************************************************************
* 函数名: void TIM2_Config(u16 arr,u16 psc)
* 功能描述: 定时器TIM2初始化
* 输入参数:u16 arr,u16 psc
* 返回: 无
* 其他:
* arr -- 计数个数,多少us进入中断, 内部实现-1
* psc -- 多长时间为1us 内部实现-1
*********************************************************************/
void TIM2_Config(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// 使能TIM2和GPIOA时钟(如果使用了TIM2的CH1-4作为输入捕获/输出比较)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 如果使用了GPIO,则启用相应的GPIO时钟,例如:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置TIM2时间基单元
TIM_TimeBaseStructure.TIM_Period = arr - 1;
TIM_TimeBaseStructure.TIM_Prescaler = psc - 1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 清除更新中断标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 使能TIM2更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 配置NVIC中断优先级
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; // 抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; // 子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// 使能TIM2
TIM_Cmd(TIM2, ENABLE);
}
// TIM2中断服务函数
void TIM2_IRQHandler(void)
{
static u16 cnt = 0;
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
// 清除中断标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 自己的代码
cnt++;
// 1ms进入一次中断,1s切换灯的状态
if(cnt >= 1000)
{
cnt = 0;
LED1 = !LED1;
}
}
}
定时器timer.h
#ifndef _TIMER_H
#define _TIMER_H
#include "stm32f10x.h"
void TIM2_Config(u16 arr,u16 psc);
#endif
main.c测试代码
功能:1ms进入1次中断,1s切换一次灯的亮度。
#include "led.h"
#include "delay.h"
#include "key.h"
#include "timer.h"
int main()
{
u8 key;
init_delay(72); // 全速72M
init_led();
init_key();
TIM2_Config(1000,72); // 1ms进入中断
while(1)
{
}
}