做网站视频一般上传到哪里,电商视觉设计是干什么的,榆林国贸网站建设,免费表格模板下载本文是通过PA0口输出PWM波#xff0c;然后通过PA6口捕获PWM波的频率和占空比#xff0c;最终在oled屏上显示我们自己设置的频率和占空比。由于和前面的pwm呼吸灯代码有重合部分所以本文中的代码由前者修改而来#xff0c;对于文件命名不要在意。
pwm_led.c文件
/*
编写步…本文是通过PA0口输出PWM波然后通过PA6口捕获PWM波的频率和占空比最终在oled屏上显示我们自己设置的频率和占空比。由于和前面的pwm呼吸灯代码有重合部分所以本文中的代码由前者修改而来对于文件命名不要在意。
pwm_led.c文件
/*
编写步骤
1.RCC开启时钟(TIM、GPIO)
2.配置时基单元
3.配置输出比较单元
4.配置GPIO
5.运行控制
*/
#include stm32f10x.h
#include stm32f10x_tim.h
#include pwm_led.h
//初始化函数
void PWM_Init(void)
{ /*开启时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //开启TIM2的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟 /*GPIO初始化*/ 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); //选择TIM2为内部时钟若不调用此函数TIM默认也为内部时钟 /*时基单元初始化*/ 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_TimeBaseInit配置TIM2的时基单元 /*输出比较初始化*/ TIM_OCInitTypeDef TIM_OCInitStructure; //定义结构体变量 TIM_OCStructInit(TIM_OCInitStructure); //结构体初始化若结构体没有完整赋值则最好执行此函数给结构体所有成员都赋一个默认值避免结构体初值不确定的问题 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; //输出比较模式选择PWM模式1 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_OC1Init配置TIM2的输出比较通道1 /*TIM使能*/ TIM_Cmd(TIM2, ENABLE); //使能TIM2定时器开始运行
}
/*改变占空比函数*/
void PWM_SetCompare1(uint16_t Compare)
{ TIM_SetCompare1(TIM2, Compare); //设置CCR1的值
}
/*通过设置psc的值来调节频率*/
void PWM_SetPrescaler(uint16_t Prescaler)
{ TIM_PrescalerConfig(TIM2,Prescaler,TIM_PSCReloadMode_Immediate); //写入一个值立刻生效
}
pwm_led.h文件
#ifndef _PWM_LED_H
#define _PWM_LED_H
#include stdint.h
void PWM_Init(void);
void PWM_SetCompare1(uint16_t Compare);
void PWM_SetPrescaler(uint16_t Prescaler);
#endif
ic.c文件
#include stm32f10x.h
#include stm32f10x_tim.h
#include ic.h
/*初始化函数步骤
1.开启GPIO和TIM的时钟
2.GPIO初始化并把GPIO配置为输入模式
3.配置时基单元让CNT计数器在内部时钟驱动下自增运行
4.配置输入捕获单元
5.选择从模式的触发源
6.选择触发后执行的操作
7.开启定时器
*/
void IC_Init(void)
{ /*开启时钟*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //开启TIM3的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟 /*GPIO初始化*/ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin GPIO_Pin_6; //GPIO_Pin_6; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); //将PA6引脚初始化为复用推挽输出受外设控制的引脚均需要配置为复用模式 /*配置时钟源*/ TIM_InternalClockConfig(TIM3); //选择TIM2为内部时钟若不调用此函数TIM默认也为内部时钟 /*时基单元初始化*/ 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_TimeBaseInit配置TIM2的时基单元 /*初始化输入捕获单元*/ TIM_ICInitTypeDef TIM_ICInitStruct; TIM_ICInitStruct.TIM_ChannelTIM_Channel_1; //通道 TIM_ICInitStruct.TIM_ICFilter0XF; //输入捕获的滤波器 TIM_ICInitStruct.TIM_ICPolarityTIM_ICPolarity_Rising; //上升沿触发 TIM_ICInitStruct.TIM_ICPrescalerTIM_ICPSC_DIV1; //不分频 TIM_ICInitStruct.TIM_ICSelectionTIM_ICSelection_DirectTI; //触发信号从直连通道输入 /* TIM_ICInit(TIM3,TIM_ICInitStruct); TIM_ICInitStruct.TIM_ChannelTIM_Channel_2; //通道 TIM_ICInitStruct.TIM_ICFilter0XF; //输入捕获的滤波器 TIM_ICInitStruct.TIM_ICPolarityTIM_ICPolarity_Falling; //下降沿触发 TIM_ICInitStruct.TIM_ICPrescalerTIM_ICPSC_DIV1; //不分频 TIM_ICInitStruct.TIM_ICSelectionTIM_ICSelection_IndirectTI; //触发信号交叉通道输入 */ //下面用这个函数更简单效果上面注销的代码一样 TIM_PWMIConfig(TIM3,TIM_ICInitStruct); /*配置从模式的触发源*/ TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1); /*配置从模式为Reset*/ TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset); //使能 TIM_Cmd(TIM3,ENABLE);
}
//获取频率的函数
uint32_t IC_GetFreq(void)
{ return 1000000/(TIM_GetCapture1(TIM3)1);
}
//获取占空比的函数
uint32_t IC_GetDuty(void)
{ return TIM_GetCapture2(TIM3)*100/(TIM_GetCapture1(TIM3)1);
}
ic.h文件
#ifndef _IC_H
#define _IC_H
#include stdint.h
void IC_Init(void);
uint32_t IC_GetFreq(void);
uint32_t IC_GetDuty(void);
#endif
main.c文件
#include stm32f10x.h
#include stm32f10x_tim.h
#include delay.h
#include OLED.h
#include pwm_led.h
#include ic.h
int main (void)
{ /*模块初始化*/ OLED_Init(); PWM_Init(); IC_Init(); OLED_ShowString(1,1,Freq:00000HZ); OLED_ShowString(2,1,Duty:00%); PWM_SetPrescaler(7200-1); PWM_SetCompare1(80); while(1) { OLED_ShowNum(1,6,IC_GetFreq(),5); OLED_ShowNum(2,6,IC_GetDuty(),2); }
}