初級會員
Joined
: 2007/11/20 18:56 最後登入時間
: 2008/1/29 5:43
Group:
註冊會員
Level : 3 HP : 0 / 57 MP : 7 / 2777 EXP : 31
|
請問: 我在看曾百由的"數位訊號控制器原理與應用C30開發實務", 其中30F4011內建有一組10位元的A/D轉換器,在範例11-1 偵測VR2的8位元類比電壓轉換值,並以10進位方式顯示在LCD上,既然30F4011是一組10位元的A/D轉換器,他如何改成8位元的轉換值呢?我要如何改回原來的10位元來顯示呢?在程式哪一部份?
/ *********************************************************************** // File : EX11_1_ADC_Man.C // Purpose : 練習如何叫 Microchip C30 提供的 ADC 函式庫 // // 使用的函式 : // ConfigIntTimer1( ) // OpenTimer1( ) // BusyADC10() // CloseADC10() // ConfigintADC10() // ConvertADC10() // OpenADC10() // ReadADC10() // SetChanADC10() // // 動作 : // 將 LCD 初始化成 2 行 5*7 文字模式 // 使用 C30EVM_LCD.c 中的副程式顯示下列字串 // // Exercise 11- ADC // VR1:XXX VR2:YYY // // 將 Timer 1 規劃成 Period 為 1 ms 的 Timer // 使用中斷的技巧 , 在 ISR 檢查是否已計時 1 秒 // 若是 , 則進行類比訊號轉換,並將轉換結果顯示於LCD // // // ***********************************************************************
#define __dsPIC30F4011__
#include <p30F4011.h> #include "C30EVM_LCD.h" // 將LCD函式的原型宣告檔案含入 #include <timer.h> // 將Timer函式的原型宣告檔案含入 #include <adc10.h> // 將adc10函式的原型宣告檔案含入
#define FCY 7372800 * 2 // 因為使用頻率為將外部 7.3728 MHz * 8 的模式 , 每一指令週期需 4 個 clock // 所以 FCY = (7.3728 * 8 / 4 ) MHz = 7372800* 2
_FOSC(CSW_FSCM_OFF & XT_PLL8); // XT with 8xPLL oscillator, Failsafe clock off _FWDT(WDT_OFF); // Watchdog timer disabled _FBORPOR(PBOR_OFF & MCLR_EN); // Brown-out reset disabled, MCLR reset enabled _FGS(CODE_PROT_OFF); // Code protect disabled
const char My_String1[]="Exercise 11- ADC" ; // 宣告字串於 Program Memory (因為 const 宣告) char My_String2[]="VR1: VR2: " ; // 宣告字串於 Data Memory
unsigned int miliSec ;
void Init_ADC(void) ; void Show_ADC(void) ;
// union 宣告將使8位元變數ByteAccess與SystemFlag結構變數使用相同的記憶體, // 以利不同格式的位元運算需求 union { unsigned char ByteAccess ; struct { unsigned Bit0: 1 ; unsigned Bit1: 1 ; unsigned Bit2: 1 ; unsigned unused : 5 ; } ; } SystemFlag ;
//定義OneSecond旗標等同於SystemFlag.Bit0位元變數,故將其使用一個位元記憶空間 #define OneSecond SystemFlag.Bit0
void _ISR _T1Interrupt(void) //Timer1中斷副程式 {
miliSec += 1 ;
if (miliSec == 1000) //每1000次將OneSecond旗標設定為1 { OneSecond = 1 ; miliSec = 0 ; } IFS0bits.T1IF = 0 ; //清除中斷旗標
}
int main( void ) {
Init_ADC( ) ; // 將ADC進行初始化設定
OpenLCD( ) ; // 使用 OpenLCD( )對 LCD 模組作初始化設定 // 4 bits Data mode // 5 * 7 Character
setcurLCD(0,0) ; // 使用 setcurLCD( ) 設定游標於 (0,0) putrsLCD( My_String1 ) ; // 將存在 Program Memory 的字串使用 // putrsLCD( ) 印出至 LCD setcurLCD(0,1) ; // 使用 setcurLCD( ) 設定游標於 (0,1) putrsLCD( My_String2 ) ; // 將存在 Data Memory 的字串使用 // putsLCD( ) 印出至 LCD
ConfigIntTimer1( T1_INT_PRIOR_7 & T1_INT_ON ) ; // Timer1 的中斷優先等級設 7 (最高) // Timer1 的中斷 ON
OpenTimer1( T1_ON & T1_IDLE_STOP & T1_GATE_OFF & // Timer1 的 Period 設為每 1ms T1_PS_1_1 & T1_SYNC_EXT_OFF & T1_SOURCE_INT , (FCY/ 1000) ) ;
OneSecond = 0 ;
while(1) { if ( OneSecond ) // 詢問 Timer1 的 Period 時間是否已到 // 可以用軟體模擬來檢查是否為準確的 1 ms { OneSecond = 0 ; Show_ADC( ) ; // 將類比轉換結果顯示於 LCD 上
} } }
/***********************************************/ // Subroutine to configure the A/D module
void Init_ADC(void) {
unsigned int Channel, PinConfig, Scanselect, Adcon3_reg, Adcon2_reg, Adcon1_reg;
ADCON1bits.ADON = 0; /* turn off ADC */
PinConfig = ENABLE_AN0_ANA; // Select port pins as analog inputs ADPCFG<15:0>
Adcon1_reg = ADC_MODULE_ON & // Turn on A/D module (ADON) ADC_IDLE_STOP & // ADC turned off during idle (ADSIDL) ADC_FORMAT_INTG & // Output in integer format (FORM) ADC_CLK_MANUAL & // Conversion trigger manually (SSRC) ADC_SAMPLE_INDIVIDUAL & // Sample channels individually (SIMSAM) ADC_AUTO_SAMPLING_OFF; // Sample trigger manually (ASAM)
Adcon2_reg = ADC_VREF_AVDD_AVSS & // Voltage reference : +AVdd, -AVss (VCFG) ADC_SCAN_OFF & // Scan off (CSCNA) ADC_ALT_BUF_OFF & // Use fixed buffer (BUFM) ADC_ALT_INPUT_OFF & // Does not alternate between MUX A & MUX B (ALTS) ADC_CONVERT_CH0 & // Convert only channel 0 (CHPS) ADC_SAMPLES_PER_INT_1; // 1 sample between interrupt (SMPI)
Adcon3_reg = ADC_SAMPLE_TIME_10 & // Auto-Sample time (SAMC) ADC_CONV_CLK_SYSTEM & // Use system clock (ADRC) ADC_CONV_CLK_4Tcy; // Conversion clock = 4 Tcy (ADCS) // ADCS = 2*(154ns)/(1/Fcy)-1 = 3.5416
Scanselect = SCAN_NONE; // ADC scan no channel (ADCSSL)
OpenADC10(Adcon1_reg, Adcon2_reg, Adcon3_reg, PinConfig, Scanselect);
Channel = ADC_CH0_POS_SAMPLEA_AN0 & // CH0 Pos. : AN0, Neg. : Nominal Vref- Defined in ADCON2 ADC_CH0_NEG_SAMPLEA_NVREF ; // (ADCHS) SetChanADC10(Channel);
ConfigIntADC10(ADC_INT_DISABLE); // Disable ADC interrupt
}
/***********************************************/ // Subroutine to show Time on LCD
void Show_ADC(void) { unsigned char dummy ; unsigned int ADCValue;
ADCON1bits.SAMP = 1; // start sampling ...
for ( dummy = 0 ; dummy < 100 ; dummy ++ );
ConvertADC10(); while (BusyADC10()); // conversion done? ADCValue = (ADCBUF0 >> 2); // get ADC value
setcurLCD(12,1) ; // Set LCD cursor put_Num_LCD( ADCValue ) ; // 將類比轉換結果以十進位數字顯示至液晶顯示器 }
發表於: 2007/11/27 4:35
|