幕墙装饰工程网站模板,做西式快餐店网站,如何对产品进行推广,网站公告建设方案目录 TIM
定时器定时中断
定时器外部时钟
PWM驱动LED呼吸灯#xff08;OC#xff09;
PWM控制舵机
PWMA驱动直流电机
输入捕获模式测频率#xff08;IC#xff09;
输入捕获模式测占空比
编码器接口测速(编码器接口) TIM 通用定时器 高级定时器 定时器定时中断
Ti…目录 TIM
定时器定时中断
定时器外部时钟
PWM驱动LED呼吸灯OC
PWM控制舵机
PWMA驱动直流电机
输入捕获模式测频率IC
输入捕获模式测占空比
编码器接口测速(编码器接口) TIM 通用定时器 高级定时器 定时器定时中断
Timer.c
#include stm32f10x.h // Device header//extern uint16_t Num; //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)/*** brief 定时器中断初始化* param 无* retval 无*/
void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//TIM2的时基单元就由内部时钟来驱动定时器上电默认使用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1;//设置时钟分频选择一分频TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up;//设置计数器模式选择向上计数TIM_TimeBaseInitStructure.TIM_Period 10000 - 1;//设置周期即ARR重装值0-65535//72000000/10000/7200 1s即1HzTIM_TimeBaseInitStructure.TIM_Prescaler 7200 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元//在TIM_TimeBaseInit函数中由缓冲寄存器只有在更新事件时//才会真正起作用为了让值立刻起作用手动生成了一个更新事件,//此时更新事件以及更新中断是同时发生的更新中断会将置位标志位故会进入中断进行中断中的操作TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号//更新中断到NVIC//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组//选择分组2NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel TIM2_IRQn;//配置中断通道//TIM2在NVIC的通道NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;//使能通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;//响应优先级NVIC_Init(NVIC_InitStructure);//初始化NVICTIM_Cmd(TIM2,ENABLE);//启动定时器
}/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Num;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位}
}
*/
main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include Timer.huint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,Num:);while(1){OLED_ShowNum(1,5,Num,5);}}/*** brief TIM2的中断函数* param 无* retval 无*/
void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Num;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位}
}定时器外部时钟
Timer.c
#include stm32f10x.h // Device header//extern uint16_t Num; //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)/*** brief 定时器外部时钟中断初始化* param 无* retval 无*/
void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启TIM2时钟//TIM2是APB1总线的外设RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//这里使用上拉输入//手册推荐浮空输入当外部输入信号功率很小内部上拉电阻可能会影响输入信号防止影响外部输入的电平可以使用GPIO_InitStructure.GPIO_Pin GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x05);//通过ETR引脚的外部时钟模式2配置(选择配置时钟预分频器选择上升/下降有效滤波器工作模式)//在此之前还需要配置GPIOTIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1;//设置时钟分频选择一分频TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up;//设置计数器模式选择向上计数TIM_TimeBaseInitStructure.TIM_Period 10 - 1;//设置周期即ARR重装值0-65535//72000000/10000/7200 1s即1HzTIM_TimeBaseInitStructure.TIM_Prescaler 1 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元//在TIM_TimeBaseInit函数中由缓冲寄存器只有在更新事件时//才会真正起作用为了让值立刻起作用手动生成了一个更新事件,//此时更新事件以及更新中断是同时发生的更新中断会将置位标志位故会进入中断进行中断中的操作TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号//更新中断到NVIC//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组//选择分组2NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel TIM2_IRQn;//配置中断通道//TIM2在NVIC的通道NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;//使能通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;//响应优先级NVIC_Init(NVIC_InitStructure);//初始化NVICTIM_Cmd(TIM2,ENABLE);//启动定时器
}uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Num;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位}
}
*/ main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include Timer.huint16_t Num;int main(void)
{OLED_Init();Timer_Init();OLED_ShowString(1,1,Num:);OLED_ShowString(2,1,CNT:);while(1){OLED_ShowNum(1,5,Num,5);OLED_ShowNum(2,5,Timer_GetCounter(),5);}}/*** brief TIM2的中断函数* param 无* retval 无*/
void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Num;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位}
}PWM驱动LED呼吸灯OC
PWM.c
#include stm32f10x.h // Device header/*** brief 初始化PWM波形* param 无* retval 无*/
void PWM_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_0;//GPIO_InitStructure.GPIO_Pin GPIO_Pin_15;//重映射到PA^15引脚GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIO//端口重映射//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//设置重映射//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG复用保留SWD复用RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//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重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 720 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数TIM_OCStructInit(TIM_OCInitstructure);//为结构体赋初始值TIM_OCInitstructure.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitstructure.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OCInitstructure.TIM_OutputState TIM_OutputState_Enable;//设置输出使能TIM_OCInitstructure.TIM_Pulse 0;//设置CCR//PWM频率 72MHz/PSC1/ARR1//PWM占空比 CCR/ARR1//PWM分辨率 1/ARR1//1Hz 1sTIM_OC1Init(TIM2,TIM_OCInitstructure);//初始化输出比较单元PA^0对应TIM_OC1InitTIM_Cmd(TIM2,ENABLE);//启动定时器
}/*** brief 设置通道1中CCR的值* param 被设定的CCR的值 * retval 无*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2,Compare);}main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include PWM.huint8_t KeyNum;int main(void)
{OLED_Init();PWM_Init();uint8_t tmp;while(1){for(tmp 0;tmp 100;tmp){PWM_SetCompare1(tmp);Delay_ms(10);}for(tmp 0;tmp 100;tmp){PWM_SetCompare1(100 - tmp);Delay_ms(10);}}}
PWM控制舵机
PWM.c
#include stm32f10x.h // Device header/*** brief 初始化PWM波形* param 无* retval 无*/
void PWM_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIORCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//TIM2的时基单元就由内部时钟来驱动定时器上电默认使用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//初始化时基单元TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1;//设置时钟分频选择一分频TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up;//设置计数器模式选择向上计数TIM_TimeBaseInitStructure.TIM_Period 20000 - 1;//设置周期即ARR重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 72 - 1;//这里可以得出频率为50Hz//周期为0.02s已知需要高电平0.5ms~2.5ms周期X占空比0.5ms占空比为0.025//那么CCR 500 ~ 2500//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数TIM_OCStructInit(TIM_OCInitstructure);//为结构体赋初始值TIM_OCInitstructure.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitstructure.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OCInitstructure.TIM_OutputState TIM_OutputState_Enable;//设置输出使能TIM_OCInitstructure.TIM_Pulse 0;//设置CCR//PWM频率 72MHz/PSC1/ARR1//PWM占空比 CCR/ARR1//PWM分辨率 1/ARR1//1Hz 1sTIM_OC2Init(TIM2,TIM_OCInitstructure);//初始化输出比较单元PA^1对应TIM_OC2Init见引脚定义表TIM_Cmd(TIM2,ENABLE);//启动定时器
}/*** brief 设置通道2中CCR的值* param 被设定的CCR的值 * retval 无*/
void PWM_SetCompare2(uint16_t Compare)
{TIM_SetCompare2(TIM2,Compare);}Servo.c
#include stm32f10x.h // Device header
#include PWM.h/*** brief 初始化PWM* param 无* retval 无*/
void Servo_Init(void)
{PWM_Init();
}/*** brief 设置转动角度* param Angle 转动角度* retval 无*/
void Servo_SetAngle(float Angle)
{PWM_SetCompare2(Angle / 180 * 2000 500);//0 500;180 2500
}main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include Servo.h
#include Key.huint8_t KeyNum;
float Angle;int main(void)
{OLED_Init();Servo_Init();Key_Init();OLED_ShowString(1,1,Angle:);while(1){KeyNum Key_GetNum();//此前在Key.c中已初始化PB^1故能读出数据if(KeyNum 1){Angle 30;if(Angle 180){Angle 0;}}Servo_SetAngle(Angle);OLED_ShowNum(2,1,Angle,3);}}
PWMA驱动直流电机
PWM.c
#include stm32f10x.h // Device header/*** brief 初始化PWM波形* param 无* retval 无*/
void PWM_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_2;//接在PA^3上GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIORCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//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重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 36 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数TIM_OCStructInit(TIM_OCInitstructure);//为结构体赋初始值TIM_OCInitstructure.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitstructure.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OCInitstructure.TIM_OutputState TIM_OutputState_Enable;//设置输出使能TIM_OCInitstructure.TIM_Pulse 0;//设置CCR//PWM频率 72MHz/PSC1/ARR1//PWM占空比 CCR/ARR1//PWM分辨率 1/ARR1//1Hz 1sTIM_OC3Init(TIM2,TIM_OCInitstructure);//初始化输出比较单元PA^2对应TIM_3C1InitTIM_Cmd(TIM2,ENABLE);//启动定时器
}/*** brief 设置通道1中CCR的值* param 被设定的CCR的值 * retval 无*/
void PWM_SetCompare3(uint16_t Compare)
{TIM_SetCompare3(TIM2,Compare);}Motor.c
#include stm32f10x.h // Device header
#include PWM.h/*** brief 初始化电机方向控制脚以及PMW* param 无* retval 无*/
void Motor_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin GPIO_Pin_4 | GPIO_Pin_5;GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步初始化电机方向控制脚PWM_Init();
}/**
* brief 设置电机运行速度为负时为反转* param Speed 电机运行速度* retval 无*/
void Motor_SetSpeed(int8_t Speed)
{if(Speed 0)//正转 {GPIO_SetBits(GPIOA,GPIO_Pin_4);GPIO_ResetBits(GPIOA,GPIO_Pin_5);PWM_SetCompare3(Speed);}else{//反转GPIO_SetBits(GPIOA,GPIO_Pin_5);GPIO_ResetBits(GPIOA,GPIO_Pin_4);PWM_SetCompare3(-Speed);}
}
main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include Motor.h
#include Key.huint8_t KeyNum;
int8_t Speed;int main(void)
{OLED_Init();Motor_Init();Key_Init();OLED_ShowString(1,1,Speed:);while(1){KeyNum Key_GetNum();if(KeyNum 1){Speed 20;if(Speed 60){Speed -60;}}Motor_SetSpeed(Speed);OLED_ShowSignedNum(2,1,Speed,3);}}
注意这里尽量不要满速跑一下香味就出来了 输入捕获模式测频率IC
PWM.c
#include stm32f10x.h // Device header/*** brief 初始化PWM波形* param 无* retval 无*/
void PWM_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP;//复用推挽输出GPIO_InitStructure.GPIO_Pin GPIO_Pin_0;//GPIO_InitStructure.GPIO_Pin GPIO_Pin_15;//重映射到PA^15引脚GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIO//端口重映射//RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启AFIO时钟//GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2,ENABLE);//设置重映射//GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//解除JTAG复用保留SWD复用RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//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重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 720 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元TIM_OCInitTypeDef TIM_OCInitstructure;//含有高级定时器参数TIM_OCStructInit(TIM_OCInitstructure);//为结构体赋初始值TIM_OCInitstructure.TIM_OCMode TIM_OCMode_PWM1;//输出比较模式TIM_OCInitstructure.TIM_OCPolarity TIM_OCPolarity_High;//输出比较极性TIM_OCInitstructure.TIM_OutputState TIM_OutputState_Enable;//设置输出使能TIM_OCInitstructure.TIM_Pulse 0;//设置CCR//PWM频率 72MHz/PSC1/ARR1//PWM占空比 CCR/ARR1//PWM分辨率 1/ARR1//1Hz 1sTIM_OC1Init(TIM2,TIM_OCInitstructure);//初始化输出比较单元PA^0对应TIM_OC1InitTIM_Cmd(TIM2,ENABLE);//启动定时器
}/*** brief 设置通道1中CCR的值占空比* param 被设定的CCR的值 * retval 无*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2,Compare);
}/*** brief 写入PSC数值修改频率* param 被设定的PSC数值* retval 无*/
void PWM_SetPrescaler(uint16_t Prescaler)
{TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate);//所使用定时器设定数值立刻重装载模式
}IC.c
#include stm32f10x.h // Device header/*** brief 输入捕获初始化* param 无* retval 无*/
void IC_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_6;//使用TIM3通道1查表为PA^6GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIORCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启RCC时钟//TIM3是APB1总线的外设(因为TIM2要放出被测的PWM)TIM_InternalClockConfig(TIM3);//选择时基单元时钟//TIM2的时基单元就由内部时钟来驱动定时器上电默认使用内部时钟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重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 72 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM3,TIM_TimeBaseInitStructure);//配置时基单元TIM_ICInitTypeDef IC_InitStructure;IC_InitStructure.TIM_Channel TIM_Channel_1 ;//配置通道1IC_InitStructure.TIM_ICFilter 0xF ;//配置输入捕获滤波器IC_InitStructure.TIM_ICPolarity TIM_ICPolarity_Rising ;//配置极性上升沿触发IC_InitStructure.TIM_ICPrescaler TIM_ICPSC_DIV1 ;//配置触发信号分频器不分频IC_InitStructure.TIM_ICSelection TIM_ICSelection_DirectTI ;//配置数据选择器直连TIM_ICInit(TIM3,IC_InitStructure);TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRGITIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式TIM_Cmd(TIM3,ENABLE);//启动定时器
}uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) 1); //1M是当前TIM3频率//待测PWM的频率为1000Hz
}main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include PWM.h
#include IC.hint main(void)
{OLED_Init();PWM_Init();IC_Init();OLED_ShowString(1,1,Freq:00000Hz);PWM_SetPrescaler(720 - 1);//设置PSC Freq 72MHz / (PSC 1) / (ARR 1)PWM_SetCompare1(50);//设置CCR Duty(占空比) CCR / (ARR 1)while(1){OLED_ShowNum(1,6,IC_GetFreq(),5);}} 输入捕获模式测占空比
IC.c
#include stm32f10x.h // Device header/*** brief 输入捕获初始化* param 无* retval 无*/
void IC_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//第一步使用RCC开启GPIO时钟GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU;//上拉输入GPIO_InitStructure.GPIO_Pin GPIO_Pin_6;//使用TIM3通道1查表为PA^6GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz;GPIO_Init(GPIOA,GPIO_InitStructure);//第二步使用GPIO_Init()初始化GPIORCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//开启RCC时钟//TIM3是APB1总线的外设(因为TIM2要放出被测的PWM)TIM_InternalClockConfig(TIM3);//选择时基单元时钟//TIM2的时基单元就由内部时钟来驱动定时器上电默认使用内部时钟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重装值0-65535TIM_TimeBaseInitStructure.TIM_Prescaler 72 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM3,TIM_TimeBaseInitStructure);//配置时基单元TIM_ICInitTypeDef IC_InitStructure;IC_InitStructure.TIM_Channel TIM_Channel_1 ;//配置通道1IC_InitStructure.TIM_ICFilter 0xF ;//配置输入捕获滤波器IC_InitStructure.TIM_ICPolarity TIM_ICPolarity_Rising ;//配置极性上升沿触发IC_InitStructure.TIM_ICPrescaler TIM_ICPSC_DIV1 ;//配置触发信号分频器不分频IC_InitStructure.TIM_ICSelection TIM_ICSelection_DirectTI ;//配置数据选择器直连//TIM_ICInit(TIM3,IC_InitStructure);TIM_PWMIConfig(TIM3,IC_InitStructure);//会自动把剩下的一个通道(1或2)初始化成相反的配置TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);//配置TRGITIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);//配置从模式TIM_Cmd(TIM3,ENABLE);//启动定时器
}/*** brief 获取频率* param 无* retval 返回被测端口频率*/
uint32_t IC_GetFreq(void)
{return 1000000 / (TIM_GetCapture1(TIM3) 1); //1M是当前TIM3频率//待测PWM的频率为1000Hz
}/*** brief 获取占空比* param 无* retval 返回被测端口占空比*/
uint32_t IC_GetDuty(void)
{return (TIM_GetCapture2(TIM3)1) * 100 / (TIM_GetCapture1(TIM3) 1);//通道二存储有效电平计次通道一存储整个周期计次
}main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include PWM.h
#include IC.hint main(void)
{OLED_Init();PWM_Init();IC_Init();OLED_ShowString(1,1,Freq:00000Hz);OLED_ShowString(2,1,Duty:000%);PWM_SetPrescaler(7200 - 1);//设置PSC Freq 72MHz / (PSC 1) / (ARR 1)PWM_SetCompare1(80);//设置CCR Duty(占空比) CCR / (ARR 1)while(1){OLED_ShowNum(1,6,IC_GetFreq(),5);OLED_ShowNum(2,6,IC_GetDuty(),3);}} 编码器接口测速(编码器接口)
Ecoder.c
#include stm32f10x.h // Device header/*** brief 对GPIO时基单元TIM捕获配置以及定时器编码器接口进行初始化* param 无* retval 无*/
void Encoder_Init(void)
{//打开各自RCC时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//GPIO配置GPIO_InitTypeDef GPIO_InitStructrue;GPIO_InitStructrue.GPIO_Mode GPIO_Mode_IPU ;//设置上拉输入//如果外部空闲模块默认输出高电平就选择上拉输入默认输入高电平//如果外部空闲模块默认输出低电平就选择下拉输入默认输入低电平//和外部模块保持状态一致防止默认电平打架。//如果不确定外部模块输出的默认状态或外部信号输出功率非常小这时候选择浮空输入//浮空输入没有上拉电阻和下拉电阻去影响外部信号但缺点是当引脚悬空时//没有默认的电平了输入就会收噪声干扰来回不断的跳变GPIO_InitStructrue.GPIO_Pin GPIO_Pin_6 | GPIO_Pin_7 ;GPIO_InitStructrue.GPIO_Speed GPIO_Speed_50MHz ;GPIO_Init(GPIOA,GPIO_InitStructrue);//时基单元配置TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1;TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up;TIM_TimeBaseInitStructure.TIM_Period 65536 - 1;//ARRTIM_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_ICInitStructure.TIM_ICPolarity TIM_ICPolarity_Rising;//这里的极性选择不代表上升沿有效这里代表的是高低电平极性不翻转也就是TI1与TI2是否反向//上升沿不反向下降沿反向TIM_ICInit(TIM3,TIM_ICInitStructure);TIM_ICInitStructure.TIM_Channel TIM_Channel_2 ;TIM_ICInitStructure.TIM_ICFilter 0xf;//TIM_ICInitStructure.TIM_ICPolarity TIM_ICPolarity_Rising;//这里的极性选择不代表上升沿有效这里代表的是高低电平极性不翻转也就是TI1与TI2是否反向//上升沿不反向下降沿反向(后面编码器接口会进行重复配置)TIM_ICInit(TIM3,TIM_ICInitStructure);//配置编码器接口TIM_EncoderInterfaceConfig(TIM3,TIM_EncoderMode_TI12,TIM_ICPolarity_Rising,TIM_ICPolarity_Rising);TIM_Cmd(TIM3,ENABLE);//启动定时器
}/*** brief 返回TIM3在1s的时间下CNT的值* param 无* retval 无*/
int16_t Encoder_Get(void)
{int16_t tmp;tmp TIM_GetCounter(TIM3);TIM_SetCounter(TIM3,0);//读取cnt并将其置零用于测频法测频率以及测速return tmp;
}Timer.c
#include stm32f10x.h // Device header//extern uint16_t Num; //使用extern声明外部变量(如果要在文件中使用其他文件中的变量)/*** brief 定时器中断初始化* param 无* retval 无*/
void Timer_Init(void)
{RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//开启RCC时钟//TIM2是APB1总线的外设TIM_InternalClockConfig(TIM2);//选择时基单元时钟//TIM2的时基单元就由内部时钟来驱动定时器上电默认使用内部时钟TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision TIM_CKD_DIV1;//设置时钟分频选择一分频TIM_TimeBaseInitStructure.TIM_CounterMode TIM_CounterMode_Up;//设置计数器模式选择向上计数TIM_TimeBaseInitStructure.TIM_Period 10000 - 1;//设置周期即ARR重装值0-65535//72000000/10000/7200 1s即1HzTIM_TimeBaseInitStructure.TIM_Prescaler 7200 - 1;//设置预分频器值psc0-65535TIM_TimeBaseInitStructure.TIM_RepetitionCounter 0;//配置重复计数器值高级定时器会用到TIM_TimeBaseInit(TIM2,TIM_TimeBaseInitStructure);//配置时基单元//在TIM_TimeBaseInit函数中由缓冲寄存器只有在更新事件时//才会真正起作用为了让值立刻起作用手动生成了一个更新事件,//此时更新事件以及更新中断是同时发生的更新中断会将置位标志位//故会进入中断进行中断中的操作TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除中断标志位TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断输出信号//更新中断到NVIC//配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组//选择分组2NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel TIM2_IRQn;//配置中断通道//TIM2在NVIC的通道NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE;//使能通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2;//抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority 1;//响应优先级NVIC_Init(NVIC_InitStructure);//初始化NVICTIM_Cmd(TIM2,ENABLE);//启动定时器
}/*TIM2中断函数模板
void TIM2_IRQHandler(void)
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Num;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断待处理 位}
}
*/
main.c
#include stm32f10x.h // Device header
#include Delay.h
#include OLED.h
#include Timer.h
#include Encoder.hint16_t Speed;int main(void)
{OLED_Init();Timer_Init();Encoder_Init();OLED_ShowString(1,1,Speed:);while(1){OLED_ShowSignedNum(1,7,Speed,5);//Delay_ms(1000);//防止阻塞将其移动至定时器中断进行配置}}/*** brief TIM2的中断函数1s* param 无* retval 无*/
void TIM2_IRQHandler()
{if(TIM_GetITStatus(TIM2,TIM_IT_Update) SET)//检查中断标志位{Speed Encoder_Get();TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位}
}