畢業(yè)論文做cad圖的網(wǎng)站江蘇網(wǎng)頁設(shè)計
一、介紹
PWM(脈寬調(diào)制,Pulse-width modulation)是一種通過調(diào)節(jié)脈沖信號的寬度來控制電能輸出的方法。PWM是一種方波信號,通常在電子和電氣工程中用于調(diào)節(jié)功率輸送,控制電機速度,調(diào)節(jié)LED亮度,以及生成模擬信號等。 PWM信號是通過不斷地將一個信號在高電平和低電平之間切換而生成的。
PWM的核心參數(shù)有兩個:頻率和占空比。
頻率:PWM信號的開關(guān)速度,表示每秒完成的周期次數(shù)。頻率越高,PWM信號周期越短。
占空比:在一個周期內(nèi),高電平所占的時間比例。
二、原理
利用TIM定時器和輸出比較,TIM定時器會周期性地線性增長,當(dāng)計數(shù)器的值低于設(shè)定的比較值時輸出高電平,大于等于比較值時輸出低電平。由于是線性增長,高電平時長占整個周期信號時長的比例是固定的,這個比例被稱為“占空比”,英文“Duty Cycle”。在嵌入式系統(tǒng)中,特別是使用定時器來生成PWM信號時,經(jīng)常使用的是定時器的比較寄存器(Capture/Compare Register,CCR)和自動重載寄存器(Auto-Reload Register,ARR)來控制PWM的占空比。
給定:
??? CCR:比較寄存器的值(通常用來設(shè)置PWM波形的占空比)
??? ARR:自動重載寄存器的值(通常用來設(shè)置PWM波形的周期)
那么:Duty=CCR/(ARR+1)
通用定時器的結(jié)構(gòu)
?
設(shè)置PWM 模式
脈沖寬度調(diào)制模式可以產(chǎn)生一個由TIMx_ARR寄存器確定頻率、由TIMx_CCRx寄存器確定占空
比的信號。在TIMx_CCMRx寄存器中的OCxM位寫入’110’(PWM模式1)或’111’(PWM模式2),能夠獨立地設(shè)置每個OCx輸出通道產(chǎn)生一路PWM。必須設(shè)置TIMx_CCMRx寄存器OCxPE位以使能相應(yīng)的預(yù)裝載寄存器,最后還要設(shè)置TIMx_CR1寄存器的ARPE位, (在向上計數(shù)或中心對稱模式中)使能自動重裝載的預(yù)裝載寄存器。
?
三、實例
定時器輸出PWM配置過程
1、打開RCC時鐘,因為PWM的輸出也是用到IO口,所以定時器和GPIO時鐘都要打開。
2、配置GPIO口,注意引腳模式。
3、配置時基單元(分頻、計數(shù)模式、arr、psc)
4、配置輸出比較段元
5、運行控制
使用PWM控制LED亮度
#include "stm32f10x.h" // Device header/*** 函 數(shù):PWM初始化* 參 數(shù):無* 返 回 值:無*/
void PWM_Init(void)
{/*開啟時鐘*/RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //開啟TIM2的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //開啟GPIOA的時鐘/*GPIO重映射*/
// RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //開啟AFIO的時鐘,重映射必須先開啟AFIO的時鐘
// GPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE); //將TIM2的引腳部分重映射,具體的映射方案需查看參考手冊
// GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //將JTAG引腳失能,作為普通GPIO引腳使用/*GPIO初始化*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); //將PA0引腳初始化為復(fù)用推挽輸出 //受外設(shè)控制的引腳,均需要配置為復(fù)用模式 /*配置時鐘源*/TIM_InternalClockConfig(TIM2); //選擇TIM2為內(nèi)部時鐘,若不調(diào)用此函數(shù),TIM默認(rèn)也為內(nèi)部時鐘/*時基單元初始化*/TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //定義結(jié)構(gòu)體變量TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鐘分頻,選擇不分頻,此參數(shù)用于配置濾波器時鐘,不影響時基單元功能TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數(shù)器模式,選擇向上計數(shù)TIM_TimeBaseInitStructure.TIM_Period = 100 - 1; //計數(shù)周期,即ARR的值TIM_TimeBaseInitStructure.TIM_Prescaler = 720 - 1; //預(yù)分頻器,即PSC的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重復(fù)計數(shù)器,高級定時器才會用到TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); //將結(jié)構(gòu)體變量交給TIM_TimeBaseInit,配置TIM2的時基單元/*輸出比較初始化*/TIM_OCInitTypeDef TIM_OCInitStructure; //定義結(jié)構(gòu)體變量TIM_OCStructInit(&TIM_OCInitStructure); //結(jié)構(gòu)體初始化,若結(jié)構(gòu)體沒有完整賦值//則最好執(zhí)行此函數(shù),給結(jié)構(gòu)體所有成員都賦一個默認(rèn)值//避免結(jié)構(gòu)體初值不確定的問題TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //輸出比較模式,選擇PWM模式1TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性,選擇為高,若選擇極性為低,則輸出高低電平取反TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //輸出使能TIM_OCInitStructure.TIM_Pulse = 0; //初始的CCR值TIM_OC1Init(TIM2, &TIM_OCInitStructure); //將結(jié)構(gòu)體變量交給TIM_OC1Init,配置TIM2的輸出比較通道1/*TIM使能*/TIM_Cmd(TIM2, ENABLE); //使能TIM2,定時器開始運行
}/*** 函 數(shù):PWM設(shè)置CCR* 參 數(shù):Compare 要寫入的CCR的值,范圍:0~100* 返 回 值:無* 注意事項:CCR和ARR共同決定占空比,此函數(shù)僅設(shè)置CCR的值,并不直接是占空比* 占空比Duty = CCR / (ARR + 1)*/
void PWM_SetCompare1(uint16_t Compare)
{TIM_SetCompare1(TIM2, Compare); //設(shè)置CCR1的值
}
main函數(shù),驅(qū)動LED燈
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "PWM.h"uint8_t i; //定義for循環(huán)的變量int main(void)
{/*模塊初始化*/OLED_Init(); //OLED初始化PWM_Init(); //PWM初始化while (1){for (i = 0; i <= 100; i++){PWM_SetCompare1(i); //依次將定時器的CCR寄存器設(shè)置為0~100,PWM占空比逐漸增大,LED逐漸變亮Delay_ms(10); //延時10ms}for (i = 0; i <= 100; i++){PWM_SetCompare1(100 - i); //依次將定時器的CCR寄存器設(shè)置為100~0,PWM占空比逐漸減小,LED逐漸變暗Delay_ms(10); //延時10ms}}
}
參考:
https://zhuanlan.zhihu.com/p/666825444
PWM輸入輸出_pwm輸出-CSDN博客?