通訊實驗 實驗三 遙控車程式流程圖 姓名:顏得洋 學號:B09622050
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
使用C8051撰寫程式輸出PPM訊號 總週期 煞車 方向盤 油門 x 1234
Main ( )主程式 Main( ) A System_Initial( ) B A2D( ) C PPM( ) 使用 Timer 開始計數22ms D A2D( ) E 22ms計數完成? NO YES
Main( ): 系統初始化 分別對 方向盤、油門、煞車 3個channel 做A/D轉換 開始計數22ms(總週期) 開始輸出3個channel的PPM 等待22ms計數完成 跳至步驟3
Main ( ) main( ) { System_Initial( ); // 程式初始化 A2D( ); // 對3個channel做A/D轉換 while(1) TH0 = (65536 - 22000)/256; // 計時 22ms 的 TH0 TL0 = (65536 - 22000)%256; // 計時 22ms 的 TL0 TR0 = 1; // 開啟Timer0 計數 PPM( ); // 輸出3個channel的PPM while(TF0==0); // 等待22ms計數完成 TR0 = 0; // 關閉 Timer0 計數 TF0 = 0; // 清除 Timer0 溢位旗標 } while(1),1代表是真實的.接下來就會做下列的動作 0的話就會跳出迴圈
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
使用的8051:c8051F320 Block Diagram
System_Initial ( ) System_Initial( ): 設定 Oscillator 關閉 PCA0 WDT Timer PCA0 Oscillator ADC0 I/O Port RET System_Initial( ): 設定 Oscillator 關閉 PCA0 WDT 設定 Timer 設定 ADC0 設定 I/O Port Return
System_Initial ( ) void System_Initial(void) { /* Oscillator Initial */ OSCICN=0x83; // Internal Oscillator Enabled and SYSCLK derived by 1 (P.117) CLKSEL=0x00; // Selected Clock from Internal Oscillator (P.123) /* PCA0 Initial*/ PCA0MD&=~0x40; // WDTE = 0 (clear watchdog timer enable IN ORDER TO CHANGE PCA0MD) (P.241) /* Timer Initial */ TMOD = 0x01; // Use Timer1 Mode1 and Timer0 Mode1 (P.214) /* ADC0 Initial */ AMX0P = 0x02; // Select positive channel : P1.2 (P.45) AMX0N = 0x1F; // Select negative channel : GND (ADC in Single-Ended Mode) (P.46) ADC0CF = 0xF8; // SAR clock = 31 and Data in ADC0H:ADC0L registers are right-justified (P.47) ADC0CN = 0x80; // ADC0 Enabled and ADC0 conversion initiated on every write of '1' to AD0BUSY... (P.48) REF0CN = 0x08; // VDD use as Voltage reference (P.55) /* I/O Port Initial */ P1MDIN = 0xE3; // Corresponding P1.2、P1.3 and P1.4 pin are configured as an analog input (P.133) P2MDOUT = 0x01; // Corresponding P2.0 Output is push-pull (P.135) P1SKIP = 0x1C; // Corresponding P1.2、P1.3 and P1.4 pin are skipped by the Crossbar (P.134) XBR1 = 0x40; // Crossbar enabled (P.131) }
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
A2D ( ) A2D( ) 開啟 A/D 轉換 設定 ch n 做A/D轉換 n=1 將 A/D數值 存至矩陣[n] n++ RET NO YES
A2D( ): n=1 設定 channel n 做A/D轉換 開啟A/D轉換 等待A/D轉換完成 將A/D數值存至矩陣[n]之中 n++ Return
A2D ( ) void A2D (void) { for(AMX0P=2;AMX0P<=4;AMX0P++) // 3個channel AD0BUSY=1; // 開啟 A/D 轉換 while(AD0BUSY==1); // 等待 A/D 轉換完成 adval = ADC0L + ( ADC0H << 8 ); // 計算 A/D 數值 switch(AMX0P) case 2: // 方向盤 TAD = -1.2153*adval + 1788.6; break; case 3: // 煞車 TAD = 1.0712*adval + 598.68; case 4: // 油門 } AD_table[AMX0P]=TAD; // 將數值存入矩陣當中
發射機之系統架構圖 油門的機制: 當前進時,switch上面接上面,下面接下面。 當後退時,switch反過來接,上面接下面,下面接上面。 Input為3個channel的輸入:油門(前進、後退)、煞車、方向。 Output為PPM編碼輸出,RST是Reset。 動作: F320分別對3個channel做A/D轉換,每轉換一次就判別輸出 一組PPM編碼。
ADC0 Function Block Diagram Analog 輸入端 Digital 輸出端
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
遙控車發射端PPM訊號 總週期 煞車 方向盤 油門 x 1234
遙控車發射端PPM訊號 煞車 方向盤 油門 1 2 3
PPM( ) PPM( ) n=1 n++ RET NO YES Output_high( ) Output_low(矩陣[n]) PPM output = 0 n<4?
PPM( ): n=1 Output_high( ) Output_low(矩陣[n] ) n++ n<4則跳至步驟2 PPM output輸出‘0’ Return
PPM( ) void PPM(void) { for(i=2;i<=4;i++) // 產生3個channel的PPM Output_high( ); // 輸出PPM的high Output_low( ); // 輸出PPM的low } Output_high( ); // 輸出最後的high P20 = 0; // 輸出low
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
遙控車發射端PPM訊號為high的部分 煞車 方向盤 油門 1 2 3
Output_high( ) Output_ high( ) RET NO YES 計數 完成? PPM output = 1 設定 TL1 和 TH1 開啟計數 關閉計數 清除溢位旗標
Output_high( ): PPM Output 輸出’1’ 設定TL1和TH1 開啟計數器 等待計數完成 關閉計數器 清除溢位旗標 Return
Output_high ( ) Void Output_high(void) { P20 = 1; // 設定輸出 high TH1 = (65536 – 500)/256; // 500us TL1 = (65536 – 500)%256; // 500us TR1 = 1; // 開啟計數 while(TF1==0); // 等待計數完成 TR1 = 0; // 關閉計數 TF1 = 0; // 清除溢位旗標 }
Outline Main ( ) : 主程式 System_Initial ( ) : 系統初始化 A2D( ) : ADC PPM( ) : 輸出PPM訊號 Output_high ( ) : 輸出PPM訊號的high Output_low ( ) : 輸出PPM訊號的low
Output_low( 矩陣[n] ) Output_ low( ) RET NO YES 計數 完成? PPM output = 0 經由矩陣[n]換算 設定 TL1 和 TH1 開啟計數 關閉計數 清除溢位旗標
Output_low(矩陣[n] ): PPM Output 輸出’0’ 經由矩陣[n]內的A/D數值換算出TL1和TH1的設定值 開啟計數器 等待計數完成 關閉計數器 清除溢位旗標 Return
Timer_Out_Low ( ) void Timer_Out_Low(void) { P20 = 0; // 輸出low TH1 = (65536-AD_table[i])/256; // 設定該channel計數的時間 TL1 = (65536-AD_table[i])%256; // 設定該channel計數的時間 TR1 = 1; // 開啟計數 while(TF1==0); // 等待計數完成 TR1 = 0; // 關閉計數 TF1 = 0; // 清除溢位旗標 }
END