STM32 PWM

OC (Output Compare) 出力比較

出力比較は、CNT レジスタと CCR レジスタの値の関係を比較することにより、出力レベルを 1 に設定、0 に設定、または反転することができ、特定の周波数とデューティ サイクルの PWM 波形を出力するために使用されます。(CCR は、CNT が CCR より大きい、以下、または等しい場合に与える値であり、反転します)

各アドバンスト タイマーと一般タイマーには 4 つの出力比較チャネルがあります。

アドバンストタイマーの最初の 3 チャネルには、デッドゾーン生成と相補出力の機能が追加されています。

PWM の概要

PWM(パルス幅変調)パルス幅変調

慣性のあるシステムでは、一連のパルスの幅を変調することで必要なアナログパラメータを等価的に取得でき、モーター速度制御などの分野でよく使用されます。

PWMパラメータ:

周波数 = 1 / TS デューティ サイクル = TON / TS 分解能 = デューティ サイクル変更ステップ

分解能はデューティ比の変化値に応じた変数名で、例えば1%、2、3%…と1%刻みでジャンプし、分解能は1%となります。

モデル

説明する

氷結

CNT=CCRの場合、REF は元の状態のままになります。

マッチング時の有効レベルを設定する

CNT=CCRの場合、REF は有効なレベルに設定されます

マッチング時に無効なレベルを設定する

CNT=CCRの場合、REF は無効なレベルに設定されます

マッチ時のレベル反転

CNT=CCRの場合、REF レベルが反転します

強制的に無効なレベルに設定されました

CNTと CCR は無効であり、REF は強制的に無効なレベルに設定されます

アクティブレベルに強制される

CNTと CCR は無効であり、REF は強制的に有効なレベルに設定されます

PWMモード1

カウントアップ:CNT<CCRの場合、REFは有効レベルに設定され、CNT≧CCRの場合、REFは非アクティブレベルに設定されます。

カウントダウン: CNT>CCR の場合、REF は無効レベルに設定され、CNT ≦ CCR の場合、REF は有効レベルに設定されます。

PWMモード2

カウントアップ:CNT<CCRの場合、REFは無効レベルに設定され、CNT≧CCRの場合、REFは有効レベルに設定されます。

カウントダウン: CNT>CCR の場合、REF は有効レベルに設定され、CNT ≦ CCR の場合、REF は無効レベルに設定されます。

 PSC はプリスケーラのクロック、CCR は設定された比較値、ARR はカウンタの最大オーバーフロー値です。

 ステアリングギアの紹介

上記の値は要件を満たすために PWM 式に代入され、20K は 20ms に相当します。

次のような対応関係があります。

20K=20ミリ秒         

         X=必要な高レベル幅 X を求めます。X は CCR の値です

指定した角度を出力する式も導出できます: Angle/180*2000+500

PWM.c

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//选择TIM2定时器
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//需要复用推挽输出,因为此程序是CH1输出,是片上外设
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;//根据GPIO引脚定义,此程序用的是OC2通道,对应的是CH2,由引脚图可知选PA1
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	TIM_InternalClockConfig(TIM2);//由内部时钟驱动
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;     //预分频系数1
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitStructure.TIM_Prescaler=72-1;//             //PSC
    TIM_TimeBaseInitStructure.TIM_Period=20000-1;//                 //ARR
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器的中的重复计数器的
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//时机单元初始化函数
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断
	
	TIM_Cmd(TIM2,ENABLE);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);//避免给一些没用到的参数赋予初始值而导致混乱
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//模式选择,此时选择PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性选择,这里是高极性,不翻转,按原来的高低电平输出
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//使能输出
	TIM_OCInitStructure.TIM_Pulse=0;              //设计CCR的值
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	
	
	
	
}

void PWM_SetCompare2(uint16_t Compare)
{
	
	TIM_SetCompare2(TIM2,Compare);//外部设计CCR的值
}

角度.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Servo_Init(void)
{
	PWM_Init();
	
}

void Servo_SetAngle(float Angle)
{
	PWM_SetCompare2(Angle/180*2000+500);
	
}

PWM.h

#ifndef __PWM_H
#define __PWM_H
void PWM_Init(void);
void PWM_SetCompare2(uint16_t Compare);
#endif

角度.h

#ifndef __SERVO_H
#define __SERVO_H
void Servo_Init(void);
void Servo_SetAngle(float Angle);

#endif

主要

#include "OLED.h"  
#include "Servo.h" 
#include "Key.h"
uint8_t KeyNum;
float Angle;
int main(void)
{
	OLED_Init();
	Servo_Init();
	Key_Init();
	OLED_ShowString(1,1,"Angle:");

	while(1)
	{
		KeyNum=Key_GetNum();
		if(KeyNum==1)
		{
			Angle+=15;
			if(Angle>180)
			{
				Angle=0;
			}
		}
			Servo_SetAngle(Angle);
			OLED_ShowNum(1,7,Angle,3);
	}
}

DC モーターとドライブの紹介

 

 ドライバーチップ.c

#include "stm32f10x.h"                  // Device header
#include "PWM.h"

void Motor_Init()
{
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5| GPIO_Pin_6| GPIO_Pin_7;
 	GPIO_Init(GPIOA, &GPIO_InitStructure);
	PWM_Init();
	
	
}

void Motor_SetSpeed(int8_t Speed)
{
	
	if(Speed>=0)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);
		GPIO_SetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6);
		PWM_SetCompare3(Speed);
		PWM_SetCompare2(Speed);
	}
	else
		{
		GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_7);
		GPIO_ResetBits(GPIOA,GPIO_Pin_4|GPIO_Pin_6);
		PWM_SetCompare3(-Speed);
		PWM_SetCompare2(-Speed);
		}
	}

PWM.c

#include "stm32f10x.h"                  // Device header


void PWM_Init(void)
{
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//选择TIM2定时器
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_1;//
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	TIM_InternalClockConfig(TIM2);//由内部时钟驱动
	
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;     //预分频系数1
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
	TIM_TimeBaseInitStructure.TIM_Prescaler=36-1;//
TIM_TimeBaseInitStructure.TIM_Period=100-1;//
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器的中的重复计数器的
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//时机单元初始化函数
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断
	
	TIM_Cmd(TIM2,ENABLE);
	
	TIM_OCInitTypeDef TIM_OCInitStructure;
	TIM_OCStructInit(&TIM_OCInitStructure);//避免给一些没用到的参数赋予初始值而导致混乱
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//模式选择,此时选择PWM1模式
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//极性选择,这里是高极性,不翻转,按原来的高低电平输出
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//使能输出
	TIM_OCInitStructure.TIM_Pulse=0;              //设计CCR的值
	TIM_OC3Init(TIM2,&TIM_OCInitStructure);
	TIM_OC2Init(TIM2,&TIM_OCInitStructure);
	
	
	
}

void PWM_SetCompare3(uint16_t Compare)
{
	
	TIM_SetCompare3(TIM2,Compare);//外部设计CCR的值
}
void PWM_SetCompare2(uint16_t Compare)
{
	
	TIM_SetCompare2(TIM2,Compare);//外部设计CCR的值
}

この記事は江蘇科技大学と共同で研究したものであり、私の研究ノートです。侵害がある場合は、削除するために私に連絡してください。

おすすめ

転載: blog.csdn.net/m0_71827453/article/details/131872577
おすすめ