嵌入式技術及應用(STM32CubeMX版)課件 任務4 制作跑馬燈_第1頁
嵌入式技術及應用(STM32CubeMX版)課件 任務4 制作跑馬燈_第2頁
嵌入式技術及應用(STM32CubeMX版)課件 任務4 制作跑馬燈_第3頁
嵌入式技術及應用(STM32CubeMX版)課件 任務4 制作跑馬燈_第4頁
嵌入式技術及應用(STM32CubeMX版)課件 任務4 制作跑馬燈_第5頁
已閱讀5頁,還剩36頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

任務4制作跑馬燈任務要求GPIO口的PE口外接8只發光二極管的控制電路,發光二極管采用低電平有效控制,8只發光二極管的編號依次為LED1~LED8。要求用STM32CubeMX對STM32進行適當配置,然后生成Keil工程代碼,再在Keil中適當地添加代碼,使8只發光二極管呈跑馬燈方式顯示。跑馬燈中發光二極管的顯示情況如下表所示,表中“█”表示當前被點亮的發光二極管。時間點亮的發光二極管t0LED8LED7LED6LED5LED4LED3LED2█t1LED8LED7LED6LED5LED4LED3█LED1t2LED8LED7LED6LED5LED4█LED2LED1t3LED8LED7LED6LED5█LED3LED2LED1t4LED8LED7LED6█LED4LED3LED2LED1t5LED8LED7█LED5LED4LED3LED2LED1t6LED8█LED6LED5LED4LED3LED2LED1t7█LED7LED6LED5LED4LED3LED2LED1知識儲備

1.位操作運算的應用C語言中有6種位操作運算,如右表所示。位操作運算中,取反運算“~”是單目運算,其他5個運算符均為雙目運算符。位操作運算要求參與運算的對象為整型或者字符型,不能是浮點型。運算符含義優先級~對操作數按位取反第2級>>將操作數右移若干位第5級<<將操作數左移若干位&兩操作數按位相與第8級^兩操作數按位異或第9級|兩操作數按位相或第10級位操作運算符1.位操作運算的應用

用X表示一位取值任意的二進制數,位運算的法則如下表所示。位運算說明0&X=0X和0相與,結果為01&X=XX和1相與,結果不變0|X=XX和0相或,結果不變1|X=1X和1相或,結果為10^X=XX和0相異或,結果不變1^X=~XX和1相異或,結果為X的反~0=10的反是1~1=01的反是0位運算法則1.位操作運算的應用

左移運算符“<<”和右移運算符“>>”的作用是,將運算符左邊的操作數的各位二進制位全部左移或右移若干位。移位后,空白位補0,舍棄溢出位,所移的位數由運算符右邊的表達式給出。例如,“a=a>>3;”的含義就是,將a中的數右移3位,若a=0x5a(01011010B),則語句執行后,a的值為0x0b(00001011B)。“a=a<<2;”的含義則是,將a中的數左移2位,若a=0x5a(01011010B),則語句執行后,a的值為0x68(01101000B)。對一個變量進行位操作運算后,并不改變變量的值,只有將位操作運算的結果再賦給該變量后才改變變量的值。例如:unsigned char a,b=0x5a; a=b<<2; //語句執行后,b=0x5a,a=0x681.位操作運算的應用

位操作運算在單片機應用程序設計中應用非常廣泛。按位與常用來將一個變量的某些位清0,而保持其他位不變。其方法是,將變量和一個常數按位相與,常數按以下方法設置:保持不變的位取1,清0位取0。將變量a的某些位清0的算法如下:a&=~(1<<i); //將變量a的第i位清0a&=~((1<<i)|(1<<j)); //將變量a的第i位、第j位清0例如,將變量a的第1、3、5位清0的程序段如下:a&=~((1<<1)|(1<<3)|(1<<5)); //將變量a的第1、3、5位清011.位操作運算的應用

按位或常用來將一個變量的某些位置1,而保持其他位不變。其方法是,將變量和一個常數按位相或,常數按以下方法設置:保持不變的位取0,置1位取1。將變量a的某些位置1的算法如下:a|=1<<i; //將變量a的第i位置1a|=(1<<i)|(1<<j); //將變量a的第i位、第j位置11.位操作運算的應用

按位異或常用來對一個變量的某些位取反,而保持其他位不變。其方法是,將變量和一個常數按位異或,常數按以下方法設置:保持不變的位取0,取反的位取1。將變量a的某些位取反的算法如下:a^=1<<i; //將變量a的第i位取反a^=(1<<i)|(1<<j); //將變量a的第i位、第j位取反1.位操作運算的應用

移位運算常用于串行數據傳輸中接收或者發送數據。另外,對于一個二進制數來說,左移n位相當于該數乘以2n,右移n位相當于該數除以2n,利用這一性質可以用移位來做快速乘除法。在單片機應用程序設計中常用到循環移位。對于一個字符型變量a,循環左移n(0<n<8)位的含義是,將a向左移n位,高位溢出位補到低位空白位中,其算法是:a=(a<<n)|(a>>(8-n));//a左移n位,a右移8-n位,兩移位的結果相或后再賦給變量a。1.位操作運算的應用

例如,a的值為0x5a(01011010B),將a循環左移3位時(n=3),a<<3的值為0xd0(11010000B),a>>(8-3)的值為0x02(00000010B),(a<<3)|(a>>(8-3))的值為11010000B|00000010B=11010010B=0xd2。對于一個字符型變量a,循環右移n(0<n<8)位的含義是,將a向右移n位,高位溢出位補到高位空白位中,其算法是:a=(a>>n)|(a<<(8-n));//a右移n位,a左移8-n位,兩移位的結果相或后再賦給變量a。2.GPIO口的并行輸出

用HAL_GPIO_WritePin()函數實現GPIO口并行輸出的方法是,先向輸出控制端口寫入使輸出控制無效的控制數據,再向端口寫入所要的控制輸出數據。例如,用PE0~PE7控制LED1~LED8共8只發光二極管顯示,發光二極管采用低有效控制,實現LED1、LED3點亮而其他6只發光二極管熄滅的程序段如下:HAL_GPIO_WritePin(GPIOE,0xff,GPIO_PIN_SET); /*8只發光二極管的控制端輸出高電平,8只發光二極管呈無效狀態*/HAL_GPIO_WritePin(GPIOE,(1<<0)|(1<<2),GPIO_PIN_RESET); /*輸出控制數據,LED1、LED3點亮*/(1)用HAL_GPIO_WritePin()函數實現2.GPIO口的并行輸出

在HAL庫中,GPIO口是用結構體指針變量GPIOx(x為A~G,下同)表示的,它的輸出數據寄存器ODR表示為GPIOx->ODR,輸出數據寄存器必須以16位的方式訪問。通過訪問輸出數據寄存ODR來實現并行輸出的方法是,對ODR寄存器進行“讀-修改-寫”操作,具體的步驟如下:第1步:將ODR寄存器內容讀出。第2步:應用位操作運算,將需要并行輸出的控制位改成所要輸出的數據,而保持其他位不變。第3步:將變換后的數據寫入ODR寄存器。(2)直接訪問輸出數據寄存器ODR2.GPIO口的并行輸出

【舉例】例如,用PE0~PE7控制LED1~LED8共8只發光二極管顯示,發光二極管采用低有效控制,實現LED2、LED4、LED6點亮而其他5只發光二極管熄滅的程序段如下:uint16_t odr; //定義變量odr,用于保存ODR寄存器的值odr=GPIOE->ODR; //讀ODR寄存器的內容odr|=0x00ff; //高8位不變,低8位設置成8只發光二極管熄滅的控制數據odr&=~((1<<1)|(1<<3)|(1<<5)); //1、3、5位清0,得輸出控制數據GPIOE->ODR=odr; //控制數據寫入ODR寄存器中2.GPIO口的并行輸出

上述要求也可以用以下程序段來實現:uint16_t odr; //定義變量odr,用于保存ODR寄存器的值odr=GPIOE->ODR; //讀ODR寄存器的內容odr&=0xff00; //高8位不變,低8位設置成8只發光二極管點亮的控制數據odr|=(1<<0)|(1<<2)|(1<<4)|(1<<6)|(1<<7);//0、2、4、6、7位置1,得輸出控制數據GPIOE->ODR=odr; //控制數據寫入ODR寄存器中實現方法與步驟任務4的硬件電路:

1.搭建電路2.生成GPIO口的初始化代碼任務4中生成GPIO口初始化代碼的操作方法與任務2中的操作方法相同,產生GPIO初始化代碼的步驟如下:(1)啟動STM32CubeMX,然后新建STM32CubeMX工程、配置SYS、RCC,其中,Debug模式選擇SerialWire,HSE選擇外部晶振,再配置時鐘,其配置結果與任務2中對應的部分完全相同。(2)將PE0~PE7引腳配置成GPIO輸出口,輸出電平為高電平、推挽輸出、無上拉也無下拉、高速輸出、無用戶標簽。(3)配置時鐘,其配置結果與任務2中對應的部分完全相同。(4)配置STM32CubeMX工程。其中,工程名為Task4,其他配置項與任務2中的配置相同。(5)保存工程,然后生成Keil工程代碼。

3.編寫跑馬燈程序任務4中在main.c文件中編寫跑馬燈控制程序,其代碼詳見鏈接。

【說明】第8~9行代碼也可以用訪問ODR寄存器的方式實現。按照程序編寫規范將上述程序代碼填寫至main.c文件的對應位置處,即得跑馬燈控制程序,其實現步驟如下:(1)打開Keil工程,然后打開main.c文件。3.編寫跑馬燈程序(2)在main.c文件的“USERCODEBEGIN1”與“USERCODEEND1”之間(用戶代碼1區)添加第4行代碼,如圖所示。第4行代碼的功能是,定義變量m,并對其賦初值。變量m用來保存發光二極管的狀態,其初始狀態為最低位亮,其他的熄滅,m的初值為0x01。

定義變量3.編寫跑馬燈程序(3)在main.c文件的while代碼區中添加第8~11行代碼,如圖所示。(4)點擊圖標工具欄上的保存文件圖標按鈕“”,保存main.c文件。

跑馬燈程序代碼4.配置Keil工程在任務4中,Keil工程的配置主要是配置調試器。其目的是,保證Keil中能用仿真器下載和調試程序。配置調試器的步驟如下:第1步:將USB線插入開發板上的USB座,USB線的另一端插入計算機的USB座,給開發板上電,此時開發板上的電源指示燈點亮。第2步:將ST-Link仿真器與開發板相連,并將仿真器插入計算機的USB口中。4.配置Keil工程第3步:按照任務2中介紹的方法打開“OptionforTarget”對話框,并在“OptionforTarget”對話框中單擊“Debug”標簽,進入如圖所示的Debug頁面。Debug頁面4.配置Keil工程第4步:在Debug頁面中單擊“Use”單選鈕,再在“Use”右邊的下拉列表框中選擇“ST-LinkDebugger”列表項,然后單擊列表框右邊的“Settings”按鈕,打開如圖所示的“Cortex-MTargetDriverSetup”對話框。“Cortex-MTargetDriverSetup”對話框4.配置Keil工程【說明】在“Cortex-MTargetDriverSetup”對話框中,“DebugAdapter”框架下面的“Unit”下拉列表框中顯示的是第2步中所插入仿真器的型號。任務2中我們使用仿真器是ST-Link,所以“Unit”下拉列表框中顯示的是“ST-LINK/V2”。如果下拉列表框中無仿真器顯示,其原因是仿真器與計算機的USB口接觸不良或者仿真器沒插入計算機的USB口,此時可重新插入仿真器試一試。如果“SWDevice”框架中顯示的SWDIO名稱和識別碼錯誤,或者無顯示,其原因是仿真器與開發板的連接線接觸不良或者無連接,此時可重新插撥一下仿真器與開發板之間的連接線。4.配置Keil工程第5步:在右圖所示的對話框中單擊“FlashDownload”標簽,進入FlashDownload頁面,如圖所示。然后在FlashDownload頁面中勾選“ResetandRun”復選框,再單擊“確定”按鈕,返回至“OptionforTarget”對話框中。第6步:在“OptionforTarget”對話框中單擊“OK”按鈕,完成調試器的配置。FlashDownload頁面5.編譯與下載程序調試程序的目的是為了查找程序中的邏輯錯誤,而不是努力地證明程序是正確的。調試程序的方法是,跟蹤程序的運行,查看程序運行的結果。在調試的過程中需要在程序中設置斷點,采取全速運行、單步運行、過程單步等多種運行方式反復運行程序,在程序運行的過程中觀察相關變量的值。調試與下載程序的步驟如下:(1)按照任務2中所介紹的方法編譯程序。

5.編譯與下載程序(2)單擊圖標工具欄上的開始/停止調試圖標按鈕“”,或者單擊菜單欄上的“Debug”→“Start/StopDebugSession”子菜單項,Keil5就會將編譯后的程序通過仿真器下載至開發板中,同時進入調試狀態。在調試狀態下,Keil的窗口將會發生一系列的變化。其中,Debug菜單中的“Run”、“Stop”、“Step”、“StepOver”等幾個灰色不可執行的子菜單項將變成黑色可執行狀態。Keil的工具欄中會出現許多調試工具圖標按鈕,如圖所示,這些調試工具圖標按鈕的功能與Debug菜單中的菜單項相對應。

Register窗口中顯示單片機內部的寄存器運行單步執行完當前函數箭頭指示當前程序執行處命令窗口CallStack+Locals窗口顯示函數調用關系和函數內變量值反匯編窗口一般關閉開始/停止調試灰條表示所在行為可執行代碼調試工具按鈕運行到光標行復位暫停過程單步調試狀態5.編譯與下載程序(3)顯示觀察窗口。觀察窗口包括Locals、Watch1和Watch2三個觀察窗口。其中Locals窗口用來顯示當前執行函數中的變量值,Watch1窗口和Watch2的功能相同,用來顯示指定變量的當前值。顯示Locals窗口的方法是,單擊調試工具欄上的圖標按鈕“”,或者單擊菜單欄上的“View”→“CallStackWindow”菜單命令。Locals窗口如圖所示。在圖中,當前執行的是main()函數,Local窗口中顯示的是STM32在執行到箭頭所指行(第100行)時,main()函數中各變量的值。當前函數中的變量及其值CallStack+Locals觀察窗口顯示CallStack窗口顯示Watch窗口Locals窗口5.編譯與下載程序顯示Watch1窗口的方法是,單擊菜單欄上的“View”→“WatchWindow”→“Watch1”菜單命令或者在調試工具欄上單擊觀察窗口圖標按鈕“”右邊的下拉箭頭“”,在彈出的快捷菜單中單擊“Watch1”菜單命令。Watch1窗口如圖所示。在Watch1窗口中被顯示的變量必須由用戶指定,可以是本地變量,也可是全局變量。指定觀察變量的方法是,在Watch1窗口中雙擊“Enterexpression”使窗口中的字符呈藍底白字的反向顯示,再輸入所要觀察的變量名,然后單擊窗口中的空白處。顯示Watch2窗口的方法與顯示Watch1窗口的方法相同。Watch1窗口5.編譯與下載程序(4)設置斷點。設置斷點的目的是,讓程序運行至指定行后暫停運行,以便用戶觀察程序運行的結果。斷點的設置方法是,在源程序窗口中,用鼠標左鍵單擊需要程序停止運行的行,再單擊圖標工具欄上的斷點設置按鈕“”或者用左鍵單擊菜單欄上的“Debug”→“Insert/RemoveBreakpoint”菜單命令,這時光標所在行的右邊會出現一個紅色的園點,用來指示斷點行。(5)選擇程序的運行方式并運行程序。在Keil中調試程序時需要控制程序的運行方式,以便在程序的運行過程中觀察運行的結果。控制程序運行的菜單命令有6個,位于Debug菜單中,在調試工具欄中有6個調試圖標按鈕與這6個控制程序運行的菜單命令相對應。5.編譯與下載程序

控制程序運行的命令圖標按鈕Debug的菜單命令快捷鍵功能說明

RunF5全速運行程序不間斷運行,遇到斷點后停止運行,用于模擬調試中觀察斷點處程序運行結果或者在仿真調試中觀察單片機系統的運行結果

StepF11單步運行只執行箭頭所指行中的語句,若箭頭所指行為函數調用語句,則進入被調函數中。用于逐條查看被調函數中各語句的執行結果。

StepOverF10過程單步只執行箭頭所指行中的語句,若箭頭所指行為函數調用語句,則把調用函數看作成一條語句來執行,而不進入被函數中。用于逐條查看函數中各語句的執行結果。

RuntocursorCtrl+F10運行至光標處從箭頭所指行執行至光標所在行。用于快速執行一段程序。

StepoutofcurrentfunctionCtrl+F11執行完當前函數執行完整個函數體后暫停運行。用于查看函數運行的結果。

StopRunningESC停止運行5.編譯與下載程序

(6)單擊圖標工具按鈕“”或者按ESC鍵,停止程序運行,單擊“”按鈕,系統會退出調試狀態返回編輯狀態。如果需要觀察程序運行至第101行時的狀態,并修改變量m的值,可以按以下方法進行操作:①在編輯窗口中單擊工具欄上的“開始/停止調試”圖標按鈕“”,進入調試狀態。②在第101行代碼處設置斷點。③在調試狀態下打開watch1窗口,然后在watch1窗口中輸入要觀察的變量m。5.編譯與下載程序

④單擊調試工具欄中的全速運行圖標按鈕“”,程序運行至第101行就會停下來,各窗口中會顯示單片機執行了第100行代碼后的狀態,包括各寄存器的值、watch1中變量m的值等。⑤在Watch1窗口中選中變量m的值,再修改其值,例如將m的值改為0x03,再單擊調試工具欄上的全速運行圖標按鈕“”,可以看到程序以修改后的狀態為基礎來設置發光二極管的狀態。如果程序有誤,則返回編輯窗口中修改程序,然后再編譯調試,直至程序正確。⑥取消第101行處的斷點,再單擊停止調試“”圖標按鈕,返回至程序編輯窗口。⑦單擊窗口上的關閉按鈕,關閉Keil,結束程序調試,可以看到8只發光二極管按改后的方式進行顯示。實踐總結與拓展

查表程序的設計方法是,利用一維數組的下標與元素值的對應關系,將事先計算好的結果值依次存放在數組中,需要結果值時直接查閱數組,并從數組中讀取對應元素的值。利用查表程序可以方便地解決數學運算無法解決的數據轉換問題。用HAL_GPIO_WritePin()函數設置GPIO引腳狀態時,其實質是將控制數據中為1位所對應的引腳設置成指定狀態(高電平或者低電平狀態),各時間段發光二極管的顯示控制數據如下表所示。1.用查表法實現跑馬燈顯示時間發光二極管的狀態HAL_GPIO_WritePin()函數中的控制數據二進制十六進制t0LED1亮,其他熄滅000000010x01t1LED2亮,其他熄滅000000100x02t2LED3亮,其他熄滅000001000x04t3LED4亮,其他熄滅000010000x08t4LED5亮,其他熄滅000100000x10t5LED6亮,其他熄滅001000000x20t6LED7亮,其他熄滅010000000x40t7LED8亮,其他熄滅100000000x801.用查表法實現跑馬燈顯示

將發光二極管在t0~t7共8個時間段的顯示控制數據按照其先后順序事先存放在數組ledcode[]中,用查表法就可以獲得各時間的顯示控制數據。數組ledcode[]的定義如下:uint8_tledcode[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};用變量i作時間計數器,很顯然ti時間的顯示控制數據為ledcode[i],因此i也可叫數組的下標記數器,i的取值范圍為0~7。1.用查表法實現跑馬燈顯示

去掉硬件初始化代碼后,用查表法實現跑馬燈的程序如下:…uint8_tledcode[]={0x01,0x02,0x04,0x08,//發光二極管控制數據 0x10,0x20,0x40,0x80};//為1位亮…int main(void){uint8_ti=0;//時間計數器…while(1){ HAL_GPIO_WritePin(GPIOE,0xff,GPIO_PIN_SET); //滅所有發光二極管HAL_GPIO_WritePin(GPIOE,ledcode[i],GPIO_PIN_RESET);//點亮1位的發光二極管i++; //時間計數加1,準備取下一時間的顯示數據if(i>7)i=0; //超界處理 HAL_Delay(500); //延時0.5s}}1.用查表法實現跑馬燈顯示

按照上述設計,用查表法實現跑馬燈顯示的步驟如下:(1)用STM32CubeMX生成GPIO口的初始化代碼,然后打開Keil工程。(2)在main.c文件的用戶變量區中定義數組ledcode[],如下圖所示。(3)在main.c文件的用戶代碼1區定義時間計數器i,并對其賦初值0,如下圖所示。1.用查表法實現跑馬燈顯示(4)在main.c文件的while代碼區中添加用查法編制的跑馬燈程序代碼,如下圖所示。(5)保存main.c文件,然后編譯下載程序,我們就可以看到8只發光二極管就呈跑馬燈方式顯示。2.用訪問ODR寄存器的方式實現跑馬燈顯示

用讀-修改-寫ODR寄存器的方式實現并行輸出時,寫入ODR寄存器的數據與GPIO口引腳的狀態是直接對應的。寫入的數位為1時,對應的引腳就為高電平,寫入的數位為0時,對應的引腳就為低電平。本任務中,發光二極管采用低電平有效控制,GPIO口引腳的狀態為低電平時,引腳上的發光二極管就點亮。所以,寫入ODR寄存器的控制數如下表所示。時間發光二極管的狀態寫入ODR寄存器的控制數據二進制十六進制t0LED1亮,其他熄滅11111110

溫馨提示

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

最新文檔

評論

0/150

提交評論