單片機STM32學習筆記
《單片機STM32學習筆記》由會員分享,可在線閱讀,更多相關《單片機STM32學習筆記(22頁珍藏版)》請在裝配圖網上搜索。
1、 . . . 推挽輸出與開漏輸出的區(qū)別 推挽輸出:可以輸出高,低電平,連接數字器件; 開漏輸出:輸出端相當于三極管的集電極. 要得到高電平狀態(tài)需要上拉電阻才行. 適合于做電流型的驅動,其吸收電流的能力相對強(一般20ma以). ??推挽結構一般是指兩個三極管分別受兩互補信號的控制,總是在一個三極管導通的時候另一個截止. 要實現“線與”需要用OC(open collector)門電路.是兩個參數一樣的三極管或MOSFET,以推挽方式存在于電路中,各負責正負半周的波形放大任務,電路工作時,兩只對稱的功率開關管每次只有一個導通,所以導通損耗小,效
2、率高。輸出既可以向負載灌電流,也可以從負載抽取電流。 問題: 很多芯片的供電電壓不一樣,有3.3v和5.0v,需要把幾種IC的不同口連接在一起,是不是直接連接就可以了?實際上系統(tǒng)是應用在I2C上面。 簡答: 1、部分3.3V器件有5V兼容性,可以利用這種容性直接連接 2、應用電壓轉換器件,如TPS76733就是5V輸入,轉換成3.3V、1A輸出。 開漏電路特點與應用 在電路設計時我們常常遇到開漏(open drain)和開集(open collector)的概念。所謂開漏電路概念中提到的“漏”就是指MOSFET的漏極。同理,開集電路中的“集”就是指三極管的集電極。開漏電路
3、就是指以MOSFET的漏極為輸出的電路。一般的用法是會在漏極外部的電路添加上拉電阻。完整的開漏電路應該由開漏器件和開漏上拉電阻組成。如圖1所示:??? 組成開漏形式的電路有以下幾個特點: 1. 利用外部電路的驅動能力,減少IC部的驅動。當IC部MOSFET導通時,驅動電流是從外部的VCC流經R pull-up ,MOSFET到GND。IC部僅需很下的柵極驅動電流。如圖1。 2. 可以將多個開漏輸出的Pin,連接到一條線上。形成 “與邏輯” 關系。如圖1,當PIN_A、PIN_B、PIN_C任意一個變低后,開漏線上的邏輯就為0了。這也是I2C,SMBus等總線判斷總線占用狀態(tài)的原
4、理。 3. 可以利用改變上拉電源的電壓,改變傳輸電平。如圖2, IC的邏輯電平由電源Vcc1決定,而輸出高電平則由Vcc2決定。這樣我們就可以用低電平邏輯控制輸出高電平邏輯了。 4. 開漏Pin不連接外部的上拉電阻,則只能輸出低電平(因此對于經典的51單片機的P0口而言,要想做輸入輸出功能必須加外部上拉電阻,否則無法輸出高電平邏輯)。 5. 標準的開漏腳一般只有輸出的能力。添加其它的判斷電路,才能具備雙向輸入、輸出的能 力。 應用中需注意: 1.?? 開漏和開集的原理類似,在許多應用中我們利用開集電路代替開漏電路。例如,某輸入Pin要求由
5、開漏電路驅動。則我們常見的驅動方式是利用一個三極管組成開集電路來驅動它,即方便又節(jié)省成本。如圖3。 2. 上拉電阻R pull-up的阻值決定了邏輯電平轉換的沿的速度 。阻值越大,速度越低功耗越小。反之亦然。 Push-Pull輸出就是一般所說的推挽輸出,在CMOS電路里面應該較CMOS輸出更合適,應為在CMOS里面的push-pull輸出能力不可能做得雙極那么大。輸出能力看IC部輸出極N管P管的面積。和開漏輸出相比,push-pull的高低電平由IC的電源低定,不能簡單的做邏輯操作等。push-pull是現在CMOS電路里面用得最多的輸出級設計方式。 at91rm9200 GPIO
6、模擬I2C接口時注意?。? 判斷上拉輸入和下拉輸入 當一個按鍵按下的時候,對應的引腳輸入數據是0或1是不確定的,還要看外部電路的組成是上拉還是下拉,當外部電路時上拉的時候,即外部接正的時候,讀入的數據是1;當外部電路是下拉的時候,讀入的數據是0. 上拉例子:無鍵按下的時候是1??,有鍵按下是0 下拉例子:無鍵按下的時候是0,有鍵按下時是1 STM32學習----時鐘 在STM32中,有五個時鐘源,為HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速部時鐘,RC
7、振蕩器,頻率為8MHz。 ②、HSE是高速外部時鐘,可接石英/瓷諧振器,或者接外部時鐘源,頻率圍為4MHz~16MHz。 ③、LSI是低速部時鐘,RC振蕩器,頻率為40kHz。 ④、LSE是低速外部時鐘,接頻率為32.768kHz的石英晶體。 ⑤、PLL為鎖相環(huán)倍頻輸出,其時鐘輸入源可選擇為HSI/2、HSE或者HSE/2。倍頻可選擇為2~16倍,但是其輸出頻率最大不得超過72MHz。 其中40kHz的LSI供獨立看門狗IWDG使用,另外它還可以被選擇為實時時鐘RTC的時鐘源。另外,實時時鐘RTC的時鐘源還可以選擇LSE,或者是HSE的128分頻。RTC的時鐘源通過RTCSEL[1:
8、0]來選擇。 STM32中有一個全速功能的USB模塊,其串行接口引擎需要一個頻率為48MHz的時鐘源。該時鐘源只能從PLL輸出端獲取,可以選擇為1.5分頻或者1分頻,也就是,當需要使用USB模塊時,PLL必須使能,并且時鐘頻率配置為48MHz或72MHz。 另外,STM32還可以選擇一個時鐘信號輸出到MCO腳(PA8)上,可以選擇為PLL輸出的2分頻、HSI、HSE、或者系統(tǒng)時鐘。 系統(tǒng)時鐘SYSCLK,它是供STM32中絕大部分部件工作的時鐘源。系統(tǒng)時鐘可選擇為PLL輸出、HSI或者HSE。系統(tǒng)時鐘最大頻率為72MHz,它通過AHB分頻器分頻后送給各模塊使用,AHB分頻器可選擇1、2、
9、4、8、16、64、128、256、512分頻。其中AHB分頻器輸出的時鐘送給5大模塊使用: ①、送給AHB總線、核、存和DMA使用的HCLK時鐘。 ②、通過8分頻后送給Cortex的系統(tǒng)定時器時鐘。 ③、直接送給Cortex的空閑運行時鐘FCLK。 ④、送給APB1分頻器。APB1分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB1外設使用(PCLK1,最大頻率36MHz),另一路送給定時器(Timer)2、3、4倍頻器使用。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器2、3、4使用。 ⑤、送給APB2分頻器。APB2分頻器可選擇1、2、4、8、16分頻,其輸出一路供APB2
10、外設使用(PCLK2,最大頻率72MHz),另一路送給定時器(Timer)1倍頻器使用。該倍頻器可選擇1或者2倍頻,時鐘輸出供定時器1使用。另外,APB2分頻器還有一路輸出供ADC分頻器使用,分頻后送給ADC模塊使用。ADC 分頻器可選擇為2、4、6、8分頻。 在以上的時鐘輸出中,有很多是帶使能控制的,例如AHB總線時鐘、核時鐘、各種APB1外設、APB2外設等等。當需要使用某模塊時,記得一定要先使能對應的時鐘。 需要注意的是定時器的倍頻器,當APB的分頻為1時,它的倍頻值為1,否則它的倍頻值就為2。 連接在APB1(低速外設)上的設備有:電源接口、備份接口、CAN、USB、I2C1、
11、I2C2、UART2、UART3、SPI2、窗口看門狗、Timer2、Timer3、Timer4。注意USB模塊雖然需要一個單獨的48MHz時鐘信號,但它應該不是供USB模塊工作的時鐘,而只是提供給串行接口引擎(SIE)使用的時鐘。USB模塊工作的時 鐘應該是由APB1提供的。 連接在APB2(高速外設)上的設備有:UART1、SPI1、Timer1、ADC1、ADC2、所有普通IO口(PA~PE)、第二功能IO口。 下圖為STM32芯片的時鐘結構圖。從圖中可以直觀的看出STM32的時鐘封裝。 STM32資料一 flas
12、h: 芯片部存儲器flash操作函數 我的理解——對芯片部flash進行操作的函數,包括讀取,狀態(tài),擦除,寫入等等,可以允許程序去操作flash上的數據。 1,FLASH時序延遲幾個周期,等待總線同步操作。推薦按照單片機系統(tǒng)運行頻率,0—24MHz時,取Latency=0;24—48MHz時,取Latency=1;48~72MHz時,取Latency=2。所有程序中必須的 用法:FLASH_SetLatency(FLASH_Latency_2); 位置:RCC初始化子函數里面,時鐘起振之后。 2,開啟FLASH預讀緩沖功能,加速FLASH的讀取。所有程序中必須的 用法:FLASH_
13、PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); 位置:RCC初始化子函數里面,時鐘起振之后。 3、lib:調試所有外設初始化的函數。 我的理解——不理解,也不需要理解。只要知道所有外設在調試的時候,EWRAM需要從這個函數里面獲得調試所需信息的地址或者指針之類的信息。 基礎應用1,只有一個函數debug。所有程序中必須的。 用法: ?? ??? #ifdef DEBUG ?? ?? ?? ?? ?? debug(); #endif ?位置:main函數開頭,聲明變量之后。 4、nvic:系統(tǒng)中斷管理。 我的理解——管理系統(tǒng)部的
14、中斷,負責打開和關閉中斷。 基礎應用1,中斷的初始化函數,包括設置中斷向量表位置,和開啟所需的中斷兩部分。所有程序中必須的。 用法: ?? ??? void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; ?? ?? ?? //中斷管理恢復默認參數 #ifdef?? VECT_TAB_RAM?? //如果C/C++ Compiler\Preprocessor\Defined symbols中的定義了VECT_TAB_RAM(見程序庫更改容的表格) NVIC_SetVectorTable(NVIC_
15、VectTab_RAM, 0x0); //則在RAM調試 #else ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? //如果沒有定義VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);//則在Flash里調試 #endif ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? //結束判斷語句 //以下為中斷的開啟過程,不是所有程序必須的。 NVIC_PriorityGroupConfig(NVIC_Priori
16、tyGroup_2); //設置NVIC優(yōu)先級分組,方式。 //注:一共16個優(yōu)先級,分為搶占式和響應式。兩種優(yōu)先級所占的數量由此代碼確定,NVIC_PriorityGroup_x可以是0、1、2、3、4,分別代表搶占優(yōu)先級有1、2、4、8、16個和響應優(yōu)先級有16、8、4、2、1個。規(guī)定兩種優(yōu)先級的數量后,所有的中斷級別必須在其中選擇,搶占級別高的會打斷其他中斷優(yōu)先執(zhí)行,而響應級別高的會在其他中斷執(zhí)行完優(yōu)先執(zhí)行。 NVIC_InitStructure.NVIC_IRQChannel = 中斷通道名; //開中斷,中斷名稱見函數庫 NVIC_InitStructure.NVIC_IRQ
17、ChannelPreemptionPriority = 0; //搶占優(yōu)先級 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; ?? ???? //響應優(yōu)先級 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //啟動此通道的中斷 NVIC_Init(&NVIC_InitStructure); ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??//中斷初始化 } 5、???????? rcc:單片機時鐘管理。 我的理解——管理外部、部和外設的時鐘,設置、打開和關閉這些時鐘
18、。 基礎應用1:時鐘的初始化函數過程 用法:void RCC_Configuration(void) ?? ?? ?? ?? ?? //時鐘初始化函數 { ?? ErrorStatus HSEStartUpStatus; ?? ?? ?? ?? ?? ?? ?? //等待時鐘的穩(wěn)定 ?? RCC_DeInit(); ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??//時鐘管理重置 ?? RCC_HSEConfig(RCC_HSE_ON); ?? ?? ?? ?? ?? ?? ?? ?? ?//打開外部晶振 ?? HSEStartUpStatus
19、= RCC_WaitForHSEStartUp(); ?? ?? ??//等待外部晶振就緒 if (HSEStartUpStatus == SUCCESS) ?? { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//flash讀取緩沖,加速 FLASH_SetLatency(FLASH_Latency_2); ?? ?? ?? ?? ?? ?? //flash操作的延時 RCC_HCLKConfig(RCC_SYSCLK_Div1); ?? ?? ?? ?? ?? ?? ?//AHB使用系統(tǒng)時鐘 RCC_PCLK2Con
20、fig(RCC_HCLK_Div2); ?? ?? ?? ?? ?? ??//APB2(高速)為HCLK的一半 RCC_PCLK1Config(RCC_HCLK_Div2); ?? ?? ?? ?? ?? ??//APB1(低速)為HCLK的一半 //注:AHB主要負責外部存儲器時鐘。APB2負責AD,I/O,高級TIM,串口1。APB1負責DA,USB,SPI,I2C,CAN,串口2345,普通TIM。 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHz * 9 = 72 MHz RCC_PLLCm
21、d(ENABLE); ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??//啟動PLL while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET){} ?//等待PLL啟動 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //將PLL設置為系統(tǒng)時鐘源 while (RCC_GetSYSCLKSource() != 0x08){} ??? //等待系統(tǒng)時鐘源的啟動 ?? } RCC_AHBPeriphClockCmd(ABP2設備1 | ABP2設備2 |, ENABLE); //啟動
22、AHP設備 RCC_APB2PeriphClockCmd(ABP2設備1 | ABP2設備2 |, ENABLE);//啟動ABP2設備 RCC_APB1PeriphClockCmd(ABP2設備1 | ABP2設備2 |, ENABLE); //啟動ABP1設備 } 6、??????? exti:外部設備中斷函數 我的理解——外部設備通過引腳給出的硬件中斷,也可以產生軟件中斷,19個上升、下降或都觸發(fā)。EXTI0~EXTI15連接到管腳,EXTI線16連接到PVD(VDD監(jiān)視),EXTI線17連接到RTC(鬧鐘),EXTI線18連接到USB(喚醒)。 基礎應用1,設定外部中斷
23、初始化函數。按需求,不是必須代碼。 用法: void EXTI_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; ?? ?? ?? //外部設備中斷恢復默認參數 EXTI_InitStructure.EXTI_Line = 通道1|通道2; //設定所需產生外部中斷的通道,一共19個。 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; ??? //產生中斷 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falli
24、ng; //上升下降沿都觸發(fā) EXTI_InitStructure.EXTI_LineCmd = ENABLE; ?? ?? ?? ?? //啟動中斷的接收 EXTI_Init(&EXTI_InitStructure); ?? ?? ?? ?? //外部設備中斷啟動 } 7、??????? dma:通過總線而越過CPU讀取外設數據 我的理解——通過DMA應用可以加速單片機外設、存儲器之間的數據傳輸,并在傳輸期間不影響CPU進行其他事情。這對于入門開發(fā)基本功能來說沒有太大必要,這個容先行跳過。 8、??????? systic:系統(tǒng)定時器 我的理解——可以輸出和利用系統(tǒng)時鐘的計數、
25、狀態(tài)。 基礎應用1,精確計時的延時子函數。推薦使用的代碼。 用法: static vu32 TimingDelay; ?? ?? ?? ?? ?? ?? ?? //全局變量聲明 void SysTick_Config(void) ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? //systick初始化函數 { SysTick_CounterCmd(SysTick_Counter_Disable); ?? ?? ?? ?? ?? //停止系統(tǒng)定時器 SysTick_ITConfig(DISABLE); //停止systick中斷 SysTick_CLKSourceCo
26、nfig(SysTick_CLKSource_HCLK_Div8); //systick使用HCLK作為時鐘源,頻率值除以8。 SysTick_SetReload(9000); ?? ?? ?? ??//重置時間1毫秒(以72MHz為基礎計算) SysTick_ITConfig(ENABLE); ?? ?? ?? ?? ?? ?? ?? ?? ? //開啟systic中斷 } void Delay (u32 nTime) ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? //延遲一毫秒的函數 { SysTick_CounterCmd(SysTick_Counter_Ena
27、ble); ?? ?? ?? ?? ?? //systic開始計時 ?? TimingDelay = nTime; ?? ?? ?? ?? ?? ?? ?? //計時長度賦值給遞減變量 while(TimingDelay != 0){}; //檢測是否計時完成 SysTick_CounterCmd(SysTick_Counter_Disable); ?? ?? ?? //關閉計數器 SysTick_CounterCmd(SysTick_Counter_Clear); ?? ?? ?? ? //清除計數值 } void TimingDelay_Decrement(void) //遞減
28、變量函數,函數名由“stm32f10x_it.c”中的中斷響應函數定義好了。 { if (TimingDelay != 0x00) //檢測計數變量是否達到0 { TimingDelay--; //計數變量遞減 } } 注:建議熟練后使用,所涉與知識和設備太多,新手出錯的可能性比較大。新手可用簡化的延時函數代替: void Delay(vu32 nCount) ?? ?? ?? ?? ?? ?? ?? ??//簡單延時函數 { ?? for(; nCount != 0; nCount--); ?? ?? ?? ? //循環(huán)變量遞減計數 } 當延時較長,又不需要精確計時的時
29、候可以使用嵌套循環(huán): void Delay(vu32 nCount) ?? ?? ?? ?? ?? ?? ?? //簡單的長時間延時函數 {int i; //聲明部遞減變量 ?? for(; nCount != 0; nCount--) ?? ?? ?? ?? ?? ?? ?? //遞減變量計數 {for (i=0; i<0xffff; i++)} ?? ?? ?? ?? ?? ?? ?? //部循環(huán)遞減變量計數 } 9、??????? gpio:I/O設置函數 我的理解——所有輸入輸出管腳模式設置,可以是上下拉、浮空、開漏、模擬、推挽模式,頻率特性為2M,10M,50M。也可
30、以向該管腳直接寫入數據和讀取數據。 基礎應用1,gpio初始化函數。所有程序必須。 用法:void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; ?? ?? ?? ?? ??//GPIO狀態(tài)恢復默認參數 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_標號 | GPIO_Pin_標號 ; //管腳位置定義,標號可以是NONE、ALL、0至15。 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;//輸出速度2MHz GPIO
31、_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模擬輸入模式 GPIO_Init(GPIOC, &GPIO_InitStructure); //C組GPIO初始化 //注:以上四行代碼為一組,每組GPIO屬性必須一樣,默認的GPIO參數為:ALL,2MHz,FLATING。如果其中任意一行與前一組相應設置一樣,那么那一行可以省略,由此推論如果前面已經將此行參數設定為默認參數(包括使用GPIO_InitTypeDef GPIO_InitStructure代碼),本組應用也是默認參數的話,那么也可以省略。以下重復這個過程直到所有應用的管腳全部被定義完畢。
32、 …… } 基礎應用2,向管腳寫入0或1 用法:GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01); ?? //寫入1 基礎應用3,從管腳讀入0或1 用法:GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) sw笨笨的STM32筆記之七:讓它跑起來,基本硬件功能的建立 0、???????實驗之前的準備 a)????????接通串口轉接器 b)????????下載IO與串口的原廠程序,編譯通過保證調試所需硬件正常 1、????????flash,lib,nvic,rcc和GPIO,基礎程序庫
33、編寫 a)????????這幾個庫函數中有一些函數是關于芯片的初始化的,每個程序中必用。為保障程序品質,初學階段要求嚴格遵守官方習慣。注意,官方程序庫例程中有個platform_config.h文件,是專門用來指定同類外設中第幾號外設被使用,就是說在main.c里面所有外設序號用x代替,比如USARTx,程序會到這個頭文件中去查找到底是用那些外設,初學的時候參考例程別被這個所迷惑住。 b)????????全部必用代碼取自庫函數所帶例程,并增加逐句注釋。 c)????????習慣順序——Lib(debug),RCC(包括Flash優(yōu)化),NVIC,GPIO d)????????必用模塊初
34、始化函數的定義: void RCC_Configuration(void);????????//定義時鐘初始化函數 void GPIO_Configuration(void);??????//定義管腳初始化函數 void NVIC_Configuration(void);?????//定義中斷管理初始化函數 void Delay(vu32 nCount);???????????????//定義延遲函數 e)????????Main中的初始化函數調用: RCC_Configuration();????????????????//時鐘初始化函數調用 NVIC_Configuratio
35、n();????????//中斷初始化函數調用 GPIO_Configuration();???????? //管腳初始化函數調用 f)????????Lib注意事項: 屬于Lib的Debug函數的調用,應該放在main函數最開始,不要改變其位置。 g)????????RCC注意事項: Flash優(yōu)化處理可以不做,但是兩句也不難也不用改參數…… 根據需要開啟設備時鐘可以節(jié)省電能 時鐘頻率需要根據實際情況設置參數 h)????????NVIC注意事項 注意理解占先優(yōu)先級和響應優(yōu)先級的分組的概念 i)????????GPIO注意事項 注意以后的過程中收集不同管腳應用對應的
36、頻率和模式的設置。 作為高低電平的I/O,所需設置:RCC初始化里面打開RCC_APB2 PeriphClockCmd(RCC_APB2Periph_GPIOA);GPIO里面管腳設定:IO輸出(50MHz,Out_PP);IO輸入(50MHz,IPU); j)????????GPIO應用 GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_RESET);//重置 GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//寫入1 GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitActi
37、on)0x00);//寫入0 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) ;//讀入IO k)????????簡單Delay函數 void Delay(vu32 nCount)//簡單延時函數 {for(; nCount != 0; nCount--);} 實驗步驟: RCC初始化函數里添加:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB , ENABLE); 不用其他中斷,NVIC初始化函數不用改
38、 GPIO初始化代碼: //IO輸入,GPIOB的2、10、11腳輸出 ??GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;//管腳號 ??GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;?? //輸出速度 ??GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;????//輸入輸出模式 ??GPIO_Init(GPIOB, &GPIO_InitStructure);??????????????//初始化 簡單的延遲函數: void Dela
39、y(vu32 nCount)???????????????????? //簡單延時函數 { for (; nCount != 0; nCount--);}?????????? //循環(huán)計數延時 完成之后再在main.c的while里面寫一段: GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x01);//寫入1 Delay(0xffff); GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)0x00);//寫入0 Delay(0xffff); 就可以看到連接在PB2腳上的LED閃爍了,單片
40、機就跑起來了。 sw笨笨的STM32筆記之八:來跟PC打個招呼,基本串口通訊 a)????????目的:在基礎實驗成功的基礎上,對串口的調試方法進行實踐。硬件代碼順利完成之后,對日后調試需要用到的printf重定義進行調試,固定在自己的庫函數中。 b)????????初始化函數定義: void USART_Configuration(void);????????//定義串口初始化函數 c)????????初始化函數調用: void UART_Configuration(void);????????//串口初始化函數調用初始化代碼: void USART_Configurat
41、ion(void)????????????????????????//串口初始化函數 { //串口參數初始化?? ??USART_InitTypeDef USART_InitStructure;??????????????//串口設置恢復默認參數 //初始化參數設置 ??USART_InitStructure.USART_BaudRate = 9600;?????????????????//波特率9600 ? USART_InitStructure.USART_WordLength = USART_WordLength_8b;?? //字長8位 ??USART_InitStr
42、ucture.USART_StopBits = USART_StopBits_1;???????//1位停止字節(jié) ??USART_InitStructure.USART_Parity = USART_Parity_No;?????????????//無奇偶校驗 ??USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無流控制 ??USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打開Rx接收和Tx發(fā)送
43、功能?USART_Init(USART1, &USART_InitStructure);?????????????????//初始化 ??USART_Cmd(USART1, ENABLE);????????????????????????????//啟動串口 } RCC中打開相應串口 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); GPIO里面設定相應串口管腳模式 //串口1的管腳初始化?? ??GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;?????????????//管
44、腳9 ??GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;?????? //復用推挽輸出 ??GPIO_Init(GPIOA, &GPIO_InitStructure);??????????????? //TX初始化 ??GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;?????????????//管腳10 ??GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空輸入 ??GPIO_Init(GPIOA, &GPIO_InitStruc
45、ture);??????????????? //RX初始化 d)????????簡單應用:發(fā)送一位字符 USART_SendData(USART1, 數據);????????????????//發(fā)送一位數據 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}????????????????????????????????????????//等待發(fā)送完畢接收一位字符 while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET){}????????????
46、????????????????????????????//等待接收完畢變量= (USART_ReceiveData(USART1));????????//接受一個字節(jié)發(fā)送一個字符串 ????先定義字符串:char rx_data[250]; ????然后在需要發(fā)送的地方添加如下代碼 ??int i;???????????????????????????????????????? //定義循環(huán)變量 ????while(rx_data!='\0')??????????????????????????//循環(huán)逐字輸出,到結束字'\0' ????{USART_SendData(USART1
47、, rx_data);????????????//發(fā)送字符 ???? while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待字符發(fā)送完畢 ???? i++;} e)????????USART注意事項:發(fā)動和接受都需要配合標志等待。只能對一個字節(jié)操作,對字符串等大量數據操作需要寫函數使用串口所需設置:RCC初始化里面打開RCC_APB2PeriphClockCmd(RCC_APB2Periph_USARTx);GPIO里面管腳設定:串口RX(50Hz,IN_FLOATING);串口TX(50Hz,AF_PP
48、); f)????????printf函數重定義(不必理解,調試通過以備后用)(1)????????需要c標準函數: #include "stdio.h" (2)????????粘貼函數定義代碼 #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)??//定義為putchar應用(3)????????RCC中打開相應串口(4)????????GPIO里面設定相應串口管腳模式(6)????????增加為putchar函數。 int putchar(int c)?????????????????????????????????????
49、???//putchar函數 { ??if (c == '\n'){putchar('\r');}??????????????????????????//將printf的\n變成\r ??USART_SendData(USART1, c);????????????????????????????????????//發(fā)送字符 ??while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){} //等待發(fā)送結束 ??return c;????????????????????????????????????????????????
50、???? //返回值 } (8)????????通過,試驗成功。printf使用變量輸出:%c字符,%d整數,%f浮點數,%s字符串,/n或/r為換行。注意:只能用于main.c中。 3、???????NVIC串口中斷的應用 a)????????目的:利用前面調通的硬件基礎,和幾個函數的代碼,進行串口的中斷輸入練習。因為在實際應用中,不使用中斷進行的輸入是效率非常低的,這種用法很少見,大部分串口的輸入都離不開中斷。 b)????????初始化函數定義與函數調用:不用添加和調用初始化函數,在指定調試地址的時候已經調用過,在那個NVIC_Configuration里面添加相應開中
51、斷代碼就行了。 c)????????過程: i.? 在串口初始化中USART_Cmd之前加入中斷設置: USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//TXE發(fā)送中斷,TC傳輸完成中斷,RXNE接收中斷,PE奇偶錯誤中斷,可以是多個。 ii.????????RCC、GPIO里面打開串口相應的基本時鐘、管腳設置 iii.??????NVIC里面加入串口中斷打開代碼: NVIC_InitTypeDef NVIC_InitStructure;//中斷默認參數 NVIC_InitStructure.NVIC_IRQChann
52、el = USART1_IRQChannel;//通道設置為串口1中斷 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;??//中斷占先等級0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;??????????//中斷響應優(yōu)先級0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;????????????//打開中斷 NVIC_Init(&NVIC_InitStructure);???????????????????????
53、????//初始化 iv.????????在stm32f10x_it.c文件中找到void USART1_IRQHandler函數,在其中添入執(zhí)行代碼。一般最少三個步驟:先使用if語句判斷是發(fā)生那個中斷,然后清除中斷標志位,最后給字符串賦值,或做其他事情。 void USART1_IRQHandler(void)??????????????????????????????//串口1中斷 { char RX_dat;?????????????????????????????????????????????????//定義字符變量 ?? ??if (USART_GetITStat
54、us(USART1, USART_IT_RXNE) != RESET)??//判斷發(fā)生接收中斷 ??{USART_ClearITPendingBit(USART1,??USART_IT_RXNE);??????????//清除中斷標志 ?? ?? GPIO_WriteBit(GPIOB, GPIO_Pin_10, (BitAction)0x01);???????????? //開始傳輸 ?? RX_dat=USART_ReceiveData(USART1) & 0x7F;?????????????????????? //接收數據,整理除去前兩位 ?? USART_SendData(U
55、SART1, RX_dat);?????????????????????????????????????? //發(fā)送數據 ?? while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//等待發(fā)送結束 ??} } d)????????中斷注意事項:可以隨時在程序中使用USART_ITConfig(USART1, USART_IT_TXE, DISABLE);來關閉中斷響應。 NVIC_InitTypeDef NVIC_InitStructure定義一定要加在NVIC初始化模塊的第一句。全局變量與函數的定義:在任意.
56、c文件中定義的變量或函數,在其它.c文件中使用extern+定義代碼再次定義就可以直接調用了。 sw笨笨的STM32筆記之九:打斷它來為我辦事,EXIT (外部I/O中斷)應用 a) 目的:跟串口輸入類似,不使用中斷進行的IO輸入效率也很低,而且可以通過EXTI插入按鈕事件,本節(jié)聯系EXTI中斷。 b) 初始化函數定義: void EXTI_Configuration(void); //定義IO中斷初始化函數 c) 初始化函數調用: EXTI_Configuration();//IO中斷初始化函數調用簡單應用: d) 初始化
57、函數: void EXTI_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; //EXTI初始化結構定義 EXTI_ClearITPendingBit(EXTI_LINE_KEY_BUTTON);//清除中斷標志 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);//管腳選擇 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource4); GPIO
58、_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource5); GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6); EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//事件選擇 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//觸發(fā)模式 EXTI_InitStructure.EXTI_Line = EXTI_Line3 | E
59、XTI_Line4; //線路選擇 EXTI_InitStructure.EXTI_LineCmd = ENABLE;//啟動中斷 EXTI_Init(&EXTI_InitStructure);//初始化 } e) RCC初始化函數中開啟I/O時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); GPIO初始化函數中定義輸入I/O管腳。 //IO輸入,GPIOA的4腳輸入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_Init
60、Structure.GPIO_Mode = GPIO_Mode_IPU; //上拉輸入 GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化 f) 在NVIC的初始化函數里面增加以下代碼打開相關中斷: NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQChannel; //通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//占先級 NVIC_I
61、nitStructure.NVIC_IRQChannelSubPriority = 0; //響應級 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //啟動 NVIC_Init(&NVIC_InitStructure); //初始化 g) 在stm32f10x_it.c文件中找到void USART
62、1_IRQHandler函數,在其中添入執(zhí)行代碼。一般最少三個步驟:先使用if語句判斷是發(fā)生那個中斷,然后清除中斷標志位,最后給字符串賦值,或做其他事情。 if(EXTI_GetITStatus(EXTI_Line3) != RESET) //判斷中斷發(fā)生來源 { EXTI_ClearITPendingBit(EXTI_Line3); //清除中斷標志 USART_SendData(USART1, 0x41);
63、 //發(fā)送字符“a” GPIO_WriteBit(GPIOB, GPIO_Pin_2, (BitAction)(1-GPIO_ReadOutputDataBit(GPIOB, GPIO_Pin_2)));//LED發(fā)生明暗交替 } h) 中斷注意事項: 中斷發(fā)生后必須清除中斷位,否則會出現死循環(huán)不斷發(fā)生這個中斷。然后需要對中斷類型進行判斷再執(zhí)行代碼。 使用EXTI的I/O中斷,在完成RCC與GPIO硬件設置之后需要做三件事:初始化EXTI、NVIC開中斷、編寫中斷執(zhí)行代碼。 sw
64、笨笨的STM32筆記之十:工作工作,PWM輸出 a) 目的:基礎PWM輸出,以與中斷配合應用。輸出選用PB1,配置為TIM3_CH4,是目標板的LED6控制腳。 b) 對于簡單的PWM輸出應用,暫時無需考慮TIM1的高級功能之區(qū)別。 c) 初始化函數定義: void TIM_Configuration(void); //定義TIM初始化函數 d) 初始化函數調用: TIM_Configuration(); //TIM初始化函數調用 e) 初始化函數,不同于前面模塊,TIM的初始化分為兩部分——基本初始化和通
65、道初始化: void TIM_Configuration(void)//TIM初始化函數 { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;//定時器初始化結構 TIM_OCInitTypeDef TIM_OCInitStructure;//通道輸出初始化結構 //TIM3初始化 TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //周期0~FFFF TIM_TimeBaseStructure.TIM_Prescaler = 5; //時鐘分
66、頻 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //時鐘分割 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //基本初始化 TIM_ITConfig(TIM3, TIM_IT_CC4, ENABLE);//打開中斷,中斷需要這行代碼 //TIM3通道初始化 TIM_OCStructInit(& TIM_OCInitStructure); //默認參數 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //工作狀態(tài) TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Ena
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
5. 裝配圖網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。