專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> STM32 >> 瀏覽文章

STM32之呼吸燈

作者:未知   來(lái)源:互聯(lián)網(wǎng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年09月14日   【字體:

作為初學(xué)者,剛剛接觸STM32,所以文章有何不妥之處,敬請(qǐng)指出,一定會(huì)改。

聽(tīng)說(shuō)呼吸燈是很久以前的事情了,那時(shí)候剛剛學(xué)習(xí)51單片機(jī),沒(méi)有單片機(jī)的基礎(chǔ)。后來(lái)在網(wǎng)上看到了一個(gè)呼吸燈的電路圖,甚是復(fù)雜,根本看不懂,無(wú)奈之下放棄了呼吸燈的制作。在接觸了STM32后,發(fā)現(xiàn)呼吸燈還是比較容易實(shí)現(xiàn)的,而且不需要什么硬件知識(shí)就可以完成。于是開始嘗試做呼吸燈了。

 

其實(shí)做呼吸燈還是有一些波折的,程序有各種版本,且由于剛剛學(xué)習(xí)STM32——看不懂程序,所以在了解了大概的思路后,便開始自己嘗試寫程序了。哈哈美圖隔開。



下面進(jìn)入今天的正題——呼吸燈。

首先我們應(yīng)該了解呼吸燈的基本原理——關(guān)鍵是用STM32輸出占空比可調(diào)的方波。

用到了STM32的PWM輸出,我們就必須了解它。STM32是帶有PWM輸出功能的。我們以TIM3來(lái)實(shí)現(xiàn)PWM的輸出。

關(guān)于TIM3大家可以查閱STM32的相關(guān)資料,在這里我不在詳解。

由以上可知道我們必須讓STM32輸出PWM或者說(shuō)輸出方波,因此我們必須知道怎么讓STM32輸出PWM。

用STM32輸出占空比可調(diào)的PWM制作呼吸燈的步驟:(自己感覺(jué)很重要)

① 配置系統(tǒng)時(shí)鐘(RCC_Config)

② 配置GPIO口(TIM3_GPIO_Config)

③ 配置TIMER(TIM3_Mode_Config)

④ 寫實(shí)現(xiàn)呼吸燈的主體程序

⑤ 進(jìn)行呼吸燈的調(diào)試

現(xiàn)在我們來(lái)一步一步理解程序:

 ① 配置系統(tǒng)時(shí)鐘(RCC_Config):

     
將TIM3和GPIO的時(shí)鐘打開。
由以上可以看出:

                            TIM3掛載在APB1

                            GPIO掛載在APB2

② 配置GPIO口(TIM3_GPIO_Config):


這里新手一般都會(huì)很疑惑,尤其是自學(xué)者都不知道為什么要設(shè)置Pin,Mode,Speed等等。

還有人常常有疑問(wèn),再用某個(gè)功能之前我怎么知道都要設(shè)置哪些東西。其實(shí)大家可以看看學(xué)習(xí)STM32至關(guān)重要的資料——STM32固件庫(kù)手冊(cè),便會(huì)有所了解。
③ 配置TIMER(TIM3_Mode_Config)

void TIM3_Mode_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//設(shè)置一個(gè)TIM_TimeBaseStructure結(jié)構(gòu)體。
  TIM_OCInitTypeDef TIM_OCInitStructure;//設(shè)置一個(gè)TIM_OCInitStructure結(jié)構(gòu)體。
  TIM_TimeBaseStructure.TIM_Period=1000-1;//個(gè)人理解就是計(jì)幾個(gè)數(shù)。(由此可以得到PWM的周期)
  TIM_TimeBaseStructure.TIM_Prescaler=0;//設(shè)置用來(lái)作為 TIMx 時(shí)鐘頻率除數(shù)的預(yù)分頻值。
  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置時(shí)鐘分割。
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//選擇了計(jì)數(shù)器模式。
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//將設(shè)置好的參數(shù)初始化。
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//設(shè)置TIM輸出模式PWM1。
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//選擇輸出比較狀態(tài)(?)
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//TIM 輸出比較極性高。
  TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//設(shè)置了待裝入捕獲比較寄存器的脈沖值。
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);//將設(shè)定好的參數(shù)初始化給通道1。
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的預(yù)裝載寄存器。
  TIM_OCInitStructure.TIM_Pulse=CCR2_Val;
  TIM_OC2Init(TIM3,&TIM_OCInitStructure);//通道2
  TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM3,ENABLE);//使能TIM3在 ARR 上的預(yù)裝載寄存器。
  TIM_Cmd(TIM3,ENABLE);//使能TIM3的外設(shè)
}

④ 寫實(shí)現(xiàn)呼吸燈的主體程序:



其實(shí)這就是主函數(shù),任何情況下主函數(shù)是必須有的。這個(gè)呼吸燈實(shí)現(xiàn)的方法和網(wǎng)上的大神寫的差很多,但是它實(shí)現(xiàn)了呼吸燈的逐漸明暗,自我感覺(jué)適合初學(xué)者學(xué)習(xí)呼吸燈以后大家把STM32學(xué)習(xí)的比較明白了后,就自然而然會(huì)寫那些更加“高大上”的呼吸燈程序了。

為了方便自學(xué)初學(xué)的需要下面添加一些附件(芯片型號(hào)和整體程序)

① 芯片信號(hào)STM32F103RB,晶振用的是8M。

② 整體程序:

#include "stm32f10x.h"
u16 CCR1_Val=1000;
u16 CCR2_Val=0;
u8 a=0;
void Delay(__IO u32 nCount)
{
  while(nCount--);
}
void RCC_Config(void)
{
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
}
void TIM3_GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;//設(shè)置一個(gè)GPIO_InitStructure結(jié)構(gòu)體。
  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7;//選擇引腳6和7。
  GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//選擇輸出模式為復(fù)用推挽輸出。
  GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//設(shè)置引腳最高輸出速率為50MHz。
  GPIO_Init(GPIOA,&GPIO_InitStructure);//將設(shè)定好的參數(shù)初始化。
}
void TIM3_Mode_Config(void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//設(shè)置一個(gè)TIM_TimeBaseStructure結(jié)構(gòu)體。
  TIM_OCInitTypeDef TIM_OCInitStructure;//設(shè)置一個(gè)TIM_OCInitStructure結(jié)構(gòu)體。
  TIM_TimeBaseStructure.TIM_Period=1000-1;//個(gè)人理解就是計(jì)幾個(gè)數(shù)。(由此可以得到PWM的周期)
  TIM_TimeBaseStructure.TIM_Prescaler=0;//設(shè)置用來(lái)作為 TIMx 時(shí)鐘頻率除數(shù)的預(yù)分頻值。
  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;//設(shè)置時(shí)鐘分割。
  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//選擇了計(jì)數(shù)器模式。
  TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);//將設(shè)置好的參數(shù)初始化。
  TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//設(shè)置TIM輸出模式PWM1。
  TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//選擇輸出比較狀態(tài)(?)
  TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//TIM 輸出比較極性高。
  TIM_OCInitStructure.TIM_Pulse=CCR1_Val;//設(shè)置了待裝入捕獲比較寄存器的脈沖值。
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);//將設(shè)定好的參數(shù)初始化給通道1。
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能TIM3在CCR1上的預(yù)裝載寄存器。
  TIM_OCInitStructure.TIM_Pulse=CCR2_Val;
  TIM_OC2Init(TIM3,&TIM_OCInitStructure);//通道2
  TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
  TIM_ARRPreloadConfig(TIM3,ENABLE);//使能TIM3在 ARR 上的預(yù)裝載寄存器。
  TIM_Cmd(TIM3,ENABLE);//使能TIM3的外設(shè)
}
int main(void)
{
    RCC_Config();
 TIM3_GPIO_Config();
 TIM3_Mode_Config();
 while(1)

 {
     if(CCR1_Val>0&&a<40&&CCR2_Val<1000)
     {
       CCR1_Val-=25;
       CCR2_Val+=25;
       TIM3_Mode_Config();
       a++;
       Delay(0XF424); 
     }
    else
    {
       CCR1_Val+=25;
       CCR2_Val-=25;
       TIM3_Mode_Config();
       Delay(0XF424);
       a++;
    if(a==80)a=0;
     }
 }
}

 

關(guān)閉窗口

相關(guān)文章