输入比较简介:
输入比较通道(高级):
输入比较通道(通用):
输入比较模式:
模式 | 描述 |
冻结 | CNT=CCR时,REF保持为原状态 |
匹配时置有效电平 | CNT=CCR时,REF置有效电平 |
匹配时置无效电平 | CNT=CCR时,REF置无效电平 |
匹配时电平翻转 | CNT=CCR时,REF电平翻转 |
强制为无效电平 | CNT与CCR无效,REF强制为无效电平 |
强制为有效电平 | CNT与CCR无效,REF强制为有效电平 |
PWM模式1 | 向上计数:CNT<CCR时,REF置有效电平,CNT≥CCR时,REF置无效电平 向下计数:CNT>CCR时,REF置无效电平,CNT≤CCR时,REF置有效电平 |
PWM模式2 | 向上计数:CNT<CCR时,REF置无效电平,CNT≥CCR时,REF置有效电平 向下计数:CNT>CCR时,REF置有效电平,CNT≤CCR时,REF置无效电平 |
PWM简介:
频率 = 1 / TS 占空比 = TON / TS 分辨率 = 占空比变化步距
PWM基本结构:
参数计算:
捕获输入简介:
频率测量方法:
𝑓𝑥=𝑁 / 𝑇f_x=N / T
𝑓𝑥=𝑓𝑐 / 𝑁f_x=f_c / N
𝑓𝑚=𝑓𝑐 / 𝑇f_m=√(f_c / T)
输入捕获通道:
主从触发模式:
输入捕获基本模式:
PWMI基本结构:
编码器接口简介:
正交编码器:
编码器接口基本结构:
定时器代码:
#include "stm32f10x.h" // Device header
void Timer_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
//开启时钟 定时器连接APB1总线
TIM_InternalClockConfig(TIM2); //开启时钟
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定义结构体
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
//选择内部时钟分频 (1分频即为不分频)
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
//选择时钟计数方式 (up为向上计数)
TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1;
//周期,ARR自动重装值
TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1;
//预分频值 对72M进行7200分频,得到10khz频率
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //基本定时器初始化
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除标志位
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //开启更新中断到NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择NVIC优先级
NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC结构体
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //选择通道
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //NVIC使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM2, ENABLE); //时钟使能
}
//void TIM2_IRQHandler(void) //定时器2的中断函数
//{
// if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) //检查标志位
// {
//
// TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除标志位
// }
//}
STM32C8T6默认频率为72M,使用定时器时,可以通过改变周期和预分频值来决定定时器。注意设定值不能超过0~65535这个区间。
定时器外部时钟:
TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x0F);
//通过ETR引脚的外部时钟模式2配置(定时器,外部触发预分频器,外部触发极性 “NonInverted 不反向”,滤波器 0x00~0x0F)
PWM代码:
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM2); //初始化时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure);
TIM_OCInitTypeDef TIM_OCInitStructure; //定义输出比较结构体
TIM_OCStructInit(&TIM_OCInitStructure); //给结构体赋初始值
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择PWM1模式
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
//选择输出比较极性,高极性,极性不翻转,有效电平为高电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_Pulse = 0; //设置CCR寄存器的值
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void PWM_SetCompare1(uint16_t Compare) //更改CCR的值
{
TIM_SetCompare1(TIM2, Compare);
}
输入捕获代码:
#include "stm32f10x.h" // Device header
void IC_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 72 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure; //定义结构体
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择捕获通道
TIM_ICInitStructure.TIM_ICFilter = 0xF; //滤波器
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;//选择触发极性 上升沿
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //选择预分频 DIV1不分频
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //选择触发信号从哪个引脚输入 直连通道
TIM_ICInit(TIM3, &TIM_ICInitStructure); //初始化输入捕获
TIM_SelectInputTrigger(TIM3, TIM_TS_TI1FP1); //触发源选择
TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset); //配置从模式为Reset
TIM_Cmd(TIM3, ENABLE);
}
uint32_t IC_GetFreq(void) //返回最新周期的频率值
{
return 1000000 / (TIM_GetCapture1(TIM3) + 1);
}
如果需要两个通道同时捕获一个引脚,可以在初始化输入捕获之类换成:
TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);
这样第二个通道的参数就会被设置成与第一个通道完全相反的参数。
编码器(使用硬件,节省软件资源):
#include "stm32f10x.h" // Device header
void Encoder_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period = 65536 - 1; //ARR
TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1; //PSC
TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICStructInit(&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
TIM_ICInitStructure.TIM_ICFilter = 0xF;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_EncoderInterfaceConfig(TIM3, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
//(选择定时器,选择编码器模式,选择IC极性)
TIM_Cmd(TIM3, ENABLE);
}
int16_t Encoder_Get(void)
{
int16_t Temp;
Temp = TIM_GetCounter(TIM3);
TIM_SetCounter(TIM3, 0);
return Temp;
}