電路原理圖如下:
原理圖.png (167.37 KB, 下載次數(shù): 309)
下載附件
2019-1-5 22:58 上傳
目錄
1 概述 1.1 背景 1.2 設(shè)計的目的與意義 2 方案簡述 3 硬件電路 3.1 單片機的選擇 3.2 MCU模塊電路 3.3 人體紅外檢測模塊電路 3.4 光照強度檢測模塊電路 3.5 照明燈模塊電路 3.6 蜂鳴器模塊電路和心跳燈模塊電路 3.7 模式選擇按鍵和模式指示燈模塊電路 3.8 復(fù)位電路 3.9 USB轉(zhuǎn)串口模塊電路和SWD下載接口電路 3.10 電源模塊電路 4 系統(tǒng)軟件設(shè)計及實現(xiàn) 4.1 主程序流程圖 4.2 手動模式流程圖 4.3 自動模式流程圖 5 調(diào)試 5.1 硬件調(diào)試規(guī)則 5.2 軟件調(diào)試 5.3 調(diào)試的最終結(jié)果 設(shè)計心得 參 考 文 獻 附錄 1 概述
1.1 背景 隨著計算機網(wǎng)絡(luò)、通信、控制等技術(shù)的發(fā)展,智能建筑的發(fā)展越來越迅猛。目前,國內(nèi)大多數(shù)智能建筑存在效率低、能耗高的現(xiàn)象。就智能建筑的照明系統(tǒng)來說,許多地方的燈是從早到晚開著的,不管這些房間或樓道是否有人,或者,當(dāng)自然光照度很好時,不能及時關(guān)閉;當(dāng)自然光照度不能滿足人的需求時,又不能及時打開。這種照明系統(tǒng),不僅造成能源的浪費,而且不能滿足人對照明的需求,同時也給人的視力造成了很壞的影響,F(xiàn)代照明除了滿足人的基本需求,應(yīng)更注重能量的節(jié)省和使用上的便利。要做到合理、經(jīng)濟、節(jié)能,首先應(yīng)采用先進成熟的技術(shù)和產(chǎn)品,如電光源、燈具、照明控制系統(tǒng)。 在大學(xué)校園的建設(shè)中,各大高校意識到了智能照明的重要性。相對商業(yè)樓宇而言,大學(xué)校園里的大功率動力和制冷設(shè)備比重較少,照明燈具則相對比重更多,所以控制教室照明是節(jié)能的關(guān)鍵。使用照明控制系統(tǒng),更能體現(xiàn)其在節(jié)能方面的優(yōu)勢,提高學(xué)校的科學(xué)管理水平,而且還能節(jié)省開支。 1.2 設(shè)計的目的與意義 ① 良好的節(jié)能效果和延長燈具壽命 節(jié)能是照明控制系統(tǒng)的最大優(yōu)勢。傳統(tǒng)的樓宇公共區(qū)域照明工作模式,只能是白天關(guān)燈,晚上開燈。而采用了智能照明控制系統(tǒng)后,可以根據(jù)不同場合、不同的人流量,進行時間段、工作模式的細(xì)分,把不必要的照明關(guān)掉,在需要時自動開啟。同時,系統(tǒng)還能充分利用自然光,自動調(diào)節(jié)室內(nèi)照度?刂葡到y(tǒng)實現(xiàn)了不同工作場合的多種照明工作模式,在保證必要照明的同時,有效減少了燈具的工作時間,節(jié)省了不必要的能源開支,也延長了燈具的壽命。 ② 改善工作環(huán)境,提高工作效率 良好的工作環(huán)境是提高工作效率的一個必要條件。合理地選用光源、燈具及性能優(yōu)越的照明控制系統(tǒng),都能提高照明質(zhì)量。智能照明控制系統(tǒng)具有開關(guān)和調(diào)光兩種控制方法,可以有效地控制各種照明場所的平均照度值,從而提高照度均勻性。同時,系統(tǒng)能根據(jù)不同的時間段,人們的不同需要,自動調(diào)節(jié)照度。 ③ 提高管理水平 智能照明控制系統(tǒng)是以自動控制為主、人工控制為輔的系統(tǒng)。在一般的情況下,不需要有人的參與,照明系統(tǒng)自動實現(xiàn)開關(guān)和調(diào)光功能,既大大減少了管理人員的數(shù)量,也排除了由于人為因素而出現(xiàn)的不定時開關(guān),影響學(xué)校的正常教學(xué)、生活秩序的情況。 ④ 較好的投資收益效果 智能照明控制系統(tǒng)在節(jié)能和節(jié)省燈具使用的同時,有效節(jié)省了電費與管理費用的支出。根據(jù)一般的辦公大樓運營的經(jīng)驗來看,節(jié)能效果能達到40%以上,一般的商場、酒店、地鐵站等節(jié)能效果也能達到25%~30%。
2 方案簡述
針對上述節(jié)能、環(huán)保、健康等問題研究,基于STM32微控制器和PWM調(diào)光的LED燈以STM32F103C8作為主控芯片,設(shè)置了手動控制模式和自動控制模式。在手動控制時,分為五個檔,輸出不同的PWM占空比對LED的電流進行控制,從而實現(xiàn)了對光度的手動調(diào)節(jié)。 在自動控制時,通過STM32F103C8芯片自帶的AD轉(zhuǎn)換不斷檢驗光敏電阻的電壓來間接測量感應(yīng)光度,將電壓和預(yù)設(shè)的閾值進行對比,調(diào)整PWM的占空比對LED的電流進行控制,從而實現(xiàn)了對光度的自動調(diào)節(jié)。 總體框圖如下圖2.1: 
圖2.1總體框圖 在實現(xiàn)主要功能的基礎(chǔ)上,增加了自動模式和手動模式的指示燈以及蜂鳴器的提示功能。選擇自動模式時,自動模式的指示燈亮,選擇手動模式時,手動模式的指示燈亮。同時伴隨著呼吸燈的閃爍。當(dāng)進行關(guān)機的時候,蜂鳴器會發(fā)出聲響,提示操作者系統(tǒng)已經(jīng)關(guān)機。
3 硬件電路
3.1 單片機的選擇 STM32是目前最流行的一款單片機, 現(xiàn)在以STM32F103為代表介紹它的各個參數(shù)。STM32微控制器是把那些作為控制應(yīng)用所必需的基本內(nèi)容都集成在一個尺寸有限的集成電路芯片上。按功能劃分,它由如下功能部件組成,即內(nèi)核,存儲器,時鐘、復(fù)位和電源管理,模數(shù)轉(zhuǎn)換器,DMA控制器,I/O口,定時器,通信接口等。它們都是通過片內(nèi)總線連接而成,對各種功能部件的控制是采用特殊功能寄存器的集中控制方式。其內(nèi)部結(jié)構(gòu)主要有以下幾部分: - 內(nèi)核:ARM32位的CortexTM-M3 CPU,最高72MHz工作頻率,在存儲器的0等待周期訪問時可達1.25DMips/MHz(Dhrystone2.1),單周期乘法和硬件除法。
- 存儲器:從64K或128K字節(jié)的閃存程序存儲器,高達20K字節(jié)的SRAM。
- 時鐘、復(fù)位和電源管理:2.0~3.6V供電和I/O引腳, 上電/斷電復(fù)位(POR/PDR)、可編程電壓監(jiān)測器(PVD), 4~16MHz晶體振蕩器,內(nèi)嵌經(jīng)出廠調(diào)校的8MHz的RC振蕩器,內(nèi)嵌帶校準(zhǔn)的40kHz的RC振蕩器,產(chǎn)生CPU時鐘的PLL,帶校準(zhǔn)功能的32kHz RTC振蕩器。
- 2個12位模數(shù)轉(zhuǎn)換器,1μs轉(zhuǎn)換時間(多達16個輸入通道):轉(zhuǎn)換范圍:0至3.6V,雙采樣和保持功能,溫度傳感器。
- DMA:7通道DMA控制器,支持的外設(shè):定時器、ADC、SPI、USART等。
- 多達80個快速I/O端口:26/37/51/80個I/O口,所有的I/O口可以映像到16個外部中斷,幾乎所有的端口均可容忍5V的信號。
- 多達7個定時器:3個16位定時器,每個定時器有多達4個用于輸入捕獲/輸出比較/PWM或脈沖計數(shù)的通道和增量編碼器輸入,1個16位帶死區(qū)控制和緊急剎車,用于電機控制PWM高級控制定時器,系統(tǒng)時間定時器:24位自減型計數(shù)器。
- 多達9個通信接口:多達3個USART接口(支持ISO7816接口,LIN,IrDA接口和調(diào)制解調(diào)控制),多達2個SPI接口(18M位/秒),CAN接口(2.0B主動),USB2.0全速接口。
STM32具有較強的代表性以及該系列單片機資料較多,本設(shè)計采用STM32F103C8來實現(xiàn)。 3.2 MCU模塊電路 MCU模塊電路在整個控制系統(tǒng)中起到至關(guān)重要的作用,如圖3.2所示。圖中包含了時鐘電路,采用8MHz的晶振和兩個22pF的電容構(gòu)成的振蕩器,為MCU的工作提供有序的時間。電源引腳VBAT、VDD_1、VDD_2、VDD_3和VDDA接的是3.3V的高電平,VSS_1、VSS_2、VSS_3和VSSA接的是GND。 圖中PA1引腳GZ_ADC連接的是光照強度檢測模塊,PA3引腳PERSON_CHECK連接的是人體紅外檢測模塊的PC817的第4引腳,PA9引腳USART1_TX連接的是USB轉(zhuǎn)串口模塊的CH340G的第3引腳,PA10引腳USART1_RX連接的是USB轉(zhuǎn)串口模塊的CH340G的第2引腳,PA11引腳HM_key連接的是模式選擇按鍵模塊的KEY1,PA12引腳AUTO_key連接的是模式選擇按鍵模塊的KEY2,PA13引腳SWDIO連接的是SWD下載接口的第2引腳,PA14引腳SWCLK連接的是SWD下載接口的第3引腳,PA15引腳的BEEP連接的是蜂鳴器模塊,PB3引腳的LED0連接的是心跳燈模塊,PB4引腳的HM_led連接的是模式指示燈模塊的HM_led,PB5引腳的AUTO_led連接的是模式指示燈模塊的AUTO_led,PB7引腳的LEDPWM連接的是照明燈模塊,PB8引腳和PB9引腳暫時沒有用到。 以上提到的各個電路模塊將在下面詳細(xì)介紹。 
圖3.2 MCU模塊電路 3.3 人體紅外檢測模塊電路 采用集成電路BIS0001,該芯片是一款具有較高性能的傳感信號處理集成電路。它配以熱釋電紅外傳感器和少量外接元器件就可構(gòu)成被動式的熱釋電紅外開關(guān)、報警用人體熱釋電傳感器等。它能自動快速開啟各類白熾燈、熒光燈、蜂鳴器、自動門、電風(fēng)扇、烘干機和自動洗手池等裝置,特別適用于企業(yè)、賓館、商場、庫房及家庭的過道、走廊等敏感區(qū)域,或用于安全區(qū)域的自動燈光、照明和報警系統(tǒng)。BIS0001的引腳圖如圖3.3.1: 
圖3.3.1 BIS0001的引腳圖 由BIS0001構(gòu)成的人體紅外檢測電路如圖3.3.2所示:: 圖3.3.2 人體紅外檢測電路 圖3.3.2中,RE200B是熱釋電紅外傳感器,運算放大器OP1將熱釋電紅外傳感器的輸出信號作第一級放大,然后由C9耦合給運算放大器OP2進行第二級放大,再經(jīng)由電壓比較器COP1和COP2構(gòu)成的雙向鑒幅器處理后,檢出有效觸發(fā)信號Vs去啟動延遲時間定時器,輸出信號Vo,Vo引腳的OUT連接PC817的第2引腳,Vo通過PC817對PERSON_CHECK進行控制,PERSON_CHECK連接的是MCU模塊的PA3引腳,由此MCU可以知道此時PERSON_CHECK是高電平還是低電平,從而可以判斷出有人經(jīng)過還是無人經(jīng)過。這個電路模塊就是對人進行檢測。 3.4 光照強度檢測模塊電路 光敏電阻又稱光導(dǎo)管,由于光照產(chǎn)生的載流子都參與導(dǎo)電,在外加電場的作用下作漂移運動,電子奔向電源的正極,空穴奔向電源的負(fù)極,從而使光敏電阻器的阻值迅速下降。光敏電阻器是利用半導(dǎo)體的光電導(dǎo)效應(yīng)制成的一種電阻值隨入射光的強弱而改變的電阻器,又稱為光電導(dǎo)探測器。入射光強,電阻減小,入射光弱,電阻增大。電路如下圖3.4所示: 
圖3.4 光照強度檢測電路 圖3.5 照明燈電路 圖3.4中,光照強度檢測電路由一個光敏電阻和一個普通電阻組成。GZ_ADC是和MCU模塊的PA1引腳連接在一起的,通過檢測外部光照的強弱,從而改變光敏電阻的阻值,使得GZ_ADC的到不同的電平信號,也即是PA1上的電平。光照強時,光敏電阻的阻值小,GZ_ADC得到低電平,光照較弱時,光敏電阻的阻值大,GZ_ADC得到高電平。由于以上現(xiàn)象,可以實現(xiàn)此次設(shè)計的一個必不可少的重要功能:有光的時候,LED燈不亮,無光的時候,LED燈亮。 3.5 照明燈模塊電路 上圖3.5展示了照明燈的驅(qū)動電路,此電路由一個發(fā)光二極管,一個三極管以及三個電阻組成。圖中LEDPWM連接的是MCU模塊的PB7引腳,當(dāng)LEDPWM輸出高電平時,三極管Q4導(dǎo)通,接通發(fā)光二極管DS1,使其發(fā)光,而LEDPWM輸出低電平時,三極管截止,發(fā)光二極管也截止。通過編程可以實現(xiàn)PB7腳輸出不同占空比的PWM波,可以調(diào)節(jié)通過三極管中的電流,從而實現(xiàn)不同亮度的調(diào)節(jié)。這個電路一方面是驅(qū)動LED燈,另一方面實現(xiàn)對LED燈的控制和亮度調(diào)節(jié)。 3.6 蜂鳴器模塊電路和心跳燈模塊電路 蜂鳴器模塊電路如下圖3.6.1所示,蜂鳴器模塊電路主要是由一個蜂鳴器,一個三極管和兩個電阻組成。蜂鳴器模塊電路中的BEEP連接的是MCU模塊的PA15引腳,此電路和照明燈驅(qū)動電路基本類似。當(dāng)三極管基極BEEP輸出高電平時,三極管Q1導(dǎo)通,接通蜂鳴器BEEP發(fā)聲,而三極管基極BEEP輸出低電平時,三極管截止,蜂鳴器BEEP構(gòu)不成完整的回路,不能發(fā)聲。 心跳燈模塊電路如下圖3.6.2所示,心跳燈模塊電路主要是由一個發(fā)光二極管和一個電阻組成。LED0連接的是MCU模塊的PB3引腳。LED0一旦接收到低電平,發(fā)光二極管就接通。所以,可以通過編程對PB3引腳在不同時刻輸出高低電平,從而實現(xiàn)不同情況下的燈亮和燈滅。  圖3.6.1蜂鳴器模塊電路 圖3.6.2心跳燈模塊電路 3.7 模式選擇按鍵和模式指示燈模塊電路 模式選擇按鍵模塊電路如下圖3.7.1所示,模式選擇按鍵模塊電路主要是由兩個開關(guān)和兩個電阻組成。模式選擇按鍵電路中,HM_key連接的是MCU模塊的PA11引腳,AUTO_key連接的是MCU模塊的PA12引腳。PA11和PA12主要是用來檢測HM_key和AUTO_key上是高電平還是低電平,通過軟件編程,當(dāng)PA11引腳得到低電平,也就是KEY1按下時,選擇手動模式;當(dāng)PA12引腳得到高電平,也就是KEY2按下,選擇自動模式。 模式指示燈模塊電路如下圖3.7.1所示,模式指示燈模塊電路主要是由兩個發(fā)光二極管和兩個電阻組成。模式指示燈電路中,HM_led連接的是MCU模塊中的PB4引腳,AUTO_led連接的是MCU模塊的PB5引腳。當(dāng)MCU給PB4或PB5低電平時,模式指示燈電路中的DS3或DS4導(dǎo)通發(fā)光。選擇手動模式時,手動模式指示燈亮,選擇自動模式時,自動模式指示燈亮。 
圖3.7.1 模式選擇按鍵電路 圖3.7.2 模式指示燈電路 3.8 復(fù)位電路 復(fù)位電路是一種用來使電路恢復(fù)到起始狀態(tài)的電路。就像計算器的清零按鈕的作用一樣,以便回到原始狀態(tài),重新進行計算。當(dāng)系統(tǒng)死機或者程序跑飛的時候,通過復(fù)位電路可以使系統(tǒng)恢復(fù)到初始狀態(tài)。所以復(fù)位電路是系統(tǒng)中不可或缺的一部分。復(fù)位方式有手動復(fù)位和上電復(fù)位。 本設(shè)計的手動復(fù)位電路如圖3.8所示,復(fù)位電路由一個按鍵,一個電阻和一個電容組成。圖中的RESET連接的是MCU模塊的NRST引腳,一旦按鍵按下,NRST就收到一個低電平,使MCU模塊復(fù)位,從起始狀態(tài)重新開始執(zhí)行。 
圖3.8 復(fù)位電路 3.9 USB轉(zhuǎn)串口模塊電路和SWD下載接口電路 USB轉(zhuǎn)串口模塊電路如圖3.9.1所示,圖中的USB中的VCC連接的是電源模塊的VUSB,為USB模塊的工作提供電壓,CH340D-和CH340+分別連接CH340G驅(qū)動芯片的第6腳和第5腳,圖中CH340G的TXD和RXD引腳分別連接MCU模塊的USART1_RX和USART1_TX。USB得到的信息經(jīng)過CH340G芯片的處理,通過TXD發(fā)送到MCU,MCU的信息通過RXD傳達給USB實現(xiàn)外設(shè)與MCU的通信。 由一個12MHz的晶振和兩個電容構(gòu)成的振蕩器,為CH340G提供時鐘,讓通信有條不紊的持續(xù)下去。 
圖3.9.1 USB轉(zhuǎn)串口電路 大家比較常用的是Jlink下載器,這種下載器有一個缺點就是使用的Jtag 20PIN接口,太多的PIN會導(dǎo)致一些小型的PCB板很擁擠,也會增加布線的難度。而使用SWD接口下載調(diào)試,只需要要使用4個PIN:GND,RST,SWDIO,SWDCLK ,而且下載速度可以達到10M/s,優(yōu)勢顯而易見。SWD下載接口電路如下圖3.9.2所示,圖中SWDIO和SWCLK分別連接MCU模塊的SWDIO和SWCLK引腳,上位機就可以通過這個下載接口把程序下載到板子里面,實現(xiàn)功能控制。 圖3.9.2 SWD下載接口電路 3.10 電源模塊電路 電源模塊是可以直接貼裝在印刷電路板上的電源供應(yīng)器,其特點是可為專用集成電路(ASIC)、數(shù)字信號處理器 (DSP)、微處理器、存儲器、現(xiàn)場可編程門陣列 (FPGA) 及其他數(shù)字或模擬負(fù)載供電。由于模塊式結(jié)構(gòu)的優(yōu)點甚多,因此模塊電源廣泛用于交換設(shè)備、接入設(shè)備、移動通訊、微波通訊以及光傳輸、路由器等通信領(lǐng)域和汽車電子、航空航天等。 本設(shè)計的電源模塊電路如下圖3.10所示,電源模塊有一塊集成芯片AMS1117,三個電容,一個電阻和一個發(fā)光二極管組成。電源模塊為中整個系統(tǒng)提供合適有效的電壓。當(dāng)通電時,發(fā)光二極管PWR會亮,提示本系統(tǒng)已經(jīng)供電,可以進行其他操作了。 
圖3.10電源模塊電路
4 系統(tǒng)軟件設(shè)計及實現(xiàn)
4.1 主程序流程圖 軟件部分的主要任務(wù)是完成對光照檢測電路和對熱釋電傳感器信號處理電路的輸出信號進行處理;谏鲜龇治,系統(tǒng)軟件設(shè)計流程如圖4.1所示。


圖4.1主程序流程圖 由系統(tǒng)軟件流程圖4.1可以進行邏輯編程,通過編程基本實現(xiàn)了智能燈的各項功能。編程的代碼見附錄。 4.2 手動模式流程圖 

 



圖4.2 手動模式流程圖 4.3 自動模式流程圖

圖4.3 自動模式流程圖
5 調(diào)試
5.1 硬件調(diào)試規(guī)則 硬件調(diào)試是利用基本測試儀器(萬用表、示波器等),檢查用戶系統(tǒng)硬件中存在的故障。 硬件調(diào)試可分為靜態(tài)調(diào)試與動態(tài)調(diào)試兩步進行。 靜態(tài)調(diào)試是在用戶系統(tǒng)未工作時的一種硬件檢測。 第一步:目測。檢查外部的各種元件或者是電路是否有斷點。 第二步:用萬用表測試。先用萬用表復(fù)核目測中有疑問的連接點,再檢測各種電源線與地線之間是否有短路現(xiàn)象。 第三步:加電檢測。給板加電,檢測所有插座或是器件的電源端是否符合要求的值。 第四步是聯(lián)機檢查。因為只有用單片機開發(fā)系統(tǒng)才能完成對用戶系統(tǒng)的調(diào)試。 動態(tài)調(diào)試是在用戶系統(tǒng)工作的情況下發(fā)現(xiàn)和排除用戶系統(tǒng)硬件中存在的器件內(nèi)部故障、器件連接邏輯錯誤等的一種硬件檢查。動態(tài)調(diào)試的一般方法是由近及遠、由分到合。由分到合是指首先按邏輯功能將用戶系統(tǒng)硬件電路分為若干塊,當(dāng)調(diào)試電路時,與該元件無關(guān)的 器件全部從用戶系統(tǒng)中去掉,這樣可以將故障范圍限定在某個局部的電路上。當(dāng)各塊電路無故障后,將各電路逐塊加入系統(tǒng)中,在對各塊電路功能及各電路間可能存在的相互聯(lián)系進行調(diào)試。由分到合的調(diào)試既告完成。由近及遠是將信號流經(jīng)的各器件按照距離單片機的邏輯距離進行由近及遠的分層,然后分層調(diào)試。調(diào)試時,仍采用去掉無關(guān)元件的方法,逐層調(diào)試下去,就會定位故障元件了。 結(jié)果如圖5.1所示: 
圖5.1 硬件調(diào)試 5.2 軟件調(diào)試 軟件調(diào)試是通過對程序的連接、執(zhí)行來發(fā)現(xiàn)程序中存在的語法錯誤與邏輯錯誤并加以排除糾正的過程,也可以通過keil軟件,能大大的減少設(shè)計過程中的錯誤。 正確建立keil工程,在工程中添加各個頭文件和源程序,編寫好自己的程序后進行調(diào)試,找錯誤。如圖5.2.1所示錯誤: 
圖5.2.1 軟件調(diào)試過程中的錯誤 通過查閱資料以及請教他人,發(fā)現(xiàn)這個問題是由于一個宏定義沒有添加,導(dǎo)致出現(xiàn)一個錯誤和這么多的警告。解決辦法如圖5.2.2所示,在Define欄中加上這個宏定義。 
圖5.2.1 軟件調(diào)試解決 5.3 調(diào)試的最終結(jié)果 軟件調(diào)試的最終結(jié)果,如圖5.3.1所示: 
圖5.3.1 軟件調(diào)試結(jié)果 硬件調(diào)試的最終結(jié)果,如圖5.3.2所示: 
圖5.3.2 硬件調(diào)試結(jié)果 設(shè)計心得
基于STM32的智能燈以STM32F103作為主控芯片,設(shè)置了手動控制、自動控制。在手動控制時,輸出不同的PWM占空比實現(xiàn)了對光度的手動調(diào)節(jié)。在自動控制時,通過熱釋電傳感器和處理電路,檢測此時有沒有人;通過檢驗光敏電阻的電壓來間接測量感應(yīng)光度,將電壓和預(yù)設(shè)的閾值進行對比,調(diào)整PWM的占空比實現(xiàn)了對光度的自動調(diào)節(jié)。該LED燈電路簡單,很大程度上節(jié)省電能,延長LED燈壽命,如果要用大量的燈,這種燈便于管理。 在本次課程設(shè)計中,主要有以下體會: 一、掌握了Altium Designer軟件的用法和原理圖的繪制以及PCB的布板; 二、掌握了keil軟件的工程建立,以及對程序的編寫。 三、熟悉了熱釋電繼電器的應(yīng)用。 通過這次課程設(shè)計使我懂得了理論與實際相結(jié)合是很重要的,只有理論知識是遠遠不夠的,只有把所學(xué)的理論知識與實踐相結(jié)合起來,從理論和實踐中得出結(jié)論,才能真正為社會服務(wù),從而提高自己的實際動手潛力和獨立思考的潛力。在設(shè)計的過程中遇到問題,能夠說得是困難重重,主要是對所學(xué)過的知識理解得不夠深刻,掌握得不夠牢固,理論和實踐不能有機的結(jié)合在一起。在設(shè)計中遇到的很多專業(yè)知識問題,在同學(xué)和老師的耐心指導(dǎo)下,最后都迎刃而解了。此次設(shè)計也讓我明白了思路即出路,有什么不懂不明白的地方要及時請教或上網(wǎng)查詢,只要認(rèn)真鉆研,動腦思考,動手實踐,就沒有弄不懂的知識,而且收獲頗豐。 此次課程設(shè)計,學(xué)到了很多課內(nèi)學(xué)不到的東西,比如獨立思考解決問題,查閱資料,出現(xiàn)差錯的隨機應(yīng)變和與人溝通的能力,希望今后高質(zhì)量的完成其他項目。同時,在老師的身上我們學(xué)也到很多實用的知識,對給過我?guī)兔Φ乃型瑢W(xué)和各位指導(dǎo)老師表示衷心的感謝!
main.c文件
#include "main.h"
#define UART_LENTH 1024
char uart1_buff[UART_LENTH]="\0";
void SW_Config(void);
//手動模式的檔位
#define LIGHT_MAX 90
#define LIGHT_MIN 2
#define HM_LEVEL 5
uint8_t now_hmlevel = 0;
#define CHPWM(x) ((LIGHT_MAX - LIGHT_MIN)*x/HM_LEVEL)
//光照的閾值
#define GZ_MAX 3980
#define GZ_MIN 585
#define GZ_ERROR 900
//熱釋電的濾波
#define PERSON_COUNT 20 //判斷n次采樣
uint8_t value = 0;
uint8_t flag_bitled = 1;
uint8_t beep_count = 0;
uint8_t flag_gz = 1;//有光 1 無光 0
uint8_t flag_person = 0;//有人 1 無人 0
uint8_t flag_auto = 1; //默認(rèn)自動模式
int main()
{
uint8_t key = 0xff;//獲取的按鍵值
uint16_t person_count[3]={PERSON_COUNT,0,0};//[0] -- 時間片的長度 [1] -- 高電平的次數(shù) [2] -- 低電平的次數(shù)
uint16_t gz_value = 0; //光敏電阻的值
NVIC_SetPriorityGrouping(5);//設(shè)置中斷優(yōu)先級分組 占先 2 + 次級 2
SW_Config();//SWD模式
USART1_Config(115200);//串口初始化
// USART1_DMATx();
Delay_Init();//延時函數(shù)初始化
LED_Config();//LED初始化
BEEP_Config();//BEEP初始化
KEY_Config(); //按鍵初始化
Person_Config();//熱釋電初始化
TIM4_Config(72,1000,0); //定時器4初始化 產(chǎn)生PWM控制電燈
TIM3_Config(72,600); //定時器3初始化 實現(xiàn)無極調(diào)速 10us的速度
ADC1_Config();//ADC初始化
ADC1_DMAConfig();//DMA初始化
ADC1->CR2 |= (1<<22);//觸發(fā)ADC1轉(zhuǎn)換
LEDx_ON(LED3_PORT,LED3_PIN);//自動模式的指示燈打開
LEDx_OFF(LED2_PORT,LED2_PIN);//手動模式的指示燈關(guān)閉
while(1)
{
if(flag_auto)
{
if(flag_person == 1 && flag_gz == 0)//有人且無光
PWM_ChangeLight(100);//開燈
else
PWM_ChangeLight(0);//關(guān)燈
}
if(timeperson[0] > timeperson[1])//采樣周期
{
if(person_count[0])
{
person_count[0]--;
if(PERSON) person_count[1]++;
else person_count[2]++;
}
else //啟動下一次
{
printf("person_count[1] = %d\r\n",person_count[1]);
printf("person_count[2] = %d\r\n",person_count[2]);
//判斷是否有人
if(person_count[1] > person_count[2]) //有人
{
flag_person = 1;
timeperson[1] = 1000;//檢測到有人之后,采樣變?yōu)?s一次,減少采樣的頻率
}
else
{
timeperson[1] = 20;////檢測到無人之后,采樣變?yōu)?0ms一次,增加采樣的頻率
flag_person = 0;//無人
}
person_count[0] = PERSON_COUNT;
//清零
person_count[1] = 0;
person_count[2] = 0;
}
timeperson[0] = 0;
}
if(timekey[0] > timekey[1])//按鍵
{
key = Get_KeyValue();
switch(key)
{
case 11://關(guān)機
flag_auto = 0; //關(guān)閉自動模式
flag_bitled = 0; LEDx_OFF(LED1_PORT,LED1_PIN);//關(guān)心跳燈
LEDx_OFF(LED3_PORT,LED3_PIN);//自動模式的指示燈關(guān)閉
LEDx_OFF(LED2_PORT,LED2_PIN); //手動模式的指示燈關(guān)閉
beep_count = 4; //響2次
PWM_ChangeLight(0);//燈珠
break;//關(guān)機 -- 關(guān)閉燈 -- 蜂鳴器響 -- 指示燈關(guān)
case 1:
LEDx_OFF(LED3_PORT,LED3_PIN);//自動模式的指示燈關(guān)閉
LEDx_ON(LED2_PORT,LED2_PIN);//手動模式的指示燈打開
flag_bitled = 1; LEDx_ON(LED1_PORT,LED1_PIN);//開心跳燈
now_hmlevel++;//調(diào)節(jié)亮度等級
now_hmlevel%=5;
PWM_ChangeLight(CHPWM(now_hmlevel));
flag_auto = 0;
break;//手動
case 2:
LEDx_ON(LED3_PORT,LED3_PIN);//自動模式的指示燈打開
LEDx_OFF(LED2_PORT,LED2_PIN);//手動模式的指示燈關(guān)閉
flag_bitled = 1; LEDx_ON(LED1_PORT,LED1_PIN);//開心跳燈
//啟動光照+熱釋電
flag_auto = 1;
break;//自動
}
timekey[0] = 0;
}
if(timebeep[0] > timebeep[1])
{
if(beep_count)
{
beep_count--;
BEEP_TOGGLE();//翻轉(zhuǎn)
}
timebeep[0] = 0;
}
if(timeadc[0]>timeadc[1])//ADC開關(guān)量
{
gz_value = Get_GzValue(NULL);
// printf("gz_value =%d\r\n",gz_value);
// printf("flag_gz =%d\r\n",flag_gz);
if(gz_value != 0xffff)//判斷是否獲得數(shù)據(jù)
{
if(gz_value >= (GZ_MAX - GZ_ERROR))//無光
flag_gz = 0;
else
flag_gz = 1;
}
timeadc[0] = 0;
}
if(timeled[0] > timeled[1])//指示燈
{
if(flag_bitled)
LEDx_TOGGLE(LED1_PORT,LED1_PIN);
timeled[0] = 0;
}
}
}
void SW_Config(void)
{
//打開AFIO時鐘
RCC->APB2ENR |= (1<<0);
//SWD模式
AFIO->MAPR &= ~(0x7<<24);
AFIO->MAPR |= (0x2<<24);
}
adc.c文件
#include "adc.h"
#include "stdio.h"
void ADC1_Config(void)
{
//配置ADC1_IN1 -- PA1
//打開時鐘 A端口+ADC1
RCC->APB2ENR |= (1<<2)|(1<<9);
//PA1配置為模擬輸入
GPIOA->CRL &= ~(0xF<<4);
//配置ADC1_IN1
//1.ADCCLK -- PCLK/8 -- 84/8
RCC->CFGR &= ~(0x3<<14);
RCC->CFGR |= (0x3<<14);
//2.配置規(guī)則組的轉(zhuǎn)換長度+IN1放在第一位
ADC1->SQR1 &= ~(0xf<<20);
ADC1->SQR1 |= (0x0<<20);//n次轉(zhuǎn)換
//規(guī)則組第1位置
ADC1->SQR3 &= ~(0x1f<<0);
ADC1->SQR3 |= (0x1<<0);
//3.配置轉(zhuǎn)換模式:單次/連續(xù) 掃描/不連續(xù)
//單次/連續(xù) -- ADC_CR2 CONT位
ADC1->CR2 |= (1<<1);
//ADC1->CR2 &= ~(1<<1);
//掃描 -- ADC_CR1 SCAN
ADC1->CR1 &= ~(1<<8);//不掃描
//ADC1->CR1 |= (1<<8);//掃描
//4.設(shè)置采樣速率 3+12 = 15 ADCCLK
//設(shè)置采樣速率:ADC_IN1 -- ADC_SMPR2 3個周期
ADC1->SMPR2 &= ~(0x7<<3);
ADC1->SMPR2 |= (0x7<<3);
//5.禁止不連續(xù)采樣
ADC1->CR1 &= ~(1<<11);
//6.選擇觸發(fā)類型 軟件觸發(fā)
ADC1->CR2 |= (0x1<<20);
ADC1->CR2 |= (0x7<<17);
//7.設(shè)置數(shù)據(jù)對齊 -- 右對齊
ADC1->CR2 &= ~(1<<11);
//復(fù)位校準(zhǔn)
ADC1->CR2 |= (1<<3);
while((ADC1->CR2 & (1<<3)) == 1);
//校準(zhǔn)
ADC1->CR2 |= (1<<2);
while((ADC1->CR2 & (1<<2)) == 1);
//8.啟動ADC ADC_CR2 -- ADON
ADC1->CR2 |= (1<<0);
}
#define ADC_A(x) (3.3*x/4096)
u16 dma_adcbuff[30];
void ADC1_DMAConfig(void)
{
//時鐘打開
RCC->AHBENR |= (1<<0);
//ADC1配置DMA模式
ADC1->CR2 |= (1<<8);
//關(guān)閉DMA1
DMA1_Channel1->CCR &= ~(1<<0);
//清相關(guān)標(biāo)志位
DMA1->IFCR |= (1<<0)|(1<<1)|(1<<2)|(1<<3);
//設(shè)置源和目標(biāo) -- 源 -- 外設(shè)(ADC_DR) 目標(biāo) -- 存儲器(dma_adcbuff)
DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;
DMA1_Channel1->CMAR = (uint32_t)dma_adcbuff;
//配置傳輸數(shù)據(jù)的總數(shù)
DMA1_Channel1->CNDTR = sizeof(dma_adcbuff)/sizeof(dma_adcbuff[0]);
//優(yōu)先級 -- 高
DMA1_Channel1->CCR &= ~(0x3<<12);
DMA1_Channel1->CCR |= (0x2<<12);
//方向:外設(shè)到存儲器
DMA1_Channel1->CCR &= ~(0x1<<4);
//外設(shè)不增量
DMA1_Channel1->CCR &= ~(0x1<<6);
//存儲器不增量
DMA1_Channel1->CCR |= (0x1<<7);
//外設(shè)數(shù)據(jù)的寬度
DMA1_Channel1->CCR &= ~(0x3<<8);
DMA1_Channel1->CCR |= (0x1<<8);
//存儲器數(shù)據(jù)的寬度
DMA1_Channel1->CCR &= ~(0x3<<10);
DMA1_Channel1->CCR |= (0x1<<10);
//循環(huán)模式
DMA1_Channel1->CCR |= (0x1<<5);
//啟動DMA1_1
DMA1_Channel1->CCR |= (0x1<<0);
}
//通過DMA處理數(shù)據(jù) -- 濾波
//0xffff -- 數(shù)據(jù)沒有獲得
uint16_t Get_GzValue(uint16_t *pdata)
{
uint16_t value = 0XFFFF;
uint32_t i = 0;
uint32_t lenth = sizeof(dma_adcbuff)/sizeof(dma_adcbuff[0]);
uint32_t sum = 0;
if(DMA1->ISR &(1<<1))//DMA傳輸完成
{
//清標(biāo)志位
DMA1->IFCR |= (1<<1);
for(i=0;i<lenth;i++)
sum+= dma_adcbuff[ i];
value = sum/lenth;
if(pdata != NULL)
*pdata = value;
}
return value;
}
beep.c文件
#include "beep.h"
void BEEP_Config(void)
{
//打開時鐘 -- PA15
RCC->APB2ENR |= (1<<2);
//配置PA8-- 通用推挽輸出 速度50MHz 無上拉下拉
GPIOA->CRH &= ~((0xf<<28));
GPIOA->CRH |= (0x3<<28);
//關(guān)閉蜂鳴器
BEEP(0);
}
delay.c文件
#include "delay.h"
void Delay_nus(uint32_t time)
{
while(time--)
{
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
}
}
#define DELAY_1US 72
#define DELAY_1MS 72000
uint32_t runtime = 0;//保存當(dāng)前系統(tǒng)運行的時間 單位ms
vu32 timeled[2] = {0,1000};//初始值 延時值
vu32 timebeep[2] = {0,100};
vu32 timekey[2] = {0,8};
vu32 timeusart1[2] = {0,100};
vu32 timeadc[2] = {0,1000};
vu32 timeperson[2] = {0,100};
void Delay_Init(void)
{
if(SysTick_Config(DELAY_1MS) == 1)//初始化滴答定時器
{
while(1);
}
TIM2_Config(1,72);
}
void SysTick_Handler(void)
{
runtime++;//每1ms加1次
timeled[0]++;
timebeep[0]++;
timekey[0]++;
timeusart1[0]++;
timeadc[0]++;
timeperson[0]++;
}
void Delay_ms(uint32_t time)
{
uint32_t time1 = runtime;//保存當(dāng)前的系統(tǒng)時間
while((runtime - time1 )< time);
}
void TIM2_Config(uint16_t psc,uint16_t reload)
{
//打開時鐘 TIM2
RCC->APB1ENR |= (1<<0);
//初始化TIM7
//分頻
TIM2->PSC = psc-1;
//計數(shù)器清零
TIM2->CNT = 0;
//重裝載初始化
TIM2->ARR = reload-1;
//TIM6 CR1 -- 使能(定時器、重裝載值緩存區(qū)、事件)
TIM2->CR1 = 0;
//中斷配置
//中斷打開
TIM2->DIER |= (1<<0);
//設(shè)置中斷通道使能以及優(yōu)先級
NVIC_SetPriority(TIM2_IRQn,0xf);//2 2 11 11
NVIC_DisableIRQ(TIM2_IRQn);
//定時打開
TIM2->CR1 &= ~(1<<0);
}
//1us 進入中斷一次
uint32_t run_ustime = 0;
void TIM2_IRQHandler(void)
{
TIM2->SR &= ~(1<<0);//清標(biāo)志位
if(run_ustime > 0) run_ustime--;
}
void Delay_us(uint32_t time)
{
run_ustime = time;
TIM2->CNT = 0;//計數(shù)器清零
TIM2->CR1 |= (1<<0);//定時器打開
while(run_ustime); //延時等待
TIM2->CR1 &= ~(1<<0);//關(guān)閉定時器
}
key.c文件
#include "key.h"
#include "delay.h"
//KEY1 -- PA11 KEY2 -- PA12
void KEY_Config(void)
{
//打開端口時鐘
RCC->APB2ENR |= (1<<2);
//配置為輸入模式 -- 浮空輸入
GPIOA->CRH &= ~((0xf<<12)|(0xf<<16));
GPIOA->CRH |= (0x4<<12)|(0x4<<16);
}
uint8_t Get_KeyValue(void)
{
static uint32_t count1 = 0;//檢測到低電平的次數(shù)
static uint32_t count2 = 0;//檢測到低電平的次數(shù)
if(KEY1 == 0)
{
count1++;
if(count1 > 120)
{
count1 = 0;
return 11;
}
}
else if(count1 > 15 && count1 <50)
{
count1 = 0;
return 1;
}
else //濾波
count1 = 0;
if(KEY2 == 0) count2++;
else if(count2 > 15)
{
count2 = 0;
return 2;
}
else //濾波
count2 = 0;
return 0xff;
}
led.c文件
#include "led.h"
#include "delay.h"
#include "bitband.h"
void LED_Config(void)
{
//打開LED1 2 3燈的時鐘 -- B
RCC->APB2ENR |= sbit(3);
//配置PB3 4 5-- 通用推挽輸出 速度50MHz 無上拉下拉
//通用輸出 -- 清零賦值
GPIOB->CRL &= ~((0xf<<12)|(0xf<<16)|(0xf<<20));
GPIOB->CRL |= (0x3<<12)|(0x3<<16)|(0x3<<20);
//滅燈
LEDx_OFF(LED1_PORT,LED1_PIN);
LEDx_OFF(LED2_PORT,LED2_PIN);
LEDx_OFF(LED3_PORT,LED3_PIN);
}
light.c文件
#include "light.h"
void TIM3_Config(uint16_t psc,uint16_t reload)
{
//打開時鐘 TIM3
RCC->APB1ENR |= (1<<1);
//初始化TIM3
//分頻
TIM3->PSC = psc-1;
//計數(shù)器清零
TIM3->CNT = 0;
//重裝載初始化
TIM3->ARR = reload-1;
//TIM3 CR1 -- 使能(定時器、重裝載值緩存區(qū)、事件)
TIM3->CR1 = 0;
//中斷配置
//中斷打開
TIM3->DIER |= (1<<0);
//設(shè)置中斷通道使能以及優(yōu)先級
NVIC_SetPriority(TIM3_IRQn,0xf);//2 2 11 11
NVIC_EnableIRQ(TIM3_IRQn);
//定時關(guān)閉
TIM3->CR1 &= ~(1<<0);
}
uint16_t new_ccr = 0;
void TIM3_IRQHandler(void)
{
int offset = new_ccr - TIM4->CCR2;//求出偏差值
TIM3->SR &= ~(1<<0);//清標(biāo)志位
if(TIM4->CCR2 <= TIM4->ARR && TIM4->CCR2 >= 0)//
{
//分為三種情況
if(offset == 0) TIM3->CR1 &= ~(1<<0);//關(guān)閉定時器,不修改CCR值
else if(offset > 0) TIM4->CCR2 += 1;
else if(offset < 0) TIM4->CCR2 -= 1;
}
}
//參數(shù):pwmvalue 0~100
void PWM_ChangeLight(uint32_t pwmvalue)
{
//把PWMValue轉(zhuǎn)換為CCR寄存器的值 pwmvalue(0~100) -- CCR(0~ARR重裝載值)
uint16_t arr = TIM4->ARR;
//計算出要修改的PWM波的占空比所對應(yīng)的CCR寄存器值
new_ccr = arr*pwmvalue/100;
//啟動一個定時器去實現(xiàn)無極調(diào)光
TIM3->CR1 |= (1<<0);
}
person.c文件
#include "person.h"
void Person_Config(void)
{
//打開端口時鐘
RCC->APB2ENR |= (1<<2);
//配置為輸入模式 -- 浮空輸入
GPIOA->CRL &= ~((0xf<<12));
GPIOA->CRL |= (0x4<<12);
}
tim.c文件
#include "tim.h"
//1KHz -- 1ms -- 72 1000 500
//PB7 -- TIM_CH2 -- 復(fù)用
void TIM4_Config(uint16_t psc,uint16_t arr,uint16_t ccr)
{
//B端口時鐘 PB7 TIM4時鐘打開
RCC->APB2ENR |= (1<<3);
RCC->APB1ENR |= (1<<2);
//PB7配置為復(fù)用功能
GPIOB->CRL &= ~((0xf<<28));
GPIOB->CRL |= (0xb<<28);
//TIM4的定時時長 -- 1ms
TIM4->CNT = 0;
TIM4->PSC = psc-1;
TIM4->ARR = arr-1;
TIM4->CCR2 = ccr;//比較寄存器值
//ARR的預(yù)裝載 -- CR1
TIM4->CR1 = 0;
//輸出模式、CCR預(yù)裝載、快速使能
TIM4->CCMR1 = 0;
//PWM1模式
TIM4->CCMR1 &= ~(0x7<<12);
TIM4->CCMR1 |= (0x6<<12);
//有效電平高電平 使能OC輸出
TIM4->CCER = 0;
TIM4->CCER |= (1<<4);
//開啟定時器
TIM4->CR1 |= (1<<0);
}
usart.c文件
#include "usart.h"
#include "beep.h"
#include "led.h"
#include "string.h"
#include "stdio.h"
void USART1_Config(uint32_t brr)
{
float div;//分頻數(shù)
uint32_t div_m;//整數(shù)部分
uint32_t div_f;//小數(shù)部分
//A端口時鐘 PA9 PA10 USART1時鐘打開
RCC->APB2ENR |= (1<<2)|(1<<14);
//PA9 PA10配置為復(fù)用功能
GPIOA->CRH &= ~((0xf<<4)|(0xf<<8));
GPIOA->CRH |= (0xb<<4);
GPIOA->CRH |= (0x4<<8);
//配置串口 232協(xié)議:字長 + 奇偶校驗使能
USART1->CR1 = 0;
//停止位 1位
USART1->CR2 &= ~(0x3<<12);
//配置全雙工模式:接收發(fā)送打開
USART1->CR1 |= (0x1<<2)|(0x1<<3);
//配置波特率
div = 72000000.0/(16.0*brr);
div_m = (uint32_t)div;
div_f = (uint32_t)((div-div_m)*16);
USART1->BRR = div_m<<4|div_f;
//使能串口1
USART1->CR1 |= (1<<13);
}
void USART1_NVICConfig(void)
{
//接收中斷使能
USART1->CR1 |= (1<<5);
//NVIC
NVIC_SetPriority(USART1_IRQn,1);//占先 0 次級 1
NVIC_EnableIRQ(USART1_IRQn);
}
void USART1_Echo(void)
{
uint8_t data;
//接收數(shù)據(jù) -- 判斷數(shù)據(jù)是否到來(SR) -- 阻塞
while((USART1->SR & (1<<5)) == 0);
//保存數(shù)據(jù)
data = USART1->DR;
//發(fā)送數(shù)據(jù) -- 等待上次發(fā)送完成(SR -- 7/6)
while((USART1->SR & (1<<7)) == 0);
USART1->DR = data;
}
uint8_t USART1_RecvData(void)
{
//uint8_t data;
//接收數(shù)據(jù) -- 判斷數(shù)據(jù)是否到來(SR) -- 阻塞
while((USART1->SR & (1<<5)) == 0);
//保存數(shù)據(jù)
//data = USART1->DR;
return USART1->DR;
}
void USART1_SendData(uint8_t data)
{
//發(fā)送數(shù)據(jù) -- 等待上次發(fā)送完成(SR -- 7/6)
while((USART1->SR & (1<<7)) == 0);
USART1->DR = data;
}
void USART1_SendString(uint8_t *p)
{
while(*p)
{
USART1_SendData(*p++);
}
}
int fputc(int c, FILE *stream)
{
USART1_SendData((uint8_t)c);
return c;
}
uint8_t dmabuff[]="深圳信盈達鄭州分公司\r\n";
void USART1_DMATx(void)
{
//時鐘打開
RCC->AHBENR |= (1<<0);
//USART1_Tx配置DMA模式
USART1->CR3 |= (1<<7);
//關(guān)閉DMA1
DMA1_Channel4->CCR &= ~(1<<0);
//清相關(guān)標(biāo)志位
DMA1->IFCR |= (1<<12)|(1<<13)|(1<<14)|(1<<15);
//設(shè)置源和目標(biāo) -- 源 -- 外設(shè)(USART1_DR) 目標(biāo) -- 存儲器(dma_buff)
DMA1_Channel4->CPAR = (uint32_t)&USART1->DR;
DMA1_Channel4->CMAR = (uint32_t)dmabuff;
//配置傳輸數(shù)據(jù)的總數(shù)
DMA1_Channel4->CNDTR = sizeof(dmabuff)/sizeof(dmabuff[0]);
//優(yōu)先級 -- 高
DMA1_Channel4->CCR &= ~(0x3<<12);
DMA1_Channel4->CCR |= (0x2<<12);
//方向:存儲器到外設(shè)
DMA1_Channel4->CCR |= (0x1<<4);
//外設(shè)不增量
DMA1_Channel4->CCR &= ~(0x1<<6);
//存儲器增量
DMA1_Channel4->CCR |= (0x1<<7);
//外設(shè)數(shù)據(jù)的寬度
DMA1_Channel4->CCR &= ~(0x3<<8);
DMA1_Channel4->CCR |= (0x0<<8);
//存儲器數(shù)據(jù)的寬度
DMA1_Channel4->CCR &= ~(0x3<<10);
DMA1_Channel4->CCR |= (0x0<<10);
//循環(huán)模式
DMA1_Channel4->CCR &= ~(0x1<<5);
//關(guān)閉DMA1_4
DMA1_Channel4->CCR &= ~(0x1<<0);
}
////void USART1_DMATxTest(void)
////{
//// //關(guān)閉數(shù)據(jù)流
//// DMA2_Stream7->CR &=~(1<<0);
//// //清相關(guān)標(biāo)志位
//// DMA2->HIFCR |= (1<<22)|(1<<24)|(1<<25)|(1<<26)|(1<<27);
//// //確定傳輸?shù)拇螖?shù)
//// DMA2_Stream7->NDTR = sizeof(dmabuff)/sizeof(dmabuff[0]);
//// //啟動DMA
//// DMA2_Stream7->CR |= (1<<0);
////}
////0 -- 失敗 1 -- 成功
void Uart1_DMA_Printf(char *p,uint32_t lenth)
{
//關(guān)閉DMA1
DMA1_Channel4->CCR &= ~(1<<0);
//清相關(guān)標(biāo)志位
DMA1->IFCR |= (1<<12)|(1<<13)|(1<<14)|(1<<15);
//修改存儲器地址
DMA1_Channel4->CMAR = (uint32_t)p;
//確定傳輸?shù)拇螖?shù)
DMA1_Channel4->CNDTR = lenth;
//啟動DMA
DMA1_Channel4->CCR |= (0x1<<0);
}
完整的Word格式文檔51黑下載地址:
基于STM32的智能燈.docx
(1.51 MB, 下載次數(shù): 575)
2019-1-5 22:57 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|