【注意】STM32F103 7、PWM出力タイマ - 呼吸する光

これは、STM32、3つのカテゴリに分類STM32タイマーを導入するタイマーです。

  • ベーシック・タイマ基本タイマ):0から所定値までカウントし、DACの内部に接続されている割り込みやDMA、他の機能は、トリガDACに使用することができないトリガー。
  • 汎用タイマ汎用タイマー):昇順または降順カウントインプットキャプチャのために使用することができ、PWM I、比較出力、PWM出力、パルス出力、及び単機能ので、
  • アドバンストタイマアドバンスト制御タイマー):汎用タイマと、実質的に全ての機能があり、挿入された出力PWMデッド、ステップ6と、三相モータ駆動機能をデコードするエンコーダ。

STM32F103C8T6ための3つの汎用タイマとタイマ用(マニュアル)進みました。これは、出力する光呼吸の効果を達成するため、LEDを制御するために、異なるデューティサイクルのPWM波を使用する汎用タイマーです。

デザインの原則

システムボードにおいて、PB8は、LED、STM32F103C8T6手動検査を制御するために使用される、それは4のPB8チャネルタイマ出力端子3が見出された:
ここに画像を挿入説明
タイマー4を分析する必要があります。

TIM4タイマー

タイマクロック

その内部構造図4に示すように、STM32タイマタイマ汎用である:
ここに画像を挿入説明
第二章で分析し、上記クロック信号選択部タイマ、タイマAPB1バス、クロック信号APB1マウントSystemInit後()関数は、周波数逓倍器2 APB1クロック信号を可能にするタイマーを入力した後、初期化した後、周波数逓倍APB1バスを介して、36MHzのを初期化します。

すなわち、バスAPB1の36MHzの上のクロック信号が、であるがための周波数逓倍器2と、最終的にクロックタイマは72MHzであり、即ち図の上方に、CK_PSCの 72MHzのクロック信号。

スルーCK_PSCクロック信号PSCプリスケーラカウンタに周波数分割後、クロック信号としてカウンタ。

タイマー関数ライブラリ

基本初期構造TIM_TimeBaseInitTypeDef

そしてここで、他の周辺機器の初期化として、タイマーの初期化は、その構造を持って初期化し、機能を制御することができます手動分析、コードに直接貼り付けます。

/** 
  * @brief  TIM Time Base Init structure definition
  * @note   This structure is used with all TIMx except for TIM6 and TIM7.    
  */

typedef struct
{
  uint16_t TIM_Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                       This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_CounterMode;       /*!< Specifies the counter mode.
                                       This parameter can be a value of @ref TIM_Counter_Mode */

  uint16_t TIM_Period;            /*!< Specifies the period value to be loaded into the active
                                       Auto-Reload Register at the next update event.
                                       This parameter must be a number between 0x0000 and 0xFFFF.  */ 

  uint16_t TIM_ClockDivision;     /*!< Specifies the clock division.
                                      This parameter can be a value of @ref TIM_Clock_Division_CKD */

  uint8_t TIM_RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                       reaches zero, an update event is generated and counting restarts
                                       from the RCR value (N).
                                       This means in PWM mode that (N+1) corresponds to:
                                          - the number of PWM periods in edge-aligned mode
                                          - the number of half PWM period in center-aligned mode
                                       This parameter must be a number between 0x00 and 0xFF. 
                                       @note This parameter is valid only for TIM1 and TIM8. */
} TIM_TimeBaseInitTypeDef;  
  • TIM_Prescaler:プリスケーラPSCに対応する値の上方に設けられているクロック分周値は、この値は、0x0000-0xFFFF設定することができる、すなわち0-65535、レジスタに対応TIMxをpresacler(TIMx_PSC)
    ここに画像を挿入説明
    PSCプリスケーラが進行した後にカウンタクロック信号の周波数であります:
    F C K _ P S C / P S C + 1 F_ {CK \ _PSC} /(PSC + 1)
    このようなPSC 71の値を設定するように、最終的にカウンタにクロック信号の周波数は1MHzです。
  • TIM_CounterMode:カウンター方向、他の加算または減算からです。
  • TIM_Period:计数周期,也就是计数器一共计数多少,比如设置为999且为向上计数,那么计数器从0计数到999+1,共计1000us,也就是计数器最后输出PWM的频率为1KHz;
  • 剩下的参数在这里不使用,暂时不进行说明。
输出比较结构体

若使用PWM直接控制引脚输出,则还需要另一个初始化结构体:

typedef struct
{
  uint16_t TIM_OCMode;        /*!< Specifies the TIM mode.
                                   This parameter can be a value of @ref TIM_Output_Compare_and_PWM_modes */

  uint16_t TIM_OutputState;   /*!< Specifies the TIM Output Compare state.
                                   This parameter can be a value of @ref TIM_Output_Compare_state */

  uint16_t TIM_OutputNState;  /*!< Specifies the TIM complementary Output Compare state.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_state
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint16_t TIM_Pulse;         /*!< Specifies the pulse value to be loaded into the Capture Compare Register. 
                                   This parameter can be a number between 0x0000 and 0xFFFF */

  uint16_t TIM_OCPolarity;    /*!< Specifies the output polarity.
                                   This parameter can be a value of @ref TIM_Output_Compare_Polarity */

  uint16_t TIM_OCNPolarity;   /*!< Specifies the complementary output polarity.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_Polarity
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint16_t TIM_OCIdleState;   /*!< Specifies the TIM Output Compare pin state during Idle state.
                                   This parameter can be a value of @ref TIM_Output_Compare_Idle_State
                                   @note This parameter is valid only for TIM1 and TIM8. */

  uint16_t TIM_OCNIdleState;  /*!< Specifies the TIM Output Compare pin state during Idle state.
                                   This parameter can be a value of @ref TIM_Output_Compare_N_Idle_State
                                   @note This parameter is valid only for TIM1 and TIM8. */
} TIM_OCInitTypeDef;
  • TIM_OCMode:输出模式设置,这里设置成PWM1输出模式,即当计数器中的值小于等于设定的值时,引脚输出有效电平,大于时输出无效电平;
  • TIM_OutputState:设置为使能输出模式;
  • TIM_Pulse:即设定的值(取名为Pulse可能意思是PWM有效电平脉宽吧),当计数器中计数值小于等于设定的值时,输出有效电平;
  • TIM_OCPolarity:设置有效电平为高电平还是低电平;
  • 剩下的参数在这里不使用,暂时不进行说明。

程序设计

改进延时函数

在上一篇中,利用SysTick的中断进行延时,而SysTick中断可能影响其他中断操作(虽然本篇没用到中断)。

因此首先对延时函数进行改进,SysTick可以配置成不触发中断的形式,此时可以不断查询SysTick寄存器CTRL的Bit 16,当Bit 16置1时说明计数结束,即延时完成:

void delay_us(uint32_t us)
{
	SysTick->LOAD = us * 9;
	// 设置SysTick8分频,即9MHz,并使能SysTick开始计数
	SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
	while(!(SysTick->CTRL&(1<<16)));
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
void delay_ms(uint32_t ms)
{
	SysTick->LOAD = ms * 9000;
	SysTick->CTRL = SysTick_CTRL_ENABLE_Msk;
	while(!(SysTick->CTRL&(1<<16)));
	SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

这里注意在配置CTRL寄存器时,应保持Bit 2为0,即使用8分频时钟,否则LOAD寄存器可能超出范围(最大值为0xFFFFFF)。

初始化TIM4

根据上述两个初始化结构体,对TIM4进行初始化:

void Timer4PWMConfig(void)
{
	TIM_TimeBaseInitTypeDef TIM4InitStruct;
	TIM_OCInitTypeDef TIM4OCInitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	
	TIM4InitStruct.TIM_Prescaler = 71;  // 1MHz
	TIM4InitStruct.TIM_Period = 999;  //999+1=1000 - 1KHz
	TIM4InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM4InitStruct);
	
	TIM4OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM4OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM4OCInitStruct.TIM_Pulse = 0;
	TIM4OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OC3Init(TIM4, &TIM4OCInitStruct);
	// 使能TIM4的通道3比较寄存器预加载
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
	// 使能自动重载寄存器ARR
	TIM_ARRPreloadConfig(TIM4, ENABLE);
	// 使能TIM4
	TIM_Cmd(TIM4, ENABLE);
}

初始化PB8

这里注意将PB8初始化为复用推挽输出(用于TIM4的输出引脚):

void PB8LEDConfig(void)
{
	GPIO_InitTypeDef GPIOInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStruct);
}

完整程序

(1)サイクルメイン関数が、シグモイド関数は、現在のPWMパルス幅に応じて算出され、チャネルリセットTIM_Pulse 3(すなわち、CCR3 TIM4レジスタ)、光操作呼吸の効果:

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "delay.h"
#include <math.h>

/* Functions decleration -----------------------------------------------------*/
void Timer4PWMConfig(void);
void PB8LEDConfig(void);

int main(void)
{
	uint16_t i;
	double temp;
	
	PB8LEDConfig();
	Timer4PWMConfig();
	
	while(1)
	{
		for(i=0; i<101; i++)
		{
			temp = 1000 / (1 + pow(2.71828, 5-(double)i/10));
			// 调用库函数TIM_SetCompare3或者直接对CCR3寄存器赋值
			//TIM_SetCompare3((uint16_t)temp);
			TIM4->CCR3 = (uint16_t)temp;
			delay_ms(10);
		}
		for(i=0; i<101; i++)
		{
			temp = 1000 / (1 + pow(2.71828, (double)i/10-5));
			//TIM_SetCompare3((uint16_t)temp);
			TIM4->CCR3 = (uint16_t)temp;
			delay_ms(10);
		}
	}
}

void Timer4PWMConfig(void)
{
	TIM_TimeBaseInitTypeDef TIM4InitStruct;
	TIM_OCInitTypeDef TIM4OCInitStruct;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
	
	TIM4InitStruct.TIM_Prescaler = 71;  // 1MHz
	TIM4InitStruct.TIM_Period = 999;  //999+1=1000 - 1KHz
	TIM4InitStruct.TIM_CounterMode = TIM_CounterMode_Up;
	TIM_TimeBaseInit(TIM4, &TIM4InitStruct);
	
	TIM4OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
	TIM4OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
	TIM4OCInitStruct.TIM_Pulse = 0;
	TIM4OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_Low;
	TIM_OC3Init(TIM4, &TIM4OCInitStruct);
	TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable);
	TIM_ARRPreloadConfig(TIM4, ENABLE);
	TIM_Cmd(TIM4, ENABLE);
}

void PB8LEDConfig(void)
{
	GPIO_InitTypeDef GPIOInitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIOInitStruct.GPIO_Pin = GPIO_Pin_8;
	GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIOInitStruct);
}

業績

コンパイルダウンロードして、プログラムを実行するには、呼吸パターンに光LEDが点滅します。
ここに画像を挿入説明

エンドSahua✿✿ヽ(゜▽゜)テクノ✿

リリース9件のオリジナルの記事 ウォン称賛22 ビュー8144

おすすめ

転載: blog.csdn.net/Keep_moving_tzw/article/details/104592277
おすすめ