嵌入式系統設計課程設計 課題名稱:基于stm32的呼吸燈設計說明書 學 院: 機械與自動控制學院 專 業: 機械電子工程 3班 設計成員:胡* 學 號:201530300139 指導老師: 張* 日 期: 2018年6月20日
目錄 一、 呼吸燈簡介2 二、 PWM呼吸燈原理3 1.PWM簡介3 2.PWM程序編寫5 三、呼吸燈的設計9 1.程序設計9 2. 呼吸燈電路圖設計14 3.呼吸燈實驗實物圖 14 四、結論與心得15 五、參考文獻16
基于stm32的呼吸燈 1、呼吸燈簡介呼吸燈是指燈光在微電腦的控制之下完成由亮到暗的逐漸變化,感覺好像是人在呼吸。其廣泛應用于手機之上,并成為各大品牌新款手機的賣點之一,起到一個通知提醒的作用。當你的手機里面有未處理的通知,比如說未接來電,未查收的短信等等,呼吸燈就會由暗到亮的變化,像呼吸一樣那么有節奏,起到一個通知提醒的作用。 要使用數字器件控制燈光的強弱,我們很自然就想到PWM(脈沖寬度調制)技術。假如以LED作為燈光設備,且由控制器輸出的PWM信號可以直接驅動LED,PWM信號中的低電平可點亮LED燈。由于視覺暫留效應,人眼可以看不到LED燈的閃爍現象,反應到人眼中的是亮度的差別,因此我們需要LED以較高的頻率進行開關(亮滅)切換。因此我們可以使用高頻率的PWM信號,通過調制信號的占空比,控制LED燈的亮度。根據以上思路,根據上課和實驗所學知識利用PWM實現呼吸燈設計。 2、PWM呼吸燈原理1.PWM簡介Pulse Width Modulation: 脈沖寬度調制(PWM) 脈沖:頻率 ,方波 脈沖寬度:占空比, 高電平的寬度:在同一個時間內,高電平所占比例 頻率與周期:f = 1/T f:頻率(主頻) T:周期 脈沖寬度調制(PWM),是英文“Pulse Width Modulation”的縮寫,簡稱脈寬調制,是利用微處理器的數字輸出來對模擬電路進行控制的一種非常有效的技術。簡單一點,就是對脈沖寬度的控制,PWM原理如圖: 圖中,我們假定定時器工作在向上計數PWM模式,且當CNT<CCRx時,輸出0,CNT>=CCRx時輸出1。那么就可以得到如上的PWM示意圖:當CNT值小于CCRx的時候IO輸出低電平(0),當CNT值大于等于CCRx的時候,IO輸出高電平(1),當CNT達到ARR值的時候,重新歸零,然后重新向上計數,依次循環。改變CCRx的值,就可以改變PWM輸出的占空比,改變ARR的值,就可以改變PWM輸出的頻率,這就是PWM輸出的原理。 控制PWM的三個寄存器:捕獲/比較模式寄存器(TIMx_CCMR1/2),捕獲/比較使能寄存器(TIMx_CCER),捕獲/比較寄存器(TIMx_CCR1~4)。這三個寄存器針對不同的定時器不同的輸出模式設置各不相同。 本次實驗主要用到捕獲/比較寄存器( TIMx_CCR1~4),該寄存器總共有 4 個,對應 4 個輸通道 CH1~4。 TIMX_CCR包括捕獲輸入部分(數字濾波、多路復用和預分頻器)和比較輸出部分(比較器和輸出控制)。 - 捕獲輸入。在輸入時,捕獲/比較寄存器TIMx_CCR被用于黨捕獲(存儲)輸入脈沖在電平發生翻轉時加載脈沖計數器TIMx_CNT的當前計數值,從而實現脈沖的頻率測量。
- 比較輸出。在輸出時,捕獲/比較寄存器TIMx_CCR用來存儲一個脈沖數值,把這個數值與脈沖計數器TIMx_CNT的當前計數值進行比較,根據比較結果進行不同的電平輸出。
在輸出模式下,該寄存器的值與 CNT 的值比較,根據比較結果產生相應動作。通過修改這個寄存器的值,就可以控制 PWM 的輸出脈寬了。 在呼吸燈設計過程中使用的是 TIM3的通道 1和2,需要修改 TIM3_CCR2 以實現脈寬控制 A6和A7的亮度。 2.PWM程序編寫1)開啟TIM3和GPIO時鐘,配置PA6、PA7選擇復用功能AF9(TIM3)輸出。RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能定時器TIM3時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能引腳PA6和PA7的時鐘 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //選擇輸出模式為復用推挽輸出 2)初始化TIM3,設置TIM3的ARR和PSC等參數。在開啟了 TIM3 的時鐘之后,要設置 ARR 和 PSC 兩個寄存器的值來控制輸出 PWM 的周期。當 PWM 周期太慢(低于 50Hz)的時候,就會明顯感覺到閃爍了。因此, PWM 周期在這里不宜設置的太小。 這在庫函數是TIM_TimeBaseInit 函數實現的,調用的格式為: TIM_TimeBaseStructure.TIM_Period=1000-1; //設置自動重裝載寄存器周期的值。 TIM_TimeBaseStructure.TIM_Prescaler=0; //設置用來作為TIMx時鐘頻率除數的預分頻數。 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //設置時鐘分割。 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //選擇計數器模式,向上計數。 TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //將設置好的參數初始化。 3)設置TIM3_CHX的PWM模式,使能TIM3的輸出。要設置 TIM3_CH2 為 PWM 模式(默認是凍結的),因為 LED是低電平亮,而當 CCR2 的值小的時候,D9 就暗,CCR2 值大的時候, D9 就亮,所以通過配置 TIM3_CCMR1 的相關位來控制 TIM3_CH2 的模式。在庫函數中,PWM 通道設置是通過函數TIM_OC1Init()~TIM_OC4Init()來設置的, 不同的通道的設置函數不一樣,通道 1時,使用的函數為TIM_OC1Init();通道2時,使用的函數為TIM_OC2Init()。 結構體TIM_OCInitTypeDef的定義: typedef struct { uint16_t TIM_OCMode; / uint16_t TIM_OutputState; / uint16_t TIM_OutputNState; / uint16_t TIM_Pulse; / uint16_t TIM_OCPolarity; / uint16_t TIM_OCNPolarity; / uint16_t TIM_OCIdleState; / uint16_t TIM_OCNIdleState; / } TIM_OCInitTypeDef; 參數 TIM_OCMode 設置模式是 PWM 還是輸出比較,這里我們是 PWM 模式。
參數 TIM_OutputState 用來設置比較輸出使能,也就是使能 PWM 輸出到端口。
參數 TIM_OCPolarity 用來設置極性是高還是低。
其他的參數 TIM_OutputNState, TIM_OCNPolarity, TIM_OCIdleState 和 TIM_OCNIdleState 是高級定時器 TIM1 和 TIM8 才用到的。 主函數中設置如下: TIM_OCInitTypeDef TIM_OCInitStructure; //設置一個TIM_OCInitStructure結構體來初始化外設 TIMx。 TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //設置TIM輸出模式為PWM1。 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //比較輸出使能。
TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;; //TIM輸出比較級極性高。
TIM_OC1Init(TIM3, &TIM_OCInitStructure); //將設定好的參數初始化給通道1。 TIM_OC2Init(TIM3,&TIM_OCInitStructure); //初始化通道2。 4)使能TIM3.TIM_Cmd(TIM3,ENABLE); //使能 TIM3的外設。 5)修改TIM14_CCR1來控制占空比。通過修改 TIM3_CCR1和TIM3_CCR2 可以控制通道1和通道2的輸出占空比。繼而控制 PA6和PA7 的亮度。 TIM_OCInitStructure.TIM_Pulse=CCR1_Val; //設置了待裝入捕獲比較寄存器的脈沖值。 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的預裝載寄存器 TIM_OCInitStructure.TIM_Pulse=CCR2_Val; //設置了待裝入捕獲比較寄存器的脈沖值。 TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預裝載寄存器。
呼吸燈電路圖設計

圖 部分硬件仿真電路圖 3.呼吸燈實驗實物圖
 四、結論與心得1.一開始老師布置作業時是無限制的自由發揮,一頭霧水不知道自己該從哪里下手該干什么,后來因為在機電傳動控制實驗中正好學習了直流電機PWM調速實驗,由此得到啟發覺得可以通過PWM控制燈泡的閃爍頻率來實現燈光的亮度變化,進而實現呼吸燈的效果。 2.編寫程序過程中還存在許多問題,一開始是直接在實驗例程PWM輸出實驗中修改,因為沒有硬件設備,只能通過仿真,仿真一直不成功,后經過在網上搜集資料、查看相關書籍和詢問同學完成本次實驗的程序,實驗程序中沒有LED程序,而是直接在輸出引腳輸出高低電平從而實現燈泡的閃爍。對實驗中出現的諸多問題,一定要認真分析其原因之所在,然后查閱資料通過各種方法解決實驗中出現的這些問題,做完實驗之后要做好相關總結,這樣才能把一個實驗做完美,對以后的實驗也有著一定的幫助作用。 - 在本次實驗中當決定好做什么內容時,一定要先仔細分析整個實驗要達到的目標要求,然后做出總體設計方案將程序編寫細化到每一部分,這樣就不容易出錯,而且在檢查錯誤問題時也會稍微容易一點。
- 通過這次綜合實驗讓我對stm32有了更進一步的熟悉和了解,一個看似很簡單的東西,到動手把它設計出來就比較困難了,所以在今后的學習中我們要注意這一點,要把課堂上所學到的知識和實際聯系起來,同時通過本次實驗讓我對課本理論知識有了深入實際的理解,也會在調試中出現的錯誤結合理論知識尋找問題所在的原因,一步步檢查調試,直到完成實驗最終目的。
- 通過設計大作業,讓我明白任何實驗都是基于理論的,理論知識學扎實了,才能在程序編寫上和調試上快速準確的完成實驗,以此警示自己在后期的學習中一定要注意理論知識的學習。
三、呼吸燈的設計
1.程序設計
- /*延時函數*/
- void Delay(__IO u32 nCount)
- {
- while(nCount--);
- }
- u16 CCR1_Val=1000;
- u16 CCR2_Val=0;
- u8 a=0;
- /*主函數*/
- 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(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- }
- else
- {
- CCR1_Val+=25;
- CCR2_Val-=25;
- TIM3_Mode_Config();
- Delay(0XFFFF);
- Delay(0XFFFF);
- a++;
- if(a==80)a=0;
- }
- }
- }
- /*使能時鐘*/
- void RCC_Config(void)
- {
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //使能定時器TIM3時鐘。
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //使能引腳PA的時鐘。
- }
- /*配置 GPIO 的模式和 IO 口*/
- void TIM3_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure; //設置一個GPIO_InitStructure結構體。
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7; //選擇引腳PA6和PA7。
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //選擇輸出模式為復用推挽模式。
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; //設置引腳最高輸出速率為50MHZ。
- GPIO_Init(GPIOA,&GPIO_InitStructure); //將設定好的參數初始化。
- }
- /* 設置TIM3 */
- void TIM3_Mode_Config(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //設置一個TIM_TimeBaseStructure結構體。
- TIM_OCInitTypeDef TIM_OCInitStructure; //設置一個TIM_OCInitStructure結構體 。 TIM_TimeBaseStructure.TIM_Period=1000-1; //設置自動重裝載寄存器周期的值。
- TIM_TimeBaseStructure.TIM_Prescaler=0; //設置用來作為TIMx時鐘頻率除數的預分頻值。 TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //設置時鐘分割 。 TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //選擇了計數器模式,向上計數。
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure); //將設置好的參數初始化 。
- TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1; //設置TIM輸出模式為PWM1。
- TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //使能輸出比較
- TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; /TIM輸出比較劑型高
- TIM_OCInitStructure.TIM_Pulse=CCR1_Val; //設置了待裝入捕獲比較寄存器的脈沖值
- TIM_OC1Init(TIM3, &TIM_OCInitStructure); //將設定好的參數初始化給通道1
- TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR1上的預裝載寄存器
- TIM_OCInitStructure.TIM_Pulse=CCR2_Val;
- TIM_OC2Init(TIM3,&TIM_OCInitStructure); //通道2
- TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);
- TIM_ARRPreloadConfig(TIM3,ENABLE); //使能TIM3在ARR上的預裝載寄存器
- TIM_Cmd(TIM3,ENABLE); //使能TIM3的外設
- }
復制代碼
完整的Word格式文檔51黑下載地址:
教學模板-庫函數操作.rar
(460.43 KB, 下載次數: 53)
2018-7-4 03:39 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|