摘要:
本文用PWM輸出波形控制IO口實作呼吸燈,并通過DAC輸出2KHz的正弦波和編輯音頻輸出的功能。
文章目錄
-
-
- 摘要:
- 一. PWM練習
-
- 1. PWM簡介
- 2. PWM輸出配置
- 3. 主要代碼
- 4.示範效果
-
- a. 模拟示波器顯示
- b. 示波器顯示
- c. 實物效果
- 二. DAC練習
-
- 1. DAC簡介
- 2.要點分析并實作2KHz正弦波的輸出
- 4. 設計輸出音頻信号
- 三. 總結
-
一. PWM練習
1. PWM簡介
PWM是 Pulse Width Modulation 的縮寫,中文意思就是脈沖寬度調制,簡稱脈寬調制。它是利用微處理器的數字輸出來對模拟電路進行控 制的一種非常有效的技術,其控制簡單、靈活和動态響應好等優點而成 為電力電子技術最廣泛應用的控制方式。
其原理圖如下:

STM32F1除了基本定時器TIM6和TIM7,其他定時器都可以産生PWM輸出 。其中進階定時器 TIM1 和 TIM8 可以同時産生多達 7 路的 PWM 輸出 。而通用定時器也能同時産生多達 4路的 PWM 輸出,這些在定時器中斷 章節中已經介紹過。 PWM的輸出其實就是對外輸出脈寬可調(即占空比調節)的方波信号 ,信号頻率是由自動重裝寄存器 ARR 的值決定,占空比由比較寄存器 CCR 的值決定。PWM輸出比較模式總共有8種,具體由寄存器 CCMRx 的位 OCxM[2:0] 配置。我們這裡隻講解最常用的兩種PWM輸出模式:PWM1和PWM2,其他幾 種模式可以參考《STM32F10x中文參考手冊》13、14、15定時器章節。
更多知識可以參考stm32 PWM輸出實驗
2. PWM輸出配置
1)配置使能端口時鐘,設定引腳複用器映射
2)初始化定時器參數,包含自動重裝值,分頻系數,計數方式等
初始化PWM輸出參數,包含輸出極性,使能等
3)開定時器
4)之後在主函數中控制占空比:
這時while(1)裡循環得代碼,作用就是led0pwmval占空比逐漸增大,也就是越來越亮。在
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare2(TIM3,led0pwmval);
3. 主要代碼
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鐘使能
TIM_TimeBaseStructure.TIM_Period = arr; //設定在下一個更新事件裝入活動的自動重裝載寄存器周期的值 計數到5000為500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設定用來作為TIMx時鐘頻率除數的預分頻值 10Khz的計數頻率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數機關
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優先級0級
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級3級
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIMx外設
}
//定時器3中斷服務程式
void TIM3_IRQHandler(void) //TIM3中斷
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷發生與否:TIM 中斷源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中斷待處理位:TIM 中斷源
LED1=!LED1;
}
}
//TIM3 PWM部分初始化
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預分頻數
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定時器3時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設和AFIO複用功能子產品時鐘
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//設定該引腳為複用輸出功能,輸出TIM3 CH2的PWM脈沖波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //設定在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設定用來作為TIMx時鐘頻率除數的預分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數機關
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據T指定的參數初始化外設TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預裝載寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
4.示範效果
a. 模拟示波器顯示
選擇魔術棒–Debug–配置如下
示波器配置如下:
顯示效果:
b. 示波器顯示
c. 實物效果
二. DAC練習
1. DAC簡介
- DAC為數字/模拟轉換子產品,故名思議,它的作用就是把輸入的數字編碼,轉換成對應的模拟電壓輸出,它的功能與ADC相反。在常見的數字信号系統中,大部分傳感器信号被化成電壓信号,而ADC把電壓模拟信号轉換成易于計算機存儲、處理的數字編碼,由計算機處理完成後,再由DAC輸出電壓模拟信号,該電壓模拟信号常常用來驅動某些執行器件,使人類易于感覺。如音頻信号的采集及還原就是這樣一個過程。
- STM32具有片上DAC外設,它的分辯率可配置為8位或12位的數字輸入信号,具有兩個DAC輸出通道,這兩個通道互不影響,每個通道都可以使用DMA功能,都具有出錯檢測能力,可外部觸發。
- DAC子產品圖如下:
整個DAC子產品圍繞框圖下方的**“數字至模拟轉換器x”**展開,它的左邊分别是參考電源的引腳:VDDA、VSSA及Vref+,其中STM32的DAC規定了它的參考電壓Vref+輸入範圍為2.4–3.3V。“數字至模拟轉換器x”的輸入為DAC的資料寄存器“DORx”的數字編碼,經過它轉換得的模拟信号由圖中右側的“ DAC OUTX”輸出。而資料寄存器“DORx“又受“控制邏輯”支配,它可以控制資料寄存器加入一些僞噪聲信号或配置産生三角波信号。圖中的左上角為DAC的觸發源,DAC根據觸發源的信号來進行DAC轉換,其作用就相當于DAC轉換器的開關,它可以配置的觸發源為外部中斷源觸發、定時器觸發或軟體控制觸發。如本章實驗中需要控制正弦波的頻率,就需要定時器定時觸發DAC進行資料轉換。
2.要點分析并實作2KHz正弦波的輸出
- DAC_Trigger 用于配置DAC的觸發方式
- DAC_WaveGeneration為是否啟動輸出噪聲或者三角波
- DAC_LFSRUnmask_TriangleAmpliude 為選擇噪聲生成器的低通濾波或三角波的幅值
-
DAC_OutputBuffer 選擇是否使能輸出緩存器
更多步驟請參考
《【野火®】零死角玩轉STM32—F103-MINI》
根據公式:
STM32的PWM和DAC的練習
設定如下
這樣即可輸出2Khz的正弦波
結果如下:
接入蜂鳴器,聽有單音。
4. 設計輸出音頻信号
算法邏輯類似與輸出正弦波信号的思路一緻,不同的是要更改采樣的數值。
step1:打開
Adobe Audition
打開自己喜歡的音樂,設定:
- 采樣率8000
- 單聲道
- 16位
- 大約采集2-3s
step2:存儲為.wav檔案
.wav檔案通過軟體
Uedit32
打開
step3:格式轉換
全選内容,右鍵–用16進制複制所選視圖,複制到記事本–粘貼回去–右鍵–選擇範圍
step4:複制到notepad++進行填充
關于
notepad++
前文提到過用法,
按列塊插入
0x
和
,
每列重複操作
step5:修改數組
step6:燒入觀察波形
三. 總結
這次實驗,嘗試了解了DAC和PWM,這兩個子產品在時機中應用十分廣泛,比如在一些比賽中可以用PWM波控制舵機和點選,用ADC,DAC進行采集資訊等。收獲許多
參考
[1] 使用STM32控制無源蜂鳴器發聲播放音樂(STM32_07)
[2] stm32 PMW輸出實驗
[3] 詳解基于STM32的keil4 MDK 軟體仿真輸出IO口的波形圖!