天津大學(xué)嵌入式系統(tǒng)——Traffic實(shí)驗(yàn)_第1頁(yè)
天津大學(xué)嵌入式系統(tǒng)——Traffic實(shí)驗(yàn)_第2頁(yè)
天津大學(xué)嵌入式系統(tǒng)——Traffic實(shí)驗(yàn)_第3頁(yè)
天津大學(xué)嵌入式系統(tǒng)——Traffic實(shí)驗(yàn)_第4頁(yè)
天津大學(xué)嵌入式系統(tǒng)——Traffic實(shí)驗(yàn)_第5頁(yè)
已閱讀5頁(yè),還剩18頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、Traffic實(shí)驗(yàn)一、 建立Keil工程1. 選擇ProjectNew uVision Project命令,彈出Create New Project 對(duì)話框,指定工程路徑并在文件名文本框中輸入Traffic,如圖1所示。圖12. 單擊“保存”按鈕,彈出Select Device for Target 窗口,在左側(cè)的列表框中選擇CPU的類型(STM32F10系列),右邊對(duì)應(yīng)出現(xiàn)該芯片的資源描述,如圖2所示。圖23. 單擊OK按鈕,出現(xiàn)如圖3所示提示信息(是否復(fù)制啟動(dòng)代碼到工程文件夾并添加文件到工程中)。這里的啟動(dòng)代碼是依據(jù)設(shè)置的編譯器而生成的。圖34. 單擊是按鈕添加啟動(dòng)代碼,此時(shí)啟動(dòng)代碼已經(jīng)添

2、加到工程中,左側(cè)的Project Workspace 中顯示添加的啟動(dòng)代碼文件,雙擊Startup.s可查看代碼,如圖4所示。圖45. 添加如圖5所示實(shí)驗(yàn)所需文件夾和文件。圖5二、 進(jìn)行工程配置1. 在工作空間選擇Target1 右鍵選擇Options for TargetTarget1命令,彈出對(duì)話框如圖6所示,設(shè)置Xtal為8MHz。圖6(此后步驟本來(lái)想做電路仿真的,但發(fā)現(xiàn)proteus里沒(méi)有stm32系列芯片)2. 單擊Output標(biāo)簽,再單擊Create Hex File前面的單選按鈕,如圖7所示。可生成hex格式可執(zhí)行文件,再單擊Select Folder for Objects按鈕

3、,指定輸出文件路徑。圖73. 單擊Listing標(biāo)簽,再單擊Select Folder for Listings按鈕,指定生成的list文件的輸出路徑,然后單擊Assembler Listing和Linker Listing前面的單選按鈕,如圖8所示。圖84. 單擊Linker標(biāo)簽,設(shè)定鏈接器參數(shù),指定Linker Script文件的路徑,如圖9所示,單擊Edit按鈕對(duì)Flash.ld文件進(jìn)行編輯。圖95. 單擊OK按鈕保存設(shè)置。三、 Build目標(biāo)在工作空間右鍵單擊選擇Build Target或者按F7鍵,編譯并鏈接工程,輸出窗口如圖10所示。圖10四、 程序仿真1.交通信號(hào)燈的五種狀態(tài)(正

4、常運(yùn)行:在起始時(shí)間和結(jié)束時(shí)間之內(nèi))狀態(tài)車輛交通燈行人交通燈解釋紅燈黃燈綠燈StopWalk100110車輛通行,行人禁行201010車???10010車輛禁行,行人準(zhǔn)備通行410001車輛禁行,行人通行510010行人禁行,車輛準(zhǔn)備通行611010行人禁行,車輛準(zhǔn)備通行狀態(tài)1 程序仿真截圖狀態(tài)2 程序仿真截圖狀態(tài)3 程序仿真截圖狀態(tài)4 程序仿真截圖狀態(tài)5 程序仿真截圖狀態(tài)6程序仿真截圖2.按下按鈕(S2: Push for Walk)后程序啟動(dòng)行人自助服務(wù)(相當(dāng)于中斷),進(jìn)入狀態(tài)2狀態(tài)3狀態(tài)4(行人通過(guò)),之后恢復(fù)正常。(正常運(yùn)行時(shí)間之內(nèi))3.異常運(yùn)行:時(shí)間超出起始時(shí)間和結(jié)束時(shí)間,黃燈閃爍。4

5、.菜單操作:D:顯示當(dāng)前時(shí)間T:設(shè)置當(dāng)前時(shí)間S:設(shè)置起始時(shí)間E:設(shè)置結(jié)束時(shí)間下面依次進(jìn)行這四個(gè)操作錯(cuò)誤輸入操作:5程序流程圖開始調(diào)用SER_Init,LED_Init,KBD_Init 初始化硬件配置,調(diào)用os_sys_init (init)初始化系統(tǒng)任務(wù)Clock任務(wù),定時(shí)器(計(jì)時(shí)器)command命令符操作任務(wù)(串口輸入命令符)lignts任務(wù),正常運(yùn)行信號(hào)燈順序控制鍵盤掃描任務(wù),捕捉是否有鍵按下Command任務(wù)流程圖ESC開始Print操作菜單Print “Command”讀操作命令并轉(zhuǎn)換大小寫Switch操作符=D,顯示時(shí)間=T,設(shè)置當(dāng)前時(shí)間=E,設(shè)置結(jié)束時(shí)間=S,設(shè)置起始時(shí)間def

6、ault,print操作菜單Print“type ESC to abort”等待ESC命令延時(shí)50ticks延時(shí)250ticks延時(shí)50ticks延時(shí)50ticks是,延時(shí)50ticks否,延時(shí)800ticks延時(shí)50tickst_lights改變?否否查詢是開始所有燈初始為滅檢查時(shí)間是否在起始時(shí)間和結(jié)束時(shí)間之內(nèi)Signalon函數(shù)退出lights任務(wù),進(jìn)入blinking任務(wù)Blinking任務(wù)初始化燈全滅異常狀態(tài),黃燈閃爍檢查時(shí)間是否在起始時(shí)間和結(jié)束時(shí)間之內(nèi)是狀態(tài)6狀態(tài)1按鍵?key_read 鍵盤掃描任務(wù)狀態(tài)2狀態(tài)3狀態(tài)4狀態(tài)5Lights任務(wù)流程圖五、 程序分析1. Startup F

7、ilesStartup Files 顧名思義為系統(tǒng)啟動(dòng)文件夾。2. RTX Configuration串口配置文件。3. System FilesRetarget.c為系統(tǒng)重定義系統(tǒng)的基本IO函數(shù)Serial.c為串口基礎(chǔ)程序,下面具體分析這個(gè)程序代碼:串口初始化程序(定義端口,配置波特率)void SER_Init (void) #ifndef _DBG_ITM int i; RCC->APB2ENR |= ( 1UL << 0); /* 使能時(shí)鐘備用功能*/ AFIO->MAPR &= ( 1UL << 2); /* 清除UART1重映射*/ R

8、CC->APB2ENR |= ( 1UL << 2); /* 使能GPIOA*/ GPIOA->CRH &= (0xFFUL << 4); /* PA9,PA10清零*/ GPIOA->CRH |= (0x0BUL << 4); /* USART1 Tx(PA9)推挽輸出*/ GPIOA->CRH |= (0x04UL << 8); /* USART1 Rx (PA10)懸空*/ RCC->APB2ENR |= ( 1UL << 14); /* 使能USART1*/ /* 設(shè)置波特率為115200

9、,8位數(shù)據(jù)有效位,1位停止位*/ USART1->CR1 = 0x002C; /* 使能RX,TX端口*/ USART1->CR2 = 0x0000; USART1->CR3 = 0x0000; USART1->BRR = 0x0271; for (i = 0; i < 0x1000; i+) _NOP(); USART1->CR1 |= 0x2000; /* 使能USART*/#endif串口發(fā)送程序int SER_PutChar (int c) #ifdef _DBG_ITM ITM_SendChar(c);#else while (!(USART1-&

10、gt;SR & USART_SR_TXE); USART1->DR = (c & 0x1FF);#endif return (c);串口接收程序int SER_GetChar (void) #ifdef _DBG_ITM while (ITM_CheckChar() != 1) _NOP(); return (ITM_ReceiveChar();#else while (!(USART1->SR & USART_SR_RXNE); return (USART1->DR & 0xFF);#endif串口接收檢驗(yàn)程序(是否收到)int SER_Ch

11、eckChar (void) #ifdef _DBG_ITM return (ITM_CheckChar();#else if (USART1->SR & USART_SR_RXNE) return (1); else return (0);#endif4. Source FilesLED.c LED燈基礎(chǔ)控制程序,實(shí)現(xiàn)開燈關(guān)燈操作。初始化端口void LED_Init (void) RCC->APB2ENR |= (1UL << 3); /* 使能端口GPIOB*/ GPIOB->ODR &= 0x0000FF00; /* 所有燈初始為滅*/ G

12、PIOB->CRH &= 0xFFFFFFFF; GPIOB->CRH |= 0x33333333;開燈函數(shù)void LED_On (unsigned int num) if (num < LED_NUM) GPIOB->BSRR = led_masknum; 關(guān)燈函數(shù)void LED_Off (unsigned int num) if (num < LED_NUM) GPIOB->BRR = led_masknum; LED輸出控制函數(shù)(本實(shí)驗(yàn)中未使用)void LED_Out(unsigned int value) int i; for (i =

13、 0; i < LED_NUM; i+) if (value & (1<<i) LED_On (i); else LED_Off(i); Getline.c 字符串輸入操作程序void getline (char *line, int n) int cnt = 0; char c; do if (c = SER_GetChar() = CR) c = LF; /* 讀字符串*/ if (c = BACKSPACE | c = DEL) if (cnt != 0) cnt-; line-; putchar (BACKSPACE); putchar (' '

14、;); putchar (BACKSPACE); else if (c != CNTLQ && c != CNTLS) putchar (*line = c); line+; cnt+; while (cnt < n - 1 && c != LF); *(line - 1) = 0; Traffic.c程序分析系統(tǒng)操作菜單(見(jiàn)仿真測(cè)試)const char menu = "n" "+* TRAFFIC LIGHT CONTROLLER using RVCT and RTX kernel *+n" "| Th

15、is program is a simple Traffic Light Controller. Between |n" "| start time and end time the system controls a traffic light |n" "| with pedestrian self-service. Outside of this time range |n" "| the YELLOW caution lamp is blinking. |n" "+ command -+ syntax -+

16、function-+n" "| Display | D | display times |n" "| Time | T hh:mm:ss | set clock time |n" "| Start | S hh:mm:ss | set start time |n" "| End | E hh:mm:ss | set end time |n" "+-+-+-+n"操作命令D、T、S、E對(duì)應(yīng)如上圖所示struct time ctime = 12, 0, 0 ; /*定義系統(tǒng)當(dāng)前時(shí)間為12:

17、00:00*/struct time start = 7, 30, 0 ; /*定義系統(tǒng)起始時(shí)間為7:30:00*/struct time end = 18, 30, 0 ; /* 系統(tǒng)結(jié)束時(shí)間為18:30:00*/#define RED 0 定義狀態(tài)對(duì)應(yīng)操作符#define YELLOW 1 #define GREEN 2 #define STOP 4 #define WALK 5 #define key 0x002000 自主服務(wù)IO入口地址(S2)char cmdline16; /* 命令符存儲(chǔ)空間*/struct time rtime; /* 輸入時(shí)間暫存地址*/BIT display

18、_time = _FALSE; BIT escape; #define ESC 0x1B /* 退出地址*/static U64 cmd_stack800/8; /* 申請(qǐng)一個(gè)命令存放堆棧*/_task void init (void); /* 系統(tǒng)任務(wù)*/_task void clock (void) ;_task void get_escape (void);_task void command (void);_task void blinking (void);_task void lights (void);_task void keyread (void);鍵盤配置函數(shù)(初始化)vo

19、id KBD_Init (void) RCC->APB2ENR |= (1UL << 2) | (1UL << 4); /* 使能GPIOA GPIOC*/ GPIOA->CRL &= 0x0000000F; /* PA.0清零*/ GPIOA->CRL |= 0x00000004; /* PA.0 配置為懸浮輸入*/ GPIOC->CRH &= 0x00F00000; /* PC.13清零*/ GPIOC->CRH |= 0x00400000; /* PC.13 配置為懸浮輸入*/燈操作函數(shù)void SetLights (

20、U32 light, U32 on) if (on = 0) LED_Off (light); /*調(diào)用的是LED.c 中的LED_Off和 LED_On*/ else LED_On (light); int main (void) /* 主函數(shù)*/ SER_Init (); /* 調(diào)用了Serial.c中串口初始化程序*/ LED_Init (); /* 調(diào)用了LED.c中端口初始化程序*/ KBD_Init (); /* 調(diào)用鍵盤初始化程序*/ os_sys_init (init); /* 調(diào)用init(init)函數(shù)(系統(tǒng)函數(shù))*/任務(wù)初始化任務(wù)(os_task_create創(chuàng)建一個(gè)任務(wù)

21、)_task void init (void) t_clock = os_tsk_create (clock, 0); t_command = os_tsk_create_user (command,0,&cmd_stack,sizeof(cmd_stack); t_lights = os_tsk_create (lights, 0); t_keyread = os_tsk_create (keyread,0); os_tsk_delete_self (); /*任務(wù)刪除(自己)函數(shù)*/定時(shí)器任務(wù)(計(jì)時(shí)器)_task void clock (void) os_itv_set (100)

22、; /* 等待時(shí)間間隔1s*/ while (1) /* 函數(shù)在此內(nèi)無(wú)限循環(huán),計(jì)時(shí)*/ if (+ctime.sec = 60) /*60秒進(jìn)位1分*/ ctime.sec = 0; if (+ctime.min = 60) /*60分進(jìn)位1小時(shí)*/ ctime.min = 0; if (+ctime.hour = 24) /*24小時(shí)進(jìn)位為1天*/ ctime.hour = 0; if (display_time) /* display_time初始為False,系統(tǒng)命令更改后改變,為True時(shí)才進(jìn)入*/ os_evt_set (0x0001,t_command);/* 設(shè)置t_comman

23、d表征時(shí)間改變*/ os_itv_wait (); 時(shí)間修改錄入函數(shù)(針對(duì)時(shí)間更改后)char readtime (char *buffer) int args; int hour,min,sec; rtime.sec = 0; /*輸入的時(shí)間秒置零*/ args = sscanf (buffer, "%d:%d:%d", /* 復(fù)制buffer數(shù)據(jù)到args*/ &hour, &min, &sec); if (hour > 23 | min > 59 | /* 檢驗(yàn)時(shí)間是否正確*/ sec > 59 | args < 2 )

24、 printf ("n* ERROR: INVALID TIME FORMATn"); return (0); rtime.hour = hour; rtime.min = min; rtime.sec = sec; return (1);退出任務(wù)(退出此時(shí)時(shí)間操作)_task void get_escape (void) while (1) if (SER_GetChar () = ESC) /*SER_GetChar調(diào)用自Serial.c*/ escape = _TRUE; os_evt_set (0x0002, t_command); /* 發(fā)現(xiàn)ESC字符就退出*/

25、命令符處理任務(wù)_task void command (void) U32 i; printf (menu); /* 打印出菜單*/ while (1) printf ("nCommand: "); /* 輸出“Command”提示*/ getline (cmdline, sizeof (cmdline); /* 獲得輸入命令*/ for (i = 0; cmdlinei != 0; i+) /* 轉(zhuǎn)換為大寫字母*/ cmdlinei = (char) toupper(cmdlinei); for (i = 0; cmdlinei = ' ' i+); /*

26、跳過(guò)空字符*/ switch (cmdlinei) /* 選擇執(zhí)行命令*/ case 'D': /*顯示當(dāng)前時(shí)間命令*/ printf ("Start Time: %02d:%02d:%02d " "End Time: %02d:%02d:%02dn", start.hour, start.min, start.sec, end.hour, end.min, end.sec); printf (" type ESC to abortr"); t_getesc = os_tsk_create (get_escape, 0

27、);/* 檢查是否退出*/ escape = _FALSE; /* 清除退出標(biāo)志*/ display_time = _TRUE; /*設(shè)置顯示時(shí)間標(biāo)志*/ os_evt_clr (0x0003, t_command); /* 改變命令標(biāo)志*/ while (!escape) /* 如果未退出*/ printf ("Clock Time: %02d:%02d:%02dr", /* 顯示時(shí)間*/ ctime.hour, ctime.min, ctime.sec); os_evt_wait_or (0x0003, 0xffff); /* 等待改變或退出*/ os_tsk_dele

28、te (t_getesc); /* 終止退出程序*/ display_time = _FALSE; /* 清除顯示時(shí)間標(biāo)志*/ printf ("nn"); break; case 'T': /* 設(shè)置當(dāng)前時(shí)間命令*/ if (readtime (&cmdlinei+1) /* 讀時(shí)間輸入*/ ctime.hour = rtime.hour; /* 保存為當(dāng)前時(shí)間*/ ctime.min = rtime.min; ctime.sec = rtime.sec; break; case 'E': /* 設(shè)置結(jié)束時(shí)間命令*/ if (rea

29、dtime (&cmdlinei+1) /* 讀輸入時(shí)間*/ end.hour = rtime.hour; /* 保存為結(jié)束時(shí)間*/ end.min = rtime.min; end.sec = rtime.sec; break; case 'S': /* 設(shè)置起始時(shí)間命令*/ if (readtime (&cmdlinei+1) /* 讀輸入時(shí)間*/ start.hour = rtime.hour; /* 保存為起始時(shí)間*/ start.min = rtime.min; start.sec = rtime.sec; break; default: /* 錯(cuò)誤命

30、令*/ printf (menu); /* 重新顯示菜單*/ break; 時(shí)間檢查函數(shù)(檢查當(dāng)前時(shí)間是否位于起始時(shí)間和結(jié)束時(shí)間之間)char signalon (void) if (memcmp (&start, &end, sizeof (struct time) < 0) if (memcmp (&start, &ctime, sizeof (struct time) < 0 && memcmp (&ctime, &end, sizeof (struct time) < 0) return (1); els

31、e if (memcmp (&end, &ctime, sizeof (start) > 0 && memcmp (&ctime, &start, sizeof (start) > 0) return (1); return (0); 閃爍任務(wù)_task void blinking (void) SetLights (RED, 0); 關(guān)掉所有燈 SetLights (YELLOW, 0); SetLights (GREEN, 0); SetLights (STOP, 0); SetLights (WALK, 0); while (1) SetLights (YELLOW, 1); /* 點(diǎn)亮黃燈*/ os_dly_wait (30); /* 延時(shí)30周期*/ SetLights (YELLOW, 0); /* 熄滅黃燈*/ os_dly_wait (30); /* 延時(shí)30周期*/ if (signalon () /* 如果閃爍時(shí)間結(jié)束*/ os_tsk_create (lights, 0); /* 啟動(dòng)light任務(wù)*/ os_tsk_delete_self (); /* 刪除blinking任務(wù)(自己)*

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論