STM32f4日记1之输出pwm波(用按键调整频率,占空比,可用示波器观察结果)
选用板子:正点原子stm32f407zgt6迷你板
如果你觉得这篇文章对你有用,请记得点赞同,这对我很重要。
使用到OLED显示当前输出的频率和占空比
实验仪器:示波器(黑色接地,红色接PF8)
使用公母头杜邦线,可以用公公头跟母母头拼出来
以下是pwm.c里的代码(定时器Tim13 IO口为PF8)
void TIM13_PWM_Init(u32 arr,u32 psc)//入口参数arr psc分频系数根据单片机型号定在main.c里使用
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_PinAFConfig(GPIOF,GPIO_PinSource8,GPIO_AF_TIM13);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOF8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //pp
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉默认高电平
GPIO_Init(GPIOF,&GPIO_InitStructure); //PF8
TIM_TimeBaseStructure.TIM_Prescaler=psc; //设置分频系数
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //定时器向上计数
TIM_TimeBaseStructure.TIM_Period=arr; //设置arr
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM13,&TIM_TimeBaseStructure);//
//TIM13 Channel1
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //pwm1模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //极性高
TIM_OC1Init(TIM13, &TIM_OCInitStructure); //初始化tim13 oc1
TIM_OC1PreloadConfig(TIM13, TIM_OCPreload_Enable); //
TIM_ARRPreloadConfig(TIM13,ENABLE);//使能arr
TIM_Cmd(TIM13, ENABLE); //使能tim13
}
以下是pwm.h里面的代码
#ifndef _TIMER_H
#define _TIMER_H
#include "sys.h"
void TIM13_PWM_Init(u32 arr,u32 psc);
#endif
以下是主函数里面的代码
代码功能:
初始占空比1%
初始频率1500
按下key0占空比每次加2
按下wkup频率每次加100当频率大于1500清为100
#include "sys.h"
#include "delay.h"
//#include "timer.h"
#include "led.h"
#include "string.h"
#include "pwm.h"
#include "key.h"
#include "usart.h"
#include "oled.h"
// #include "waishekey.h"
//extern u8 TIM5CH1_CAPTURE_STA;
//extern u8 count;
//extern u32 TIM5CH1_CAPTURE_UP1;
//extern u32 TIM5CH1_CAPTURE_UP2;
//extern u32 TIM5CH1_CAPTURE_DOWN; //这些是为输入捕获准备的请忽略
// PF8 用来接示波器
// PE5 用来接信号发生器,本实验不用
int main(void)
{
//u32 temp_f=0;
//float temp_d=0;
u8 key;
u8 key1;
int t=1500; //
int duty=1; //
char buffer1[100];
char buffer2[100];
char buffer3[100];
char buffer4[100];
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断
TIM13_PWM_Init(1500-1,84-1); //最重要的初始化 arr1000 设置TIM13初始arr1500 分频84
delay_init(168); //初始化delay
KEY_Init(); //初始化键盘
uart_init(115200); //´初始化串口本实验不用
OLED_Init(); //初始化oled
OLED_Clear();
//TIM5_CH1_Cap_Init(0xFFFFFFFF,42-1); //输入捕获,本实验不用
//sprintf(buffer1,"in duty:%5.1f%%",temp_d);
//sprintf(buffer2,"in freq:%.1uHZ",temp_f);
sprintf(buffer3,"out duty:%3d%%",duty);
sprintf(buffer4,"out freq:%dHZ",t);
while(1)
{
//sprintf(buffer1,"in duty:%5.1f%%",temp_d);
//sprintf(buffer2,"in freq:%.1uHZ", temp_f);
sprintf(buffer3,"out duty:%3d%%",duty);
sprintf(buffer4,"out freq:%dHZ",t);
//OLED_ShowString(0,0,buffer1,16);
//OLED_ShowString(0,16,buffer2,16);
OLED_ShowString(0,32,buffer3,16);
OLED_ShowString(0,48,buffer4,16);
OLED_Refresh();
key=KEY_Scan(0);
if(key)
{
switch(key)
{
case WKUP_PRES: //
t+=100;
if(t>1500)t=100;
TIM_SetCompare1(TIM13,1000000/t*(duty/100.0));
TIM_SetAutoreload(TIM13,1000000/t-1);
break;
case KEY0_PRES: //
duty+=2;
if(duty>100)duty=0;
TIM_SetCompare1(TIM13,1000000/t*(duty/100.0));
break;
}
}
}
}
下一篇文章会讲输入捕获实验,用到信号发生器(可将两者综合一个输出pwm一个捕获pwm,就不用仪器了)
敬请期待---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
作者:shawn
QQ:965798711 可咨询
2020.12.19 00:37