1.実験の目的:
PWMプログラミング;
テスト波形;ロジックアナライザー;
2。実験装置;
コアボードとルーチン;
ロジックアナライザー
dapダウンローダー;
3。原理と注意事項。
高レベルの時間が必要なPWM波形。
タイマー9とタイマー1の周波数は168Mhzであることに注意してください。時計のラインを見てください。時間厳守原子のチュートリアルをご覧ください。
構成は時間厳守原子の構成とは異なる場合があります。いくつかの係数の設定をご覧ください。
実際、ロジックアナライザーを使用すると、周波数がアトミックの例とは多少異なることがわかります。問題を明確にするだけです。
時間厳守の例はタイマー14です。
結論、
**
タイマー9とタイマー1の頻度の計算:
**
タイマー9とタイマー1の周波数は168Mhzです。これら2つのタイマーから生成されたPWMのPWM周波数は周波数で除算されます。たとえば、168で除算すると、168M / 168 = 1Mhzになります。。次に、これに基づいて1回除算して、実際のPWM周波数を取得します。私の1000倍に分割すると、1Mhz / 1000 = 1000hzになります。したがって、実際にPWMの周波数を決定し、前の分配係数を168-1に固定し、後者の分配係数を変数として使用する場合は、この変数を変更して、必要なPWMの周波数を取得できます。
タイマー1とタイマー9のデューティサイクルの計算。
この関数の2番目のパラメーターを変更すると、デューティサイクルが変わる可能性があります。たとえば、周波数が1000hzの場合、100回の計算でデューティサイクルは10%、300回は30%、最大計算は1000回です。
最初のチャネルのPWMは、compare1からcompare2 ..に設定されます。
初期レベルが高く、次に0からarrが高く、arrから最大値までは0です。
構造体メンバーTIM_OCInitTypeDef.TIM_OCPolarityとともに使用します。
ここで、TIM_OCInitTypeDef.TIM_OCPolarity = TIM_OCPolarity_Highとすると、初期波形はハイになります。
TIM_OCInitTypeDef.TIM_OCMode = TIM_OCMode_PWM1の場合:
タイマ値がコンパレータの設定値よりも小さい場合、TIMX出力端子はこの時点で実効高電位を出力します。
タイマ値がコンパレータ設定値以上の場合、TIMX出力端子はこのとき低電位を出力します。
TIM_OCInitTypeDef.TIM_OCMode = TIM_OCMode_PWM2の場合:
タイマ値がコンパレータの設定値よりも小さい場合、TIMX出力端子はこの時点で実効低電位を出力します。
タイマ値がコンパレータの設定値以上の場合、TIMX出力端子はこのとき高電位を出力します。
コード:
pwm.h
#ifndef __PWM_H
#define __PWM_H
#include "stm32f4xx.h"
void TIM9_PWM_Init(u32 arr,u32 psc);//E5--ch2
void TIM1_PWM_Init(u32 arr,u32 psc);//E9 11 13 14
#endif //__DELAY_H
pwm.c
#include "pwm.h"
#include "led.h"
//TIM9 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
//注意,定时器9的频率,经过测量和分析,是168M,所以main函数中500-1,84-1,得到频率应该是
//168/84=2M ,再除以500,等于4Khz,注意,要用
void TIM9_PWM_Init(u32 arr,u32 psc)
{
//此部分需手动修改IO口设置
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE); //TIM9时钟使能 168M=84M*2
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能PORTe时钟 GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_TIM9); //e5复用为定时器14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIOE5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化PE5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);//初始化定时器14
//初始化TIM9 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //*********************************输出极性:初始高电平,小于arr,则是高电平
TIM_OC1Init(TIM9, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1
TIM_OC1PreloadConfig(TIM9, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器
TIM_ARRPreloadConfig(TIM9,ENABLE);//ARPE使能
TIM_Cmd(TIM9, ENABLE); //使能TIM9
TIM_CtrlPWMOutputs(TIM9,ENABLE);
}
//TIM9 PWM部分初始化
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数--------------PE9 11 13 14
void TIM1_PWM_Init(u32 arr,u32 psc)//E9 11 13 14
{
//此部分需手动修改IO口设置
int ccr1=500,ccr2=500,ccr3=500,ccr4=500;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//注意,定时器1用APB2时钟线
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE); //=====TIM10时钟使能
//在那个引脚产生PWM?设定对应PWM口的时钟打开,这里用B8
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //======使能PORTB时钟
//引脚复用A---6===GPIO_AF_TIM13
GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOE,GPIO_PinSource13,GPIO_AF_TIM1); //========GPIOE5复用为定时器14
GPIO_PinAFConfig(GPIOE,GPIO_PinSource14,GPIO_AF_TIM1); //========GPIOE5复用为定时器14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11|GPIO_Pin_13|GPIO_Pin_14; //=======GPIOE5 E6
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //==============初始化PF9
//Timer clock = sysclock /(TIM_Prescaler+1) = 168M
TIM_TimeBaseStructure.TIM_Prescaler=psc; //==============定时器分频0000
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
//Period = (TIM counter clock / TIM output clock) - 1 = 20K
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);//=======初始化定时器1
//初始化TIM9 Channel1 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;//输出同相,TIM_OCNPolarity_High时输出反相
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//初始高电平
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
// TIM_OC1Init(TIM1, &TIM_OCInitStructure); //=========根据T指定的参数初始化外设TIM1 4OC1
TIM_OCInitStructure.TIM_Pulse = ccr1; //设置待装入捕获比较寄存器的脉冲值
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //=============根据指定的参数初始化外设 TIMx
//TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //==========CH1 预装载使能
// TIM_ARRPreloadConfig(TIM13,ENABLE);//==============ARPE使能
TIM_OCInitStructure.TIM_Pulse = ccr2; //设置待装入捕获比较寄存器的脉冲值
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //=============根据指定的参数初始化外设 TIMx
TIM_OCInitStructure.TIM_Pulse = ccr3; //设置待装入捕获比较寄存器的脉冲值
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //=============根据指定的参数初始化外设 TIMx
TIM_OCInitStructure.TIM_Pulse = ccr4; //设置待装入捕获比较寄存器的脉冲值
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //=============根据指定的参数初始化外设 TIMx
TIM_Cmd(TIM1, ENABLE); //==============使能TIM1
TIM_CtrlPWMOutputs(TIM1,ENABLE);
}
main.c
#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"
#include "key.h"
#include "usart.h"
#include "beep.h"
#include "exti.h"
#include "timer.h"
#include "pwm.h"
//第一个,修改头文件led.h,配置硬件的IO对应
//修改led.c文件
int main(void)
{
u8 key_flag = 0; //按键标志
u8 i=0;
int led0val=0;
int led1val=0;
Delay_Init(); //延时函数初始化
LED_Init(); //LED初始化
BEEP_Init(); //LED初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
EXTIX_Init();
TIM3_Int_Init(5000-1,8400-1);
TIM4_Int_Init(5000-1,8400-1);
TIM9_PWM_Init(1000-1,168-1);//E5--ch1---------PWM波形的频率是168M/168再除以1000,1M/1000=1000hz
TIM1_PWM_Init(1000-1,168-1);//E9--
TIM_Cmd(TIM9, ENABLE); //使能TIM9的PWM1/
TIM_Cmd(TIM1, ENABLE); //使能TIM9的PWM
while (1)
{
// for(i=0;i<10;i++)
// {
// LED1_ON;LED2_ON;LED3_ON;LED4_ON;BEEP_ON;
// Delay_ms(1000);
// LED1_OFF;LED2_OFF;LED3_ON;LED4_ON;BEEP_OFF;
// Delay_ms(1000);
// }
TIM_SetCompare1(TIM9,100);
Delay_ms(10);
TIM_SetCompare1(TIM9,300);
Delay_ms(10);
TIM_SetCompare1(TIM9,600);
Delay_ms(10);
TIM_SetCompare1(TIM9,850);
Delay_ms(10);
TIM_SetCompare1(TIM1,100);
Delay_ms(10);
TIM_SetCompare1(TIM1,300);
Delay_ms(10);
TIM_SetCompare1(TIM1,600);
Delay_ms(10);
TIM_SetCompare1(TIM1,850);
Delay_ms(10);
// TIM_SetCompare1(TIM9,led0val); //修改比较值,修改占空比 pe5---T9CH1
// led0val++;
// if(led0val==400)//最大是499
// led0val=0;
//
// TIM_SetCompare1(TIM1,led1val); //修改比较值,修改占空比
// TIM_SetCompare2(TIM1,led1val); //修改比较值,修改占空比
// TIM_SetCompare3(TIM1,led1val); //修改比较值,修改占空比
// TIM_SetCompare4(TIM1,led1val); //修改比较值,修改占空比
// led1val++;
// if(led1val==400)//最大是499
// led1val=0;
// Delay_ms(10);
}
}