代码思路
1.打开RCC时钟,把要用的TIM外设和GPIO外设的时钟打开
2.配置时基单元,
3.配置输出比较单元包括(CCR的值,输出比较模式,极性选择模式,输出使能模式)使用结构体
4.配置GPIO , 把PWM对应的GPIO,初始化为复用推挽输出的设置
5.运行控制,启动计数器
PWM.c代码
#include "stm32f10x.h" // Device header
void PWM_Init(void)
{
//开启GPIO外设
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
//初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//开启TIM2时钟外设
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
//选择时基单元的时钟
TIM_InternalClockConfig(TIM2);
//配置时基单元
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//结构体类型名
TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;//指定时钟分频
TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器模式,向上计数
//关键计数器的值(决定定时时间)
/*CK_CNT_OV = CK_CNT / (ARR + 1) = CK_PSC / (PSC + 1) / (ARR + 1)
例如1s = 1HZ
所以CK_CNT_OV = 1HZ = CK_PSC(72MHZ)/ (PSC + 1) / (ARR + 1)
最后保证PSC和ARR取值在0~65535
*/
//ARR多,PSC少 即高频率记比较多的数,反之亦然;
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_OCPolarity = TIM_OCPolarity_High; //输出比较的极性
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //输出比较的模式
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //设置输出比较使能
/*
PWM频率: Freq = CK_PSC / (PSC + 1) / (ARR + 1)
PWM占空比: Duty = CCR / (ARR + 1)
PWM分辨率: Reso = 1 / (ARR + 1)
*/
TIM_OCInitStructure.TIM_Pulse = 0; //设置CCR,占空比
TIM_OC1Init(TIM2,&TIM_OCInitStructure);
//启动定时器
TIM_Cmd(TIM2,ENABLE);
}
//在运行过程中更改CCR
void PWM_SetCompare1(uint16_t Compare)
{
TIM_SetCompare1(TIM2,Compare); //单独更改CCR的值
}
主函数
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"
uint16_t i;
int main(void)
{
OLED_Init();
PWM_Init();
while (1)
{
for(i = 0;i<100;i++)
{
PWM_SetCompare1(i);
Delay_ms(10);
}
for(i = 0;i<100;i++)
{
PWM_SetCompare1(100-i);
Delay_ms(10);
}
}
}