遙控車程式 學號:B09622048 姓名:楊 穎 穆 老師:田 慶 誠
大綱 Main( ) :主程式 System_Initial( ):系統初始化副程式 A2D( ) :ADC副程式 PPM( ) :輸出PPM訊號副程式 Output_high( ) :輸出PPM的high訊號 Output_low( ) :輸出PPM的low訊號
撰寫程式輸出PPM訊號 T 1 2 3 4 1.煞車 2.方向盤 3.油門 4.未設定
Main( ) 系統初始化設定 分別對煞車、方向盤、油門3個channel 做A/D轉換 開始計數總週期22ms 使用 Timer 開始計數22ms Main( ) System_Initial( ) A2D( ) PPM( ) 22ms計數完成? NO YES A B C D E F 系統初始化設定 分別對煞車、方向盤、油門3個channel 做A/D轉換 開始計數總週期22ms 開始輸出3個channel的PPM 分別對下一個煞車、方向盤、油門 3個channel 做A/D轉換 等待總週期22ms計數完成 跳至步驟3重覆動作
主程式時序圖 PPM( ) C D F D A2D( ) A2D( ) A B E E 22ms 22ms System_Initial( ) 22ms計數完成
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 A2D( ); // 對3個channel做A/D轉換 while(TF0==0); // 等待22ms計數完成 TR0 = 0; // 關閉 Timer0 計數 TF0 = 0; // 清除 Timer0 溢位旗標 }
C8051F320 Block Diagram Timer區域 穩壓區域 Oscillator區域 I/O區域 A/D區域
System_Initial ( ) 設定 Oscillator 關閉 PCA0 WDT 設定 Timer 設定 ADC0 I/O Port Return 設定 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) }
測量遙控車油門、煞車、方向盤可變電阻變化 圖(2)實際量測阻值過程 圖(1)量測阻值電路 根據圖(1)我們可以量出在不同動作時,R1和R2的電阻值。這些數值可供我們分析Vo和A/D關係式。
發射機之系統架構圖 油門的機制: 當前進時,switch上面接上面,下面接下面。 當後退時,switch反過來接,上面接下面,下面接上面。 Input為3個channel的輸入:油門(前進、後退)、煞車、方向。 Output為PPM編碼輸出,RST是Reset。 動作: F320分別對3個channel做A/D轉換,每轉換一次就判別 輸出一組PPM編碼。
ADC0 Function Block Diagram Analog 輸入端 Digital 輸出端
A2D ( ) n=1 設定 channel n 做A/D轉換 開啟A/D轉換 等待A/D轉換完成 將A/D數值存入矩陣[n]之中 n++ Return 設定 channel n 做A/D轉換 n<4? YES 開啟 A/D 轉換 NO Return A/D 轉換完成? NO YES 將 A/D數值 存入至矩陣[n]
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.2691*adval + 2165.5; break; case 3: // 煞車 TAD = 1.3132*adval+ 963.9; case 4: // 油門 TAD= -1.4388*adval+ 2244.5; } AD_table[AMX0P]=TAD; // 將數值存入矩陣當中
遙控車發射端PPM訊號 1. 煞 車 2. 方 向 盤 3. 油 門
PPM( ) n=1 Output_high( ) Output_low(矩陣[n] ) n++ n<4則跳至步驟2 Return NO YES Output_high( ) Output_low(矩陣[n]) PPM output = 0 n<4? 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
遙控車發射端PPM訊號為High的部分 1. 煞 車 2. 方 向 盤 3. 油 門
Output_High( ) PPM Output 輸出’1’ 設定TL1和TH1 開啟計數器 等待計數完成 關閉計數器 清除溢位旗標 RET NO YES 計數完成? 溢位旗標=1? PPM output = 1 設定 TL1 和 TH1 開啟計數 關閉計數 清除溢位旗標 PPM Output 輸出’1’ 設定TL1和TH1 開啟計數器 等待計數完成 關閉計數器 清除溢位旗標 Return
Output_high ( ) Void Output_high(void) { P20 = 1; // 設定輸出 high TH1 = (8192– 500)/256; // 500us TL1 = (8192 – 500)%256; // 500us TR1 = 1; // 開啟計數 while(TF1==0); // 等待計數完成 TR1 = 0; // 關閉計數 TF1 = 0; // 清除溢位旗標 }
遙控車發射端PPM訊號為Low的部分 1. 煞 車 2. 方 向 盤 3. 油 門
Output_Low PPM Output 輸出’0’ 經由矩陣[n]內的A/D數值換算出TL1和TH1的設定值 開啟計數器 等待計數完成 Return NO YES 計數完成? 溢位旗標=1? PPM output = 0 經由矩陣[n]換算 設定 TL1 和 TH1 開啟計數 關閉計數 清除溢位旗標 PPM Output 輸出’0’ 經由矩陣[n]內的A/D數值換算出TL1和TH1的設定值 開啟計數器 等待計數完成 關閉計數器 清除溢位旗標 Return
Output_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