Presentation is loading. Please wait.

Presentation is loading. Please wait.

使用F320撰寫程式控制搖控車發射端PPM編碼輸出

Similar presentations


Presentation on theme: "使用F320撰寫程式控制搖控車發射端PPM編碼輸出"— Presentation transcript:

1 使用F320撰寫程式控制搖控車發射端PPM編碼輸出
系別:通訊三甲 學生:葉祥嵩B 指導老師:田慶誠 教授

2 目錄 F320 Datasheet 設定說明 程式流程圖 PPM編碼演算法 程式 作品展示

3 F320 Datasheet 設定說明 10-bit ADC(ADC0) Port Input/Output Oscillators
Timers Programmable Counter Array(PCA0) F320 Datasheet back

4 F320 Datasheet 設定說明 10-bit ADC(ADC0)

5 10-Bit ADC (ADC0) 由上圖我們大略可知道:(1) 有兩種輸入方式 (2) 需要控制的暫存器: AMX0P、AMX0N、 ADC0CN、ADC0CF (3) 經過 A/D 轉換後的資料存於 ADC0H、ADC0L

6 控制ADC0開始轉換 有六種方法可以控制。 我們採用 AD0BUSY (W) 當 AD0BUSY = 1 時 ADC0開始轉換 當 AD0BUSY = 0 時 代表 ADC0 轉換完成 或是未開始動作

7 A/D 輸入轉換模式: Single-Ended 和 Differential
此模式轉換為輸入 0(v) ~ VREF(v) 轉換得到 0 ~ 1023, 資料儲存方式可分為由最低位元開始排列或是由最高位元開始排列, 因為我們輸入電壓為 0(v) ~ 3.3(v) , 固使用這個模式, 而資料儲存方式採用從最低位元開始排列(AD0LJST=0)。 此模式轉換為輸入 -VREF(v) ~ VREF(v) 轉換得到 -511 ~ 512, 資料儲存方式可分為由最低位元開始排列或是由最高位元開始排列。

8 REF0CN:Reference Control Register
Bit3:VDD used as voltage reference 因為我們電路的輸入電壓為0~3.3V 而IC內的VDD在標準時為3.3V 故我們將VDD當做是VREF

9 ADC0CF:ADC0 Configuration Register
Bits7-3:設定 SAR clock = 31 , 所以設定為 “11111” Bit2:資料儲存方式為由最低位元開始排列或是由最高位元 開始排列 ,我們採用從最低位元開始排列(AD0LJST=0)

10 AMX0P:AMUX0 Positive Channel Select Register
此多工器可控制要輸入哪一個Pin腳做A/D轉換

11 AMX0N:AMUX0 Negative Channel Select Register
因為我們使用 Single-Ended Mode ,固 AMX0P = 0x1F

12 ADC0H 和 ADC0L 當 AD0LJST = 0 :資料由低位元開始排列,所以資料存於 ADC0H(Bits 1-0) 和 ADC0L(Bits 7-0) 共10-Bits 當 AD0LJST = 1 :資料由高位元開始排列,所以資料存於 ADC0H(Bits 7-0) 和 ADC0L(Bits 7-6) 共10-Bits

13 ADC0CN:ADC0 Control Register
Bit7:ADC0 Enabled Bit6:Normal Track Mode Bits2-0:When AD0TM = 0 000:ADC0 conversion initiated on every write of '1' to AD0BUSY back

14 F320 Datasheet 設定說明 Port Input/Output

15 Port I/O Functional Block Diagram

16 Step 1. Select the input mode
要做 A/D 轉換的 input 必需設定為 analog input 我設定的輸入為 P1.2、P1.3、P1.4 固 P1MDIN = “ ” = 0xE3

17 PnMDOUT 簡介 open-drain 電路圖 push-pull 電路圖 圖1 圖2
一般程式初始設定時,PnMDOUT會設定為open-drain, 然後因為我們輸出的PPM編碼週期時間短(1ms~2ms), 所以當輸出由 ‘0’ 變 ‘1’ 時,電壓沒辦法馬上從 0V 上升至 3.3V , 所以會波形會變形如圖1,所以我們要將輸出模式 設定為push-pull,這樣電壓供應源有兩個,所以就不會有電壓 無法馬上恢復的情況發生,正常PPM編碼如圖2。

18 使用示波器實際驗證 open-drain 波形圖 push-pull 波形圖

19 Step 2. Select the output mode
PPM編碼輸出時,輸出必需設定為 push-pull 所以要輸出的腳位要設定為 ’1’

20 Step 3. Select any pins to be skipped by the Crossbar
要做 A/D 轉換的 analog input 必需關閉Digital crossbar 我們設定的輸入為 P1.2、P1.3、P1.4 固 P1SKIP = “ ” = 0x1C

21 Step 4. Assign Port pins to desired peripherals
Bit7:Weak Pull-ups enabled Bits5-0:我們並未使用, 所以選擇 unavailable Step 5. Enable the Crossbar Bit6:Crossbar enabled back

22 F320 Datasheet 設定說明 Oscillators

23 Oscillator Diagram 由右圖可知 需要控制的暫存器為:
OSCICN、CLKSEL 、OSCXCN、 CLKMUL 因為我們最右邊的多工器選擇為Internal Oscillator輸入, 所以暫存器 OSCXCN、 CLKMUL可以不用設定, 因為並沒有使用所以不會影響

24 OSCICN:Internal Oscillator Control Register
Bit7: Internal Oscillator Enabled Bits1-0: SYSCLK derived from Internal Oscillator divided by 代表輸入的Internal Oscillator經過一個除1的電路 所以Internal Oscillator / 1 = 12MHz

25 CLKSEL: Clock Select Register
Bits1-0: Selected Clock from Internal Oscillator back

26 F320 Datasheet 設定說明 Timers

27 RSTRC: Reset Source Register
Bit2: Missing Clock Detector (MCD) enabled

28 IE: Interrupt Enable 因為我們使用Timer0中斷所以要設定IE Bit7: Enable All Interrupt
Bit1: Enable interrupt requests generated by the TF0 flag

29 TMOD: Timer Mode Register
我們使用 Timer1 Mode1 and Timer0 Mode1 Bits5-4: Mode 1: 16-bit counter/timer Bits1-0: Mode 1: 16-bit counter/timer back

30 F320 Datasheet 設定說明 Programmable Counter Array (PCA0)

31 PCA WDT 由Important Note我們可知 PCA WDT 在 system reset 後會自動 enabled,這樣會影響到我們原本的Timer1或Timer0的WDT,因此 我們要將此 distabled (我們並未使用PCA0), 控制它的暫存器是「PCA0MD」

32 PCA0MD: PCA Mode Register
Bit6 : WDT disabled (clear watchdog timer enable IN ORDER TO CHANGE PCA0MD) back

33 主程式流程圖 Main 備註: 1.c8051f320初始化,表示啟動320最 基本條件。 2.將channel的類比電壓量化成0~1023
刻度。(ch1~ch3的AD轉換) 3.如下圖描述出PPM輸出訊號。 C8051f320初始化 CH1做AD轉換 CH2做AD轉換 CH3做AD轉換 輸出PPM訊號

34 = ADC0L + (ADC0H<<8)
Ch1_AD轉換副程式 Ch1_AD ADC0CN = 0x80; RET P1MDIN = 0xFB; AD0BUSY = 1; P1SKIP = 0x04; while(AD0BUSY ) = 0? No AMX0P = 0x02; Yes ADC0CF = 0x08; ch1_adc_val = ADC0L + (ADC0H<<8) 備註:P1MDIN為P1.2 analog input

35 Timer0_Mode_1_Delay_low副程式
TIMER_Delay_low while(TF==0) ? Yes TMOD=0x01; No TH0=( )/256 TF=0; TL0=( )%256 TR0=0; TR0=1; RET 備註:計時為400us

36 Timer0_Mode_1_Delay_channel副程式
TIMER_Delay_Ch while(TF0==0) ? Yes TMOD=0x01; No TH0=(65536-C)/256 TF0=0; TL0=(65536-C)%256 TR0=0; TR0=1; RET

37 輸出PPM訊號副程式 PPM_Output PPM=1; PPM=0; PPM=1; Timer_Delay_low PPM=0;
Timer_Delay_Ch3 PPM=1; Timer_Delay_low PPM=0; Timer_Delay_Ch2 PPM=1; Timer_Delay_low PPM=0; Timer_Delay_Ch1 PPM=1; Timer_Delay_low PPM=0; Timer_Delay_end RET

38 演算法 備註: 1.由Timer0_Mode1計時計數知,可 計時數範圍由可以計1u~65.536ms
2.再配合電壓0~3V與ADC解析度變化 範圍為0~1023,由ADC改變的Value 帶入Timer0_Mode1之TH0與TL0, 即可計時遙控汽車,發送端PPM變 化量。 3.如圖一所示,表示: (1)當adc_value=0,則計時600uS (2)當adc_value=1023,則計時1600 uS 4.如圖二所示,表示: (a)時間變化量改變地方 (b)時間固定地方 圖一:Adc_value與時間變化量關係圖 圖二:Channel時間定量與變化地方

39 程式:系統設定 #include <c8051f320.h>
/* 定義腳位 */ sbit PPM = P2^0; /* PPM 訊號輸出腳位 */ /* 變數宣告 */ unsigned int ch1_get_adc,ch2_get_adc,ch3_get_adc; /* 宣告副程式 */ int set_ch1_get_adc (void); /* channel adc設定與取adc值 */ int set_ch2_get_adc (void); /* channe2 adc設定與取adc值 */ int set_ch3_get_adc (void); /* channe3 adc設定與取adc值 */ void sys_ini (void); /* c8051f320初始化 */ void timer_delay_high_ch_1(void); /* ch1計時時間變化 */ void timer_delay_high_ch_2(void); /* ch2計時時間變化 */ void timer_delay_high_ch_3(void); /* ch3計時時間變化 */ void timer_delay_low(void); /* 計時固定400us*/ void timer_delay_end(void); /* end_bit計時 */ void ppm_total_signal(void); /* 整體PPM輸出*/

40 主程式 /* 主程式 */ void main ( void ) { sys_ini(); /* c8051f320初始化 */ while(1) set_ch1_get_adc(); /* 設定CH1_ADC與取CH1_ADC轉換值*/ set_ch2_get_adc(); /* 設定CH2_ADC與取CH2_ADC轉換值*/ set_ch3_get_adc(); /* 設定CH3_ADC與取CH3_ADC轉換值*/ ppm_total_signal(); /* PPM整體訊號輸出*/ } void sys_ini (void) OSCICN = 0x83; /*將sysclk由1.5Mhz改成12Mhz*/ RSTSRC = 0x04; /*當timer計時大於100us會有誤差為了防止這樣的問題而做了保護動作*/ PCA0MD=0x00; /*防止timer_counter與soft_counter干擾*/ XBR1 = 0x40; /* 啟動 I/O Port */ REF0CN = 0x08; /* 使用vdd作為參考電壓 */

41 channel adc設定與取adc值 int set_ch1_get_adc (void) {
P1MDIN = 0xFB; /* 設定P1.2為analog_input */ P1SKIP = 0x04; /* 讓P1.2可以輸入analog input*/ /* Init MUX */ AMX0P = 0x02; /* P1.2腳為 analog 訊號進入給adc */ AMX0N = 0x1F; /* single_ended mode*/ /* Init ADC */ ADC0CF = 0x08; /*sampling rate */ ADC0CN = 0x80; /* 整體adc總開關並且使用ad0busy為轉換模式 */ AD0BUSY = 1; /* 當AD0BUSY=1,則開始進行轉換adc_value */ while(AD0BUSY); /* 開始轉換,轉換完畢,旗標變為0 */ ch1_get_adc = ADC0L + (ADC0H<<8); /* 取轉換值方式*/ return ch1_get_adc; /* 將值回傳 */ }

42 channe2 adc設定與取adc值 int set_ch2_get_adc (void) {
P1MDIN = 0xF7; /* 設定P1.3為analog_input */ P1SKIP = 0x08; /* 讓P1.3可以輸入analog input*/ /* Init MUX */ AMX0P = 0x03; /* P1.3腳為 analog 訊號進入給adc */ AMX0N = 0x1F; /* single_ended mode*/ /* Init ADC */ ADC0CF = 0x08; /*sampling rate */ ADC0CN = 0x80; /* 整體adc總開關並且使用ad0busy為轉換模式 */ AD0BUSY = 1; /* 當AD0BUSY=1,則開始進行轉換adc_value */ while(AD0BUSY); /* 開始轉換,轉換完畢,旗標變為0 */ ch2_get_adc = ADC0L + (ADC0H<<8); /* 取轉換值方式*/ return ch2_get_adc; /* 將值回傳 */ }

43 channe3 adc設定與取adc值 int set_ch3_get_adc (void) {
P1MDIN = 0xEF; /* 設定P1.4為analog_input */ P1SKIP = 0x10; /* 讓P1.4可以輸入analog input*/ /* Init MUX */ AMX0P = 0x04; /* P1.2腳為 analog 訊號進入給adc */ AMX0N = 0x1F; /* single_ended mode*/ /* Init ADC */ ADC0CF = 0x08; /*sampling rate */ ADC0CN = 0x80; /* 整體adc總開關並且使用ad0busy為轉換模式 */ AD0BUSY = 1; /* 當AD0BUSY=1,則開始進行轉換adc_value */ while(AD0BUSY); /* 開始轉換,轉換完畢,旗標變為0 */ ch3_get_adc = ADC0L + (ADC0H<<8); /* 取轉換值方式*/ return ch3_get_adc; /* 將值回傳 */ }

44 void timer_delay_low (void)
{ TMOD = 0x01; /* 使用 timer0_mode1 模式*/ TH0 = ( )/256; /* 計數400次,時間為400us*/ TL0 = ( )%256; /* 計數400次,時間為400us*/ TR0 = 1; /* 開始計時計數 */ while (TF0 ==0); //while(1) if (TF0 == 1) break; /*等待計時計數完成*/ TF0 = 0; /*清除TF旗標*/ TR0 = 0; /*關閉計數*/ } void timer_delay_high_ch_1 (void) { TMOD = 0x01; /* 使用 timer0_mode1 模式*/ TH0 = (65536-(600+ch1_get_adc))/256; /* 計數600~1600次,時間為600~1600us*/ TL0 = (65536-(600+ch1_get_adc))%256; /* 計數600~1600次,時間為600~1600us*/ TR0 = 1; /* 開始計時計數 */ while (TF0==0); /*等待計時計數完成 */ TF0 = 0; /*清除TF旗標 */ TR0 = 0; /*關閉計數 */ }

45 void timer_delay_high_ch_2 (void)
{ TMOD = 0x01; /* 使用 timer0_mode1 模式*/ TH0 = (65536-(600+ch2_get_adc))/256; /* 計數600~1600次,時間為600~1600us*/ TL0 = (65536-(600+ch2_get_adc))%256; /* 計數600~1600次,時間為600~1600us*/ TR0 = 1; /* 開始計時計數 */ while (TF0==0); /*等待計時計數完成 */ TF0 = 0; /*清除TF旗標 */ TR0 = 0; /*關閉計數 */ } void timer_delay_high_ch_3 (void) { TMOD = 0x01; /* 使用 timer0_mode1 模式*/ TH0 = (65536-(600+ch1_get_adc))/256; /* 計數600~1600次,時間為600~1600us*/ TL0 = (65536-(600+ch1_get_adc))%256; /* 計數600~1600次,時間為600~1600us*/ TR0 = 1; /* 開始計時計數 */ while (TF0==0); /*等待計時計數完成 */ TF0 = 0; /*清除TF旗標 */ TR0 = 0; /*關閉計數 */ }

46 end_bit計時 備註: 65536-(20000-3400-ch3_get_adc-ch2_get_adc-ch1_get_adc)
void timer_delay_end(void) { TMOD = 0x01; TH0 = (65536-( ch3_get_adc-ch2_get_adc-ch1_get_adc))/256; TL0 = (65536-( ch3_get_adc-ch2_get_adc-ch1_get_adc))%256; TR0 = 1; while (TF0==0); TF0 = 0; TR0 = 0; } 備註: 65536-( ch3_get_adc-ch2_get_adc-ch1_get_adc) 此計算式子,是由計時計數總週期20ms減去各channel的high與 low的時間。以下圖作為更詳細的說明! 20ms 20ms-各channel之high與low時間

47 整體訊號輸出 void ppm_total_signal(void) { /* channel 1 */
timer_delay_low(); /*延遲400us*/ PPM = 1; /* 輸出訊號為1 */ timer_delay_high_ch_1(); /*延遲時間600us~1600us*/ /* channel 2 */ PPM = 0; /*輸出訊號為0*/ timer_delay_low(); /*延遲400us*/ PPM = 1; /*輸出訊號為1*/ timer_delay_high_ch_2(); /*延遲時間600us~1600us*/ /* channel 3 */ timer_delay_low(); /*延遲400us*/ timer_delay_high_ch_3(); /*延遲時間600us~1600us*/ /* end bit */ timer_delay_low(); /*延遲400us*/ timer_delay_end(); /*延遲時間由20ms-各channel之延遲時間*/ }

48 電路實作 JTAG 編碼電路

49 電路測試 CH 1 Input:0V Time:1ms CH 1 Input:1.61V Time:1.5ms
Power Supply:6V CH 1 Input:3.38V Time:2ms

50 電路測試 CH 1 Time:1.5ms CH 1 Time:1ms CH 1 Time:2ms

51 電路測試 CH 2 Input:0V Time:1ms CH 2 Input:1.60V Time:1.5ms
Power Supply:6V CH 2 Input:3.38V Time:2ms

52 電路測試 CH 1 Time:1.5ms CH 2 Time:1ms CH 1 Time:2ms

53 電路測試 CH 3 Input:0V Time:1ms CH 3 Input:1.60V Time:1.5ms
Power Supply:6V CH 3 Input:3.38V Time:2ms

54 電路測試 CH 3 Time:1.5ms CH 3 Time:1ms CH 3 Time:2ms Total time Time:20ms


Download ppt "使用F320撰寫程式控制搖控車發射端PPM編碼輸出"

Similar presentations


Ads by Google