從你的程式因採用直接的位元設定,這要去一個一個的位元去看暫存器的設定,這有點辛苦,萬一一不注意漏掉了某個位元程式就不會動了。
之前我都是用 MPLAB C32 來撰寫 PIC32 的,因為 C32 有支援 Peripheral Library 所以周邊是呼叫周邊函數庫來撰寫的。
新版的 XC32 的周邊函數庫要另外安裝或是是用 MCC 來設定,高階一點就用 MHC 的設定與 Harmony 結合。
有找了一個 PIC32 的教育訓練:
MCU4101T v2.0 PIC32 & MPLAB C32 Introduction 裡面有單一 Channel 的 ADC 轉換程式可供參考,帶這是使用 C32 的編譯器。
#include <plib.h>
#include <p32xxxx.h>
#include "App1632_LCM.h"
/* Configuration Settings */
// OSC Input = HS w/PLL
// CPU Clock = ( ( OSC Input / 2 ) * 15 ) / 1
// PB Clock = CPU Clock / 1
// Disabld WDT , ICSP/ICD = PGC2 , PGD2
#pragma config FNOSC = PRIPLL , POSCMOD = HS
#pragma config FPLLIDIV = DIV_2 , FPLLMUL = MUL_15 , FPLLODIV = DIV_1
#pragma config FPBDIV = DIV_8
#pragma config FWDTEN = OFF , ICESEL = ICS_PGx2
#define SystemFrequency 60000000L
#define PBFrequency SystemFrequency / 8
#define Timer1Tick ( PBFrequency / 256 / TogglesPerSec )
#define TogglesPerSec 10
const unsigned char LCMString1[ ] = "PIC32MX795F512L";
const unsigned char LCMString2[ ] = "VR1:";
unsigned int VR1Value = 0;
void __ISR(_TIMER_1_VECTOR, ipl4 ) ISR_Imier1( void )
{
// 清除Timer中斷旗標。
mT1ClearIntFlag( );
// To Do : 使用C32 ADC Function啟動ADC的轉換。
ConvertADC10( );
// LED狀態反向。
mPORTAToggleBits( BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 );
}
int main( void )
{
// disable JTAG port
DDPCONbits.JTAGEN = 0;
// 周邊時脈 = 系統時脈 / 8。
OSCSetPBDIV( OSC_PB_DIV_8 );
// 使用C32的SYSTEM Config巨集將CPU的操作最佳化,但不修改到FPBDIV的設定。
SYSTEMConfig( SystemFrequency , SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE );
// SYSTEMConfigPerformance( SystemFrequency );
// SYSTEMConfigWaitStates( SystemFrequency );
// LED對應之I/O Port設定成數位輸出,並指定I/O Port狀態。
mPORTASetPinsDigitalOut( BIT_0 | BIT_1 | BIT_2 | BIT_3 | BIT_4 | BIT_5 | BIT_6 | BIT_7 );
mPORTASetBits( BIT_0 | BIT_1 | BIT_2 | BIT_3 );
mPORTAClearBits( BIT_4 | BIT_5 | BIT_6 | BIT_7 );
// 啟用Timer,並指定其中斷優先權。
ConfigIntTimer1( T1_INT_ON | T1_INT_PRIOR_4 );
// Timer設定。
OpenTimer1( T1_ON | T1_IDLE_CON | T1_GATE_OFF | T1_PS_1_256 | T1_SOURCE_INT , Timer1Tick );
// LCM初始化。
LCM_Init( );
// 設定遊標,輸出字串。
LCM_SetCursor( 0 , 0 );
LCM_PutROMString( LCMString1 );
// To Do : 使用C32 ADC10 Function設定ADC。
OpenADC10( ADC_MODULE_ON | ADC_IDLE_CONTINUE | ADC_FORMAT_INTG16 | ADC_CLK_MANUAL | ADC_AUTO_SAMPLING_ON | ADC_SAMP_OFF ,
ADC_VREF_AVDD_AVSS | ADC_OFFSET_CAL_DISABLE | ADC_SCAN_OFF | ADC_SAMPLES_PER_INT_1 | ADC_ALT_BUF_ON | ADC_ALT_INPUT_OFF ,
ADC_SAMPLE_TIME_31 | ADC_CONV_CLK_SYSTEM | ADC_CONV_CLK_32Tcy ,
ENABLE_AN2_ANA , SKIP_SCAN_ALL );
// To Do : 使用C32 ADC10 Function設定AD正確的正,負通道。
SetChanADC10( ADC_CH0_POS_SAMPLEA_AN2 | ADC_CH0_NEG_SAMPLEA_NVREF | ADC_CH0_POS_SAMPLEB_AN0 | ADC_CH0_NEG_SAMPLEB_NVREF );
// To Do : 使用C32 I/O Port Function將正確AD通道設定為類比輸入。
PORTSetPinsAnalogIn( IOPORT_B , BIT_2 );
INTEnableSystemMultiVectoredInt( );
while( 1 )
{
// 轉換完成 ?
if( INTGetFlag( INT_AD1 ) )
{
// 清除ADC中斷旗標
INTClearFlag( INT_AD1 );
// 讀取ADC轉換之數值。
VR1Value = ( unsigned int ) ReadADC10( 0 );
// 設定遊標,輸出ADC數值。
LCM_SetCursor( 0 , 1 );
LCM_PutROMString( LCMString2 );
LCM_PutNumber( VR1Value , 4 );
}
}
while( 1 );
}
建議使用 MCC 來產生 ADC 的函數庫在使用 XC32 來呼叫。這可以參考教育訓練:
PIC32MMv100 PIC32MM 與 MCC 快速上手 literature Hands-On New!http://www.microchip.com.tw/Data_CD/