電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程-課件 【ch11】STM32單片機(jī)的使用_第1頁
電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程-課件 【ch11】STM32單片機(jī)的使用_第2頁
電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程-課件 【ch11】STM32單片機(jī)的使用_第3頁
電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程-課件 【ch11】STM32單片機(jī)的使用_第4頁
電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程-課件 【ch11】STM32單片機(jī)的使用_第5頁
已閱讀5頁,還剩40頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第十一章

STM32單片機(jī)的使用電子設(shè)計(jì)基礎(chǔ)與創(chuàng)新實(shí)踐教程01STM32單片機(jī)概述PARTONESTM32系列MCU是意法半導(dǎo)體(ST)公司推出的基于ARM內(nèi)核的32位微控制器,包括主流MCU、高性能MCU、超低功耗MCU、無線MCU等。

以STM32F407xx為例,它包含高速存儲(chǔ)器(1MB的Flash,最高可達(dá)192KB的SRAM、最高可達(dá)4KB的備份SRAM)、3個(gè)12位ADC、2個(gè)DAC、2個(gè)通用32位定時(shí)/計(jì)數(shù)器、1個(gè)真實(shí)隨機(jī)數(shù)發(fā)生器(RNG),并且提供各類標(biāo)準(zhǔn)及高級(jí)通信接口(最多3個(gè)IIC、3個(gè)SPI/IIS接口、4個(gè)USART接口、2個(gè)CAN總線接口、1個(gè)SDIO/MMC接口、1個(gè)全速USBOTG接口和1個(gè)高速USBOTG接口、網(wǎng)口及相機(jī)接口等);在-40~+105℃的溫度范圍內(nèi)工作,電源電壓為1.8~3.6V,當(dāng)設(shè)備使用外部電源監(jiān)控器在0~70℃的溫度范圍內(nèi)運(yùn)行時(shí),電源電壓可降至1.7V,并且擁有一套全面的節(jié)能模式,以滿足低功耗應(yīng)用設(shè)計(jì)要求。STM32系列單片機(jī)介紹及選型

STM32系列單片機(jī)引腳定義我們可以通過數(shù)據(jù)手冊(cè)(Datasheet)及參考手冊(cè)獲取引腳定義,其引腳定義的說明如圖所示。STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射1.STM32F407xx總線架構(gòu)STM32F407xx存儲(chǔ)系統(tǒng)由32位多層AHB總線矩陣組成,連接了:(1)8個(gè)主控單元。? I-總線,D-總線和S-總線;? DMA1存儲(chǔ)器總線;? DMA2存儲(chǔ)器總線;? DMA3存儲(chǔ)器總線;? 以太網(wǎng)DMA總線;? USBOTGHSDMA總線。(2)7個(gè)從單元。? 內(nèi)部FlashICODE總線;? 內(nèi)部FlashDCODE總線;? 主要內(nèi)部SRAM1(112KB);? 輔助內(nèi)部SRAM2(16KB);? 輔助內(nèi)部SRAM3(64KB);? AHB1外設(shè);? AHB2外設(shè);? FSMC。2.STM32F407xx存儲(chǔ)器映射存儲(chǔ)器本身不具有地址,給存儲(chǔ)器分配地址的過程就是存儲(chǔ)器映射,STM32F407xx的存儲(chǔ)器映射。STM32的地址線是32位的,對(duì)應(yīng)4GB的存儲(chǔ)空間,被分為8塊(Block),每塊為512MB。我們重點(diǎn)介紹Block2,它被分配給外設(shè),根據(jù)總線分為APB1、APB2、AHB1、AHB2,具體劃分如表11-1-3所示。它以4字節(jié)(32位)為一個(gè)寄存器單元,C語言中通過指針來訪問這些寄存器。STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射3.STM32F407外設(shè)地址映射①總線:STM32F407連接有4條總線,不同總線掛載不同的外設(shè),APB掛載低速外設(shè),AHB掛載高速外設(shè)。總線的最低地址稱為該總線的基地址,總線基地址如表所示。②外設(shè):總線上掛著各種各樣的外設(shè),這些外設(shè)也被分配不同的地址,具體外設(shè)的邊界地址參考STM32F407參考手冊(cè)中的存儲(chǔ)器映射部分,以GPIO為例,GPIO是掛在AHB1總線上的外設(shè),其基地址如表所示。③外設(shè)寄存器:每個(gè)外設(shè)都有多個(gè)不同功能的寄存器,每個(gè)寄存器占4字節(jié)(32位),每個(gè)寄存器都會(huì)被分配不同的地址,以GPIOF端口為例,其寄存器地址如表所示,編寫C語言程序時(shí)通過“外設(shè)基地址+偏移”來描述寄存器的地址。STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射通過“AHB1基地址+相對(duì)AHB1總線基地址的偏移+相對(duì)GPIOF地址的偏移”可以獲取GPIOF的相關(guān)寄存器地址,例如0x40020000+0x00001400+0x00=0x40021400,可獲取GPIOF_MODER的地址。4.C語言對(duì)寄存器的封裝①封裝總線和外設(shè)基地址。為方便理解和記憶,通過宏定義方式進(jìn)行封裝。程序清單11-1-1 stm32f4xx.h程序/*!<Defines'read/write'permissions*/#define__IOvolatile

/*!<Peripheralbaseaddressinthealiasregion*/#definePERIPH_BASE((uint32_t)0x40000000)/*!<Peripheralmemorymap*/#defineAPB1PERIPH_BASEPERIPH_BASE#defineAPB2PERIPH_BASE(PERIPH_BASE+0x00010000)#defineAHB1PERIPH_BASE(PERIPH_BASE+0x00020000)#defineAHB2PERIPH_BASE(PERIPH_BASE+0x10000000)/*!<AHB1peripherals*/#defineGPIOA_BASE(AHB1PERIPH_BASE+0x0000)#defineGPIOB_BASE(AHB1PERIPH_BASE+0x0400)#defineGPIOC_BASE(AHB1PERIPH_BASE+0x0800)#defineGPIOD_BASE(AHB1PERIPH_BASE+0x0C00)#defineGPIOE_BASE(AHB1PERIPH_BASE+0x1000)#defineGPIOF_BASE(AHB1PERIPH_BASE+0x1400)#defineGPIOG_BASE(AHB1PERIPH_BASE+0x1800)#defineGPIOH_BASE(AHB1PERIPH_BASE+0x1C00)#defineGPIOI_BASE(AHB1PERIPH_BASE+0x2000)#defineGPIOJ_BASE(AHB1PERIPH_BASE+0x2400)#defineGPIOK_BASE(AHB1PERIPH_BASE+0x2800)②封裝寄存器列表。GPIOA~GPIOK都有一組功能相同的寄存器,它們只是地址不同,為方便訪問,通過結(jié)構(gòu)體進(jìn)行封裝。程序清單11-1-2 stm32f4xx.h程序STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射typedefstruct{__IOuint32_tMODER;/*!<GPIOportmoderegister,Addressoffset:0x00*/__IOuint32_tOTYPER;/*!<GPIOportoutputtyperegister,Addressoffset:0x04*/__IOuint32_tOSPEEDR;/*!<GPIOportoutputspeedregister,Addressoffset:0x08*/__IOuint32_tPUPDR;/*!<GPIOportpull-up/pull-downregister,Addressoffset:0x0C*/__IOuint32_tIDR;/*!<GPIOportinputdataregister,Addressoffset:0x10*/__IOuint32_tODR;/*!<GPIOportoutputdataregister,Addressoffset:0x14*/__IOuint16_tBSRRL;/*!<GPIOportbitset/resetlowregister,Addressoffset:0x18*/__IOuint16_tBSRRH;/*!<GPIOportbitset/resethighregister,Addressoffset:0x1A*/__IOuint32_tLCKR;/*!<GPIOportconfigurationlockregister,Addressoffset:0x1C*/__IOuint32_tAFR[2];/*!<GPIOalternatefunctionregisters,Addressoffset:0x20-0x24*/}GPIO_TypeDef;這段代碼用typedef關(guān)鍵字聲明了名為GPIO_TypeDef的結(jié)構(gòu)體類型,內(nèi)有10個(gè)變量。結(jié)構(gòu)體內(nèi)變量的存儲(chǔ)空間是連續(xù)的,32位變量占4字節(jié),16位變量占2字節(jié)。結(jié)構(gòu)體各個(gè)變量相對(duì)結(jié)構(gòu)體首地址的偏移與GPIO各個(gè)寄存器地址的偏移一致,只要給結(jié)構(gòu)體設(shè)置好首地址,就可以確定各個(gè)寄存器的地址,然后通過結(jié)構(gòu)體指針訪問寄存器。程序清單11-1-3 stm32f4xx.h程序STM32系列單片機(jī)總線架構(gòu)及存儲(chǔ)器映射/*使用GPIO_TypeDef把地址強(qiáng)制轉(zhuǎn)換成指針*/#defineGPIOA((GPIO_TypeDef*)GPIOA_BASE)#defineGPIOB((GPIO_TypeDef*)GPIOB_BASE)#defineGPIOC((GPIO_TypeDef*)GPIOC_BASE)#defineGPIOD((GPIO_TypeDef*)GPIOD_BASE)#defineGPIOE((GPIO_TypeDef*)GPIOE_BASE)#defineGPIOF((GPIO_TypeDef*)GPIOF_BASE)#defineGPIOG((GPIO_TypeDef*)GPIOG_BASE)#defineGPIOH((GPIO_TypeDef*)GPIOH_BASE)#defineGPIOI((GPIO_TypeDef*)GPIOI_BASE)#defineGPIOJ((GPIO_TypeDef*)GPIOJ_BASE)#defineGPIOK((GPIO_TypeDef*)GPIOK_BASE)#defineCRC((CRC_TypeDef*)CRC_BASE)#defineRCC((RCC_TypeDef*)RCC_BASE)這段代碼使用GPIO_TypeDef把地址強(qiáng)制轉(zhuǎn)換成指針,這樣可以使用定義好的宏直接訪問GPIOF端口的寄存器。時(shí)鐘是單片機(jī)的“心臟”,是單片機(jī)的驅(qū)動(dòng)源,由于STM32有很多外設(shè),每個(gè)外設(shè)需要的時(shí)鐘頻率不同,所以需要多個(gè)時(shí)鐘源。使用任何一個(gè)外設(shè)都必須打開相應(yīng)的時(shí)鐘,當(dāng)不使用某個(gè)外設(shè)的時(shí)候,就把它的時(shí)鐘關(guān)掉,從而降低系統(tǒng)的功耗。STM32F407xx系列單片機(jī)時(shí)鐘樹如圖所示,它有5個(gè)重要的時(shí)鐘源:高速內(nèi)部時(shí)鐘(HSI)、高速外部時(shí)鐘(HSE)、低速內(nèi)部時(shí)鐘(LSI)、低速外部時(shí)鐘(LSE)、鎖相環(huán)時(shí)鐘(PLL)。(1)HSI是一個(gè)RC振蕩電路,頻率為16MHz,可以作為系統(tǒng)時(shí)鐘或者PLL的輸入。(2)HSE可以外接晶振或者外部時(shí)鐘,頻率范圍為4MHz~26MHz,可以作為系統(tǒng)時(shí)鐘或者PLL的輸入。(3)LSI是一個(gè)RC振蕩電路,頻率為32kHz,為看門狗和自動(dòng)喚醒單元提供時(shí)鐘。(4)LSE外接頻率為32.768kHz的晶振,主要作為RTC的時(shí)鐘源。(5)STM32F407xx系列單片機(jī)有兩個(gè)PLL:①主PLL由HSE或者HSI提供時(shí)鐘信號(hào),并具有兩個(gè)不同的輸出時(shí)鐘。第一個(gè)輸出PLLCLK用于生成高速的系統(tǒng)時(shí)鐘(最高168MHz);第二個(gè)輸出PLL48CK用于生成USBOTGFS的時(shí)鐘(48MHz)、隨機(jī)數(shù)發(fā)生器的時(shí)鐘和SDIO時(shí)鐘。②專用PLL(PLLIISCLK)用于生成精確時(shí)鐘,從而在IIS接口實(shí)現(xiàn)高品質(zhì)音頻性能。STM32系列單片機(jī)時(shí)鐘控制STM32系列單片機(jī)時(shí)鐘控制時(shí)鐘設(shè)置函數(shù)如下。程序清單11-1-4 sys.c程序//時(shí)鐘設(shè)置函數(shù)//Fvco=Fs*(plln/pllm);//Fsys=Fvco/pllp=Fs*(plln/(pllm*pllp));//Fusb=Fvco/pllq=Fs*(plln/(pllm*pllq));//Fvco:VCO頻率//Fsys:系統(tǒng)時(shí)鐘頻率//Fusb:USB,SDIO,RNG等的時(shí)鐘頻率//Fs:PLL輸入時(shí)鐘頻率,可以是HSI,HSE等//plln:主PLL倍頻系數(shù)(PLL倍頻),取值范圍:64~432//pllm:主PLL和音頻PLL分頻系數(shù)(PLL之前的分頻),取值范圍:2~63//pllp:系統(tǒng)時(shí)鐘的主PLL分頻系數(shù)(PLL之后的分頻),取值范圍:2,4,6,8.(僅限這4個(gè)值!)STM32系列單片機(jī)時(shí)鐘控制//pllq:USB/SDIO/隨機(jī)數(shù)發(fā)生器等的主PLL分頻系數(shù)(PLL之后的分頻),取值范圍:2~15//外部晶振頻率為8MHz的時(shí)候,推薦值:plln=336,pllm=8,pllp=2,pllq=7.//得到:Fvco=8*(336/8)=336MHz//Fsys=336/2=168MHz//Fusb=336/7=48MHz//返回值:0,成功;1,失敗。u8Sys_Clock_Set(u32plln,u32pllm,u32pllp,u32pllq){u16retry=0;u8status=0;RCC->CR|=1<<16; //HSE開啟while(((RCC->CR&(1<<17))==0)&&(retry<0X1FFF))retry++;//等待HSERDYif(retry==0X1FFF)status=1; //HSE無法就緒else{RCC->APB1ENR|=1<<28; //電源接口時(shí)鐘使能PWR->CR|=3<<14; //高性能模式,時(shí)鐘頻率可達(dá)168MHzRCC->CFGR|=(0<<4)|(5<<10)|(4<<13);//HCLK不分頻;APB14分頻;APB22分頻RCC->CR&=~(1<<24); //關(guān)閉主PLLRCC->PLLCFGR=pllm|(plln<<6)|(((pllp>>1)-1)<<16)|(pllq<<24)|(1<<22); //配置主PLL,PLL時(shí)鐘源來自HSESTM32系列單片機(jī)時(shí)鐘控制RCC->CR|=1<<24; //打開主PLLwhile((RCC->CR&(1<<25))==0); //等待PLL準(zhǔn)備好FLASH->ACR|=1<<8; //指令預(yù)取使能FLASH->ACR|=1<<9; //指令cache使能FLASH->ACR|=1<<10; //數(shù)據(jù)cache使能FLASH->ACR|=5<<0; //5個(gè)CPU等待周期RCC->CFGR&=~(3<<0); //清零RCC->CFGR|=2<<0; //選擇主PLL作為系統(tǒng)時(shí)鐘while((RCC->CFGR&(3<<2))!=(2<<2));//等待主PLL作為系統(tǒng)時(shí)鐘成功}returnstatus;}在Sys_Clock_Set函數(shù)中,設(shè)置了APB1為4分頻,APB2為2分頻,HCLK不分頻,同時(shí)選擇PLLCLK作為系統(tǒng)時(shí)鐘。該函數(shù)有4個(gè)參數(shù),具體意義和計(jì)算方法見函數(shù)前面的說明。一般推薦設(shè)置為Sys_Clock_Set(336,8,2,7),即可設(shè)置STM32F407運(yùn)行在168MHz的頻率下,APB1時(shí)鐘頻率為42MHz,APB2時(shí)鐘頻率為84MHz,USB/SDIO/隨機(jī)數(shù)發(fā)生器時(shí)鐘頻率為48MHz。02STM32單片機(jī)軟件開發(fā)PARTONEGPIO口結(jié)構(gòu)及寄存器配置圖示為STM32的GPIO口的基本結(jié)構(gòu),其可通過軟件配置成8種模式:輸入浮空、輸入上拉、輸入下拉、模擬輸入/輸入、開漏輸出、推挽輸出、復(fù)用功能的推挽輸出、復(fù)用功能的開漏輸出。每個(gè)通用I/O口包括4個(gè)32位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR和GPIOx_PUPDR)、2個(gè)32位數(shù)據(jù)寄存器(GPIOx_IDR和GPIOx_ODR)、1個(gè)32位置位/復(fù)位寄存器(GPIOx_BSRR)、1個(gè)32位鎖定寄存器(GPIOx_LCKR)和2個(gè)32位復(fù)用功能選擇寄存器(GPIOx_AFRH和GPIOx_AFRL)。GPIO口的每個(gè)位均可自由編程,但I(xiàn)/O口寄存器必須按32位字、半字或字節(jié)進(jìn)行訪問。1.配置寄存器GPIOx_MODER0寄存器用于選擇I/O方向(輸入、輸出、AF、模擬)。GPIOx_OTYPER和GPIOx_OSPEEDR寄存器分別用于選擇輸出類型(推挽或開漏)和速度,GPIOx_PUPDR寄存器用于選擇上拉/下拉。其I/O口位配置表如表所示。GPIO口結(jié)構(gòu)及寄存器配置①GPIOportmoderegister(GPIO口模式寄存器)(GPIOx_MODER)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x00。GPIO口結(jié)構(gòu)及寄存器配置MODERy[1:0](y=0,1,2,…,15):端口x配置位,用于配置I/O口的方向。00:輸入。01:通用輸出。10:復(fù)用功能。11:模擬信號(hào)輸入/輸出。②GPIOportoutputtyperegister(GPIO口輸出類型寄存器)(GPIOx_OTYPER)(x=A,B,…,I,J,K)Addressoffset(偏移地址):0x04。OTy(y=0,1,2,…,15):端口x配置位,用于配置I/O口的輸出類型。0:輸出推挽。1:輸出開漏。③GPIOportoutputspeedregister(GPIO口輸出速度寄存器)(GPIOx_OSPEEDR)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x08。OSPEEDRy[1:0](y=0,1,…,15):端口x配置位,用于配置I/O口的速度。00:低速。01:中速。10:高速。11:超高速。GPIO口結(jié)構(gòu)及寄存器配置④GPIOportpull-up/pull-downregister(GPIO口上拉/下拉寄存器)(GPIOx_PUPDR)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x0C。PUPDRy[1:0](y=0,1,…,15):端口x配置位,用于配置I/O口的上拉和下拉。00:無上拉或下拉。01:上拉。10:下拉。11:保留。GPIO口結(jié)構(gòu)及寄存器配置①GPIOportinputdataregister(GPIO口輸入數(shù)據(jù)寄存器)(GPIOx_IDR)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x10。IDRy(y=0,1,…,15):端口x輸入數(shù)據(jù)位,這些位是只讀位,并且只能在word模式下訪問,儲(chǔ)存的是相應(yīng)I/O口的輸入值。②GPIOportoutputdataregister(GPIO口輸出數(shù)據(jù)寄存器)(GPIOx_ODR)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x14。ODRy(y=0,1,…,15):端口x輸出數(shù)據(jù)位,這些位可讀寫,并且可以進(jìn)行位操作。2.?dāng)?shù)據(jù)寄存器

每個(gè)GPIO口都具有2個(gè)16位數(shù)據(jù)寄存器:輸入數(shù)據(jù)寄存器(GPIOx_IDR)和輸出數(shù)據(jù)寄存器(GPIOx_ODR)。GPIOx_ODR用于存儲(chǔ)待輸出數(shù)據(jù),可對(duì)其進(jìn)行讀/寫訪問。通過I/O口輸入的數(shù)據(jù)會(huì)存儲(chǔ)到輸入數(shù)據(jù)寄存器(GPIOx_IDR)中,它是一個(gè)只讀寄存器。GPIO口結(jié)構(gòu)及寄存器配置通過對(duì)以上6個(gè)寄存器的介紹,我們結(jié)合實(shí)例來講解下STM32F407的I/O口設(shè)置,熟悉這幾個(gè)寄存器的使用。例如,設(shè)置PORTC的第12個(gè)I/O口(PC11)為推挽輸出,速度為100MHz,不帶上下拉電阻,并輸出高電平。代碼如下:RCC->AHB1ENR|=1<<2; //使能PORTC時(shí)鐘GPIOC->MODER&=~(3<<(11*2)); //先清除PC11原來的設(shè)置GPIOC->MODER|=1<<(11*2); //設(shè)置PC11為輸出模式GPIOC->OTYPER&=~(1<<11); //清除PC11原來的設(shè)置GPIOC->OTYPER|=0<<11; //設(shè)置PC11為推挽輸出GPIOC->OSPEEDR&=~(3<<(11*2)); //先清除PC11原來的設(shè)置GPIOC->OSPEEDR|=3<<(11*2); //設(shè)置PC11輸出速度為100MHzGPIOC->PUPDR&=~(3<<(11*2)); //先清除PC11原來的設(shè)置GPIOC->PUPDR|=0<<(11*2); //設(shè)置PC11不帶上下拉電阻GPIOC->ODR|=1<<11; //設(shè)置PC11輸出1(高電平)GPIO口結(jié)構(gòu)及寄存器配置經(jīng)過以上介紹,我們便可以設(shè)計(jì)一個(gè)通用的GPIO設(shè)置函數(shù)來設(shè)置STM32F407的I/O口,即GPIO_Set函數(shù),該函數(shù)代碼如下:GPIO口結(jié)構(gòu)及寄存器配置//GPIO通用設(shè)置//GPIOx:GPIOA~GPIOI.//BITx:0X0000~0XFFFF,位設(shè)置,每個(gè)位代表一個(gè)I/O口,第0位代表Px0,第1位代表Px1,依此類推.比如0X0101,代表同時(shí)設(shè)置Px0和Px8.//MODE:0~3;模式選擇,0,輸入(系統(tǒng)復(fù)位默認(rèn)狀態(tài));1,普通輸出;2,復(fù)用功能;3,模擬輸入.//OTYPE:0/1;輸出類型選擇,0,推挽輸出;1,開漏輸出.//OSPEED:0~3;輸出速度設(shè)置,0,2MHz;1,25MHz;2,50MHz;3,100MHz.//PUPD:0~3:上下拉設(shè)置,0,不帶上下拉電阻;1,上拉電阻;2,下拉電阻;3,保留.//注意:在輸入模式(普通輸入/模擬輸入)下,OTYPE和OSPEED參數(shù)無效!!voidGPIO_Set(GPIO_TypeDef*GPIOx,u32BITx,u32MODE,u32OTYPE,u32OSPEED,u32PUPD){u32pinpos=0,pos=0,curpin=0;for(pinpos=0;pinpos<16;pinpos++){pos=1<<pinpos; //一個(gè)個(gè)位檢查curpin=BITx&pos; //檢查引腳是否要設(shè)置if(curpin==pos) //需要設(shè)置{GPIOx->MODER&=~(3<<(pinpos*2)); //先清除原來的設(shè)置GPIOx->MODER|=MODE<<(pinpos*2); //設(shè)置新的模式GPIO口結(jié)構(gòu)及寄存器配置if((MODE==0X01)||(MODE==0X02)) //如果是輸出模式/復(fù)用功能模式{GPIOx->OSPEEDR&=~(3<<(pinpos*2)); //清除原來的設(shè)置GPIOx->OSPEEDR|=(OSPEED<<(pinpos*2)); //設(shè)置新的速度值

GPIOx->OTYPER&=~(1<<pinpos); //清除原來的設(shè)置GPIOx->OTYPER|=OTYPE<<pinpos; //設(shè)置新的輸出模式}GPIOx->PUPDR&=~(3<<(pinpos*2)); //先清除原來的設(shè)置GPIOx->PUPDR|=PUPD<<(pinpos*2); //設(shè)置新的上下拉模式}}}GPIO口結(jié)構(gòu)及寄存器配置該函數(shù)支持對(duì)STM32F407的任何I/O口進(jìn)行設(shè)置,并且支持同時(shí)設(shè)置多個(gè)I/O口(功能一致時(shí)),有了這個(gè)函數(shù),我們就可以大大簡(jiǎn)化STM32F407的I/O口設(shè)置過程,比如同樣設(shè)置PC11為推挽輸出,還可利用GPIO_Set函數(shù)實(shí)現(xiàn),代碼如下:RCC->AHB1ENR|=1<<2; //使能PORTC時(shí)鐘GPIO_Set(PORTC,1<<11,1,0,3,0); //設(shè)置PC11推挽輸出,100MHz,不帶上下拉電阻GPIOC->ODR|=1<<11; //設(shè)置PC11輸出1(高電平)并且,開發(fā)板廠商為GPIO_Set定義了一系列的宏,這些宏在sys.h里面,如果全換成宏,則有GPIO_Set(PORTC,1<<11,1,0,3,0);可以寫成:GPIO_Set(PORTC,PIN11,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_NONE);這樣,雖然看起來長了一點(diǎn),但是一眼便知參數(shù)設(shè)置的意義,具有很好的可讀性。3.置位/復(fù)位寄存器置位/復(fù)位寄存器(GPIOx_BSRR)是一個(gè)32位寄存器,它允許應(yīng)用程序在輸出數(shù)據(jù)寄存器(GPIOx_ODR)中對(duì)各個(gè)單獨(dú)的數(shù)據(jù)位執(zhí)行置位和復(fù)位操作。置位/復(fù)位寄存器的大小是GPIOx_ODR的兩倍。GPIOx_ODR中的每個(gè)數(shù)據(jù)位對(duì)應(yīng)于GPIOx_BSRR中的兩個(gè)控制位:BSRR(i)和BSRR(i+Size)。當(dāng)寫入1時(shí),BSRR(i)位會(huì)置位對(duì)應(yīng)的ODR(i)位,BSRR(i+Size)位會(huì)清零ODR(i)對(duì)應(yīng)的位。在GPIOx_BSRR中向任何位寫入0都不會(huì)對(duì)GPIOx_ODR中的對(duì)應(yīng)位產(chǎn)生任何影響。如果在GPIOx_BSRR中同時(shí)嘗試對(duì)某個(gè)位執(zhí)行置位和清零操作,則置位操作優(yōu)先。GPIOportbitset/resetregister(GPIO口置位/復(fù)位寄存器)(GPIOx_BSRR)(x=A,B,…,I,J,K)。Addressoffset:0x18。Bits[31:16]BRy(y=0,1,…,15):端口x復(fù)位位,用于配置I/O口的輸出類型。0:無影響。1:對(duì)相應(yīng)的ODRx位進(jìn)行復(fù)位。Bits[15:0]BSy(y=0,1,…,15):端口x置位位,用于配置I/O口的輸出類型。0:無影響。1:對(duì)相應(yīng)的ODRx位進(jìn)行置位。GPIO口結(jié)構(gòu)及寄存器配置4.復(fù)用功能寄存器復(fù)用功能寄存器GPIOx_AFRL和GPIOx_AFRH用來在每個(gè)GPIO口上復(fù)用多個(gè)可用的外設(shè)功能,可為每個(gè)I/O口選擇一個(gè)可用功能,其中AFRL控制0~7這8個(gè)I/O口,AFRH控制8~15這8個(gè)I/O口。①GPIOalternatefunctionlowregister(GPIO復(fù)用功能低位寄存器)(GPIOx_AFRL)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x20。

Bits[31:0]AFRLy(y=0,1,…,7):端口x位y的復(fù)用功能選擇,用于配置I/O口的復(fù)用功能。0000:AF0。0001:AF1。……1111:AF15。GPIO口結(jié)構(gòu)及寄存器配置4.復(fù)用功能寄存器②GPIOalternatefunctionhighregister(GPIO復(fù)用功能高位寄存器)(GPIOx_AFRH)(x=A,B,…,I,J,K)。Addressoffset(偏移地址):0x24。Bits[31:0]AFRLy(y=8,9,…,15):端口x位y的復(fù)用功能選擇,用于配置I/O口的復(fù)用功能。0000:AF0。0001:AF1?!?111:AF15。STM32F407xx系列單片機(jī)I/O口復(fù)用功能選擇如圖所示。GPIO口結(jié)構(gòu)及寄存器配置例如,要用PC11復(fù)用的功能為SDIO_D3。因?yàn)橐_11是由AFRH[15:12]控制的,且屬于SDIO功能復(fù)用,所以要選擇AF12,即設(shè)置AFRH[15:12]=AF12,代碼如下:RCC->AHB1ENR|=1<<2; //使能PORTC時(shí)鐘GPIO_Set(PORTC,PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //設(shè)置PC11復(fù)用輸出,100MHz,上拉GPIOC->AFR[1]&=~(0X0F<<12); //清除PC11原來的設(shè)置GPIOC->AFR[1]|=12<<12; //設(shè)置PC11為AF12注意,在MDK里面,AFRL和AFRH被定義成AFR[0]和AFR[1]。經(jīng)過以上設(shè)置,我們就將PC11設(shè)置為復(fù)用功能輸出,且復(fù)用功能選擇SDIO_D3。同樣,我們將AFRL和AFRH的設(shè)置封裝成函數(shù),即GPIO_AF_Set函數(shù),該函數(shù)代碼如下://GPIO復(fù)用設(shè)置//GPIOx:GPIOA~GPIOI.//BITx:0~15,代表I/O引腳編號(hào).//AFx:0~15,代表AF0~AF15.voidGPIO_AF_Set(GPIO_TypeDef*GPIOx,u8BITx,u8AFx){GPIOx->AFR[BITx>>3]&=~(0X0F<<((BITx&0X07)*4));GPIOx->AFR[BITx>>3]|=(u32)AFx<<((BITx&0X07)*4);}GPIO口結(jié)構(gòu)及寄存器配置同樣,我們將AFRL和AFRH的設(shè)置封裝成函數(shù),即GPIO_AF_Set函數(shù),該函數(shù)代碼如下://GPIO復(fù)用設(shè)置//GPIOx:GPIOA~GPIOI.//BITx:0~15,代表I/O引腳編號(hào).//AFx:0~15,代表AF0~AF15.voidGPIO_AF_Set(GPIO_TypeDef*GPIOx,u8BITx,u8AFx){GPIOx->AFR[BITx>>3]&=~(0X0F<<((BITx&0X07)*4));GPIOx->AFR[BITx>>3]|=(u32)AFx<<((BITx&0X07)*4);}GPIO口結(jié)構(gòu)及寄存器配置通過該函數(shù),我們就可以很方便地設(shè)置任何一個(gè)I/O口的復(fù)用功能了。下面通過該函數(shù)設(shè)置PC11為SDIO_D3,代碼如下:RCC->AHB1ENR|=1<<2; //使能PORTC時(shí)鐘GPIO_Set(PORTC,PIN11,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU); //設(shè)置PC11復(fù)用輸出,100MHz,上拉GPIO_AF_Set(GPIOC,11,AF12); //設(shè)置PC11為AF12其中,PIN11和AF12是在sys.h里面定義好的宏。另外,需要注意GPIO_AF_Set函數(shù)每次只能設(shè)置1個(gè)I/O口的復(fù)用功能,如果有多個(gè)I/O口要設(shè)置,那么需要多次調(diào)用該函數(shù)。新建工程(寄存器版)以跑馬燈為例,通過Keil5新建工程。STM32F407ZGT6最小系統(tǒng)板與LED的連接原理圖如圖所示,在PF9、PF10端口上分別接了兩個(gè)LED小燈。步驟1:在TEST文件夾下新建一個(gè)HARDWARE文件夾,用來存放與硬件有關(guān)的文件;然后在HARDWARE文件夾下新建一個(gè)LED文件夾,用來存放與LED相關(guān)的代碼。在USER文件夾下找到工程文件test.uvprojx并打開,新建一個(gè)led.c文件,保存在HARDWARE-LED文件夾下面,在文件中輸入如下代碼。程序清單11-2-1 led.c(寄存器版)程序#include"led.h"http://初始化PF9和PF10為輸出口,并使能這兩個(gè)口的時(shí)鐘 //LEDI/O口初始化voidLED_Init(void){ RCC->AHB1ENR|=1<<5;//使能PORTF時(shí)鐘GPIO_Set(GPIOF,PIN9|PIN10,GPIO_MODE_OUT,GPIO_OTYPE_PP,GPIO_SPEED_100M,GPIO_PUPD_PU);//PF9,PF10設(shè)置

LED0=1;//LED0關(guān)閉

LED1=1;//LED1關(guān)閉}通常購買系統(tǒng)板時(shí),廠家都會(huì)提供基本的工程文件,可以將其復(fù)制到我們的工程文件夾TEST中直接使用,通常包括表11-2-2所示文件。新建工程(寄存器版)該代碼里面就包含了一個(gè)函數(shù)voidLED_Init(void),該函數(shù)的功能就是配置PF9和PF10為推挽輸出。I/O口配置采用GPIO_Set函數(shù)實(shí)現(xiàn)。這里需要注意的是:在配置STM32F407外設(shè)的時(shí)候,要先使能該外設(shè)的時(shí)鐘。RCC_AHB1ENR是AHB總線上的外設(shè)時(shí)鐘使能寄存器,其各位的描述如下。Addressoffset(偏移地址):0x30。Access(訪問):nowaitstate,word,half-wordandbyteaccess.(無等待周期,按字、半字和字節(jié)訪問)。我們要使能PORTF的時(shí)鐘,則只要將該寄存器的bit5置1就可以。配置完時(shí)鐘之后,LED_Init調(diào)用GPIO_Set函數(shù)完成對(duì)PF9和PF10模式的配置,然后熄滅LED0、LED1。步驟2:按同樣的方法,新建一個(gè)led.h文件,也保存在LED文件夾下面。在led.h中輸入如下代碼并保存。程序清單11-2-2led.h(寄存器版)程序#ifndef__LED_H#define__LED_H #include"sys.h"http://LED端口定義#defineLED0PFout(9) //DS0#defineLED1PFout(10) //DS1 voidLED_Init(void); //初始化 #endif這里使用位帶操作來操作某個(gè)I/O口。在M3/M4中,有兩個(gè)區(qū)可以實(shí)現(xiàn)位帶操作,其中一個(gè)是SRAM區(qū)的最低1MB范圍(0x20000000~0x200FFFFF),第二個(gè)則是片內(nèi)外設(shè)區(qū)的最低1MB范圍(0x40000000~0x400FFFFF),稱為位帶區(qū)。這兩個(gè)區(qū)中的存儲(chǔ)器除了可以像普通的RAM一樣訪問使用,M3/M4還將這部分存儲(chǔ)器的每一位重映射為另外一個(gè)獨(dú)立的存儲(chǔ)空間——位帶別名區(qū)的一個(gè)字(32位),通過訪問這些獨(dú)立的存儲(chǔ)空間,就可以達(dá)到訪問原始存儲(chǔ)器每一位的目的,映射關(guān)系如圖所示。新建工程(寄存器版)SRAM位帶區(qū)字節(jié)地址為A的第n(0≤n≤7)位,對(duì)應(yīng)的位帶別名區(qū)地址為:AliasAddr=0x22000000+((A-0x20000000)*8+n)*4=0x22000000+(A-0x20000000)*32+n*4片上外設(shè)位帶區(qū)字節(jié)地址為A的第n(0≤n≤7)位,對(duì)應(yīng)的位帶別名區(qū)地址為:AliasAddr=0x42000000+((A-0x40000000)*8+n)*4=0x42000000+(A-0x40000000)*32+n*4上式中,“*4”表示一個(gè)字有4字節(jié),“*8”表示一字節(jié)有8位。位帶操作程序代碼如下://位帶操作,實(shí)現(xiàn)51單片機(jī)類似的GPIO控制功能//具體實(shí)現(xiàn)思想,參考<<Cortex-M3權(quán)威指南>>(中文)第五章(87頁~92頁).M4同M3類似,只是寄存器地址變了//I/O口操作宏定義#defineBITBAND(addr,bitnum)((addr&0xF0000000)+0x2000000+((addr&0xFFFFF)<<5)+(bitnum<<2))#defineMEM_ADDR(addr)*((volatileunsignedlong*)(addr))#defineBIT_ADDR(addr,bitnum)MEM_ADDR(BITBAND(addr,bitnum))#definePFout(n)BIT_ADDR(GPIOF_ODR_Addr,n)//輸出#definePFin(n)BIT_ADDR(GPIOF_IDR_Addr,n)//輸入新建工程(寄存器版)步驟3:在Target目錄樹上右擊,選擇“ManageProjectItems”,出現(xiàn)圖示的對(duì)話框,在Groups下面單擊“New(Insert)”按鈕,新建一個(gè)HARDWARE組,并把led.c添加到這個(gè)組里。新建工程(寄存器版)新建工程(寄存器版)步驟4:回到主界面,在main函數(shù)中編寫如下代碼。程序清單11-2-3test.c(寄存器版)程序#include"sys.h"#include"delay.h"#include"led.h"intmain(void){{LED0=0; //DS0亮

LED1=1; //DS1滅

delay_ms(500);LED0=1; //DS0滅

LED1=0; //DS1亮

delay_ms(500);}}單擊按鈕,出現(xiàn)圖11-2-7所示的“OptionsforTarget”對(duì)話框,選擇“C/C++”選項(xiàng)卡,把led.h的路徑添加進(jìn)編譯文件,如圖11-2-8所示。然后單擊按鈕,編譯工程,生成.hex文件,安裝J-LINK驅(qū)動(dòng)程序,單擊按鈕下載到目標(biāo)板中,即可驗(yàn)證程序。Stm32_Clock_Init(336,8,2,7); //設(shè)置時(shí)鐘,168MHzdelay_init(168); //初始化延時(shí)函數(shù)

LED_Init(); //初始化LED時(shí)鐘

while(1)在51單片機(jī)的開發(fā)中我們通過直接操作寄存器來實(shí)現(xiàn)控制,例如要控制I/O口的狀態(tài),我們直接操作寄存器:P0=0x11;而在STM32的開發(fā)中,同樣可以操作寄存器:GPIOF->BSRRL=0x0001;這種通過寄存器的控制需要開發(fā)者根據(jù)參考手冊(cè)查找每個(gè)寄存器對(duì)各個(gè)位的定義,再進(jìn)行配置,由于STM32有數(shù)量龐大的寄存器,因此配置過程中容易出錯(cuò)且不利于維護(hù)。ST公司推出了官方固件庫,固件庫將這些寄存器底層操作都封裝起來,提供一整套接口(API)供開發(fā)者調(diào)用。大多數(shù)場(chǎng)合下,開發(fā)者不需要知道操作的是哪個(gè)寄存器,只需要知道調(diào)用哪些函數(shù)即可。例如,上面通過控制BSRRL寄存器實(shí)現(xiàn)I/O口狀態(tài)的控制,官方固件庫就封裝了一個(gè)函數(shù):

GPIO相關(guān)庫函數(shù)介紹voidGPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin){GPIOx->BSRRL=GPIO_Pin;只需要了解函數(shù)的入口參數(shù)及調(diào)用方法就可以實(shí)現(xiàn)控制了。一句話可以概括:固件庫就是函數(shù)的集合,固件庫函數(shù)的作用是向下控制寄存器,向上提供用戶函數(shù)調(diào)用的接口。通常系統(tǒng)板廠商會(huì)提供庫函數(shù)工程模板,工程模板文件夾內(nèi)容清單如表所示。固件庫中,GPIO口的相關(guān)函數(shù)及定義放在文件stm32f4xx_gpio.h和stm32f4xx_gpio.c中。對(duì)于GPIO口的4個(gè)32位寄存器(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR和GPIOx_PUPDR)的配置是通過GPIO口初始化函數(shù)完成的:voidGPIO_Init(GPIO_TypeDef*GPIOx,GPIO_InitTypeDef*GPIO_InitStruct);這個(gè)函數(shù)有兩個(gè)參數(shù),第一個(gè)參數(shù)用來指定需要初始化的GPIO組,取值范圍為GPIOA~GPIOK。第二個(gè)參數(shù)為初始化參數(shù)結(jié)構(gòu)體指針,結(jié)構(gòu)體類型為GPIO_InitTypeDef。找到FWLIB組下面的stm32f4xx_gpio.c文件,定位到GPIO_Init函數(shù)體處,雙擊入口參數(shù)類型GPIO_InitTypeDef后右擊,選擇“Gotodefinitionof...”,可以查看結(jié)構(gòu)體的定義。typedefstruct{uint32_tGPIO_Pin;GPIOMode_TypeDefGPIO_Mode;GPIOSpeed_TypeDefGPIO_Speed;GPIOOType_TypeDefGPIO_OType;GPIOPuPd_TypeDefGPIO_PuPd;}GPIO_InitTypeDef;下面通過一個(gè)GPIO初始化實(shí)例來講解這個(gè)結(jié)構(gòu)體的成員變量的含義,例如:GPIO_InitTypeDefGPIO_InitStructure;GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9 //GPIOF9GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //普通輸出模式GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //100MHzGPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推挽輸出GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化GPIO

GPIO相關(guān)庫函數(shù)介紹結(jié)構(gòu)體GPIO_InitStructure的第一個(gè)成員變量GPIO_Pin用來設(shè)置要初始化哪個(gè)或者哪些I/O口;第二個(gè)成員變量GPIO_Mode用來設(shè)置對(duì)應(yīng)I/O口的輸入輸出模式,這個(gè)值實(shí)際上就是配置的GPIO的MODER寄存器的值,在MDK中是通過一個(gè)枚舉類型定義的,我們只需要選擇對(duì)應(yīng)的值即可。typedefenum{GPIO_Mode_IN=0x00, /*!<GPIOInputMode*/GPIO_Mode_OUT=0x01, /*!<GPIOOutputMode*/GPIO_Mode_AF=0x02, /*!<GPIOAlternatefunctionMode*/GPIO_Mode_AN=0x03 /*!<GPIOAnalogMode*/}GPIOMode_TypeDef;

GPIO相關(guān)庫函數(shù)介紹GPIO_Mode_IN用來設(shè)置輸入模式,GPIO_Mode_OUT表示通用輸出模式,GPIO_Mode_AF表示復(fù)用功能模式,GPIO_Mode_AN表示模擬輸入模式。GPIO_Speed用于設(shè)置I/O口的輸出速度,有四個(gè)可選值。實(shí)際上這就是配置的GPIO的OSPEEDR寄存器的值。在MDK中同樣是通過枚舉類型定義的:/*Addlegacydefinition*/#defineGPIO_Speed_2MHzGPIO_Low_Speed#defineGPIO_Speed_25MHzGPIO_Medium_Speed#defineGPIO_Speed_50MHzGPIO_Fast_Speed#defineGPIO_Speed_100MHzGPIO_High_Speedtypedefenum{GPIO_Low_Speed=0x00, /*!<Lowspeed*/GPIO_Medium_Speed=0x01, /*!<Mediumspeed*/GPIO_Fast_Speed=0x02, /*!<Fastspeed*/GPIO_High_Speed=0x03 /*!<Highspeed*/}GPIOSpeed_TypeDef;我們的輸入可以是GPIOSpeed_TypeDef枚舉類型中GPIO_High_Speed枚舉類型值,也可以是GPIO_Speed_100MHz這樣的值,實(shí)際上GPIO_Speed_100MHz就是通過define宏定義標(biāo)識(shí)符“define”定義出來的,它跟GPIO_High_Speed是等同的。GPIO_OType用來設(shè)置GPIO的輸出類型,實(shí)際上就是設(shè)置GPIO的OTYPER寄存器的值。在MDK中同樣是通過枚舉類型定義的:typedefenum{GPIO_OType_PP=0x00,GPIO_OType_OD=0x01}GPIOOType_TypeDef;如果需要設(shè)置為推挽輸出模式,那么設(shè)置其值為GPIO_OType_PP,如果需要設(shè)置為輸出開漏模式,那么設(shè)置其值為GPIO_OType_OD。GPIO_PuPd用來設(shè)置I/O口的上下拉電阻,實(shí)際上就是設(shè)置GPIO的PUPDR寄存器的值。同樣通過一個(gè)枚舉類型列出:

GPIO相關(guān)庫函數(shù)介紹typedefenum{GPIO_PuPd_NOPULL=0x00,GPIO_PuPd_UP=0x01,GPIO_PuPd_DOWN=0x02}GPIOPuPd_TypeDef;這三個(gè)值的意思很好理解,GPIO_PuPd_NOPULL為不使用上下拉電阻,GPIO_PuPd_UP為上拉,GPIO_PuPd_DOWN為下拉。我們根據(jù)需要設(shè)置相應(yīng)的值即可。在固件庫中通過函數(shù)GPIO_Write來設(shè)置ODR寄存器的值,從而控制I/O口的輸出狀態(tài):voidGPIO_Write(GPIO_TypeDef*GPIOx,uint16_tPortVal);該函數(shù)一般用來一次性給GPIO的所有端口賦值。

GPIO相關(guān)庫函數(shù)介紹讀ODR寄存器還可以讀出I/O口的輸出狀態(tài),庫函數(shù)為:uint16_tGPIO_ReadOutputData(GPIO_TypeDef*GPIOx);uint8_tGPIO_ReadOutputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);這兩個(gè)函數(shù)的功能類似,只不過前面的函數(shù)用來一次讀取一組I/O口的輸出狀態(tài),后面的函數(shù)用來一次讀取一組I/O口中一個(gè)或者幾個(gè)I/O口的輸出狀態(tài)。讀取某個(gè)I/O口的電平的相關(guān)庫函數(shù)為:uint8_tGPIO_ReadInputDataBit(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);uint16_tGPIO_ReadInputData(GPIO_TypeDef*GPIOx);前面的函數(shù)用來讀取一組I/O口中一個(gè)或者幾個(gè)I/O口的輸入電平,后面的函數(shù)用來一次讀取一組I/O口的輸入電平。也可通過庫函數(shù)操作BSRR寄存器來設(shè)置I/O口的電平,相關(guān)庫函數(shù)為:voidGPIO_SetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);voidGPIO_ResetBits(GPIO_TypeDef*GPIOx,uint16_tGPIO_Pin);函數(shù)GPIO_SetBits用來設(shè)置一組I/O口中的一個(gè)或者多個(gè)I/O口為高電平。GPIO_ResetBits用來設(shè)置一組I/O口中一個(gè)或者多個(gè)I/O口為低電平。比如,我們要設(shè)置GPIOB.5輸出高電平,方法為:GPIO_SetBits(GPIOB,GPIO_Pin_5); //GPIOB.5輸出高電平設(shè)置GPIOB.5輸出低電平,方法為:GPIO_ResetBits(GPIOB,GPIO_Pin_5); //GPIOB.5輸出低電平以跑馬燈為例,通過系統(tǒng)板廠商提供的庫函數(shù)工程模板來建立自己項(xiàng)目的工程。步驟1:?jiǎn)螕艄こ棠0錟SER目錄下的工程文件Template.uvproj(也可重命名為LED.uvproj)。在工程根目錄文件夾下新建一個(gè)HARDWARE文件夾,用來存放與硬件相關(guān)的代碼。然后在HARDWARE文件夾下新建一個(gè)LED文件夾,用來存放與LED相關(guān)的代碼。新建一個(gè)文本文件led.c,保存在LED文件夾下,在led.c中輸入如下代碼。程序清單11-2-4led.c(庫函數(shù)版)程序#include"led.h"

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論