;****************************************************************************************** ; dsPIC P33FJ32GP202 Sample Program ; Project : ; Program Name : ; Programer : ; Create date : Version 1.0 H21.04.20 ; History : ; Laungage : MPLAB ASM30 ;****************************************************************************************** ; (1)Description ; ;****************************************************************************************** .include "p33FJ32GP202.inc" config __FOSCSEL , FNOSC_FRC & IESO_OFF config __FOSC , FCKSM_CSECMD & IOL1WAY_OFF & OSCIOFNC_OFF & POSCMD_NONE .bss .global __reset .section data_area ADC_dat: .space 2 Tmp_w: .space 2 ;****************************************************************************************** ; Function Name : main ; Title : ; Input : ; Output : ;****************************************************************************************** .text __reset: ;******************* ; 0.Initialize ;******************* ; (0)Initialize Stack Pointer MOV #__SP_init, W15 ;Initalize the Stack Pointer MOV #__SPLIM_init, W0 ;Initialize the Stack Pointer Limit Register MOV W0, SPLIM NOP ;Add NOP to follow SPLIM initialization ; (1)Set All Digital Port MOV.W #0xFFFF,W0 MOV.W W0,AD1PCFGL ; (2)Define PortA MOV.W #0xFFFF,W0 MOV.W W0,TRISA ; (3)Define PortB MOV.W #0x0000,W0 MOV.W W0,TRISB ; CLR.W PORTB ; (4)Set A/D Converter CALL InitADC ;******************* ; 2.Program main ;******************* main_p: ; (1)Get A/D Data CALL GetADC ; (2)Wait function(Sampling times) ; CALL wat NOP NOP ; (3)Check push-sw MOV.W PORTA,W0 MOV.W W0,Tmp_w MOV.W #0x000C,W1 AND.W W0,W1,W2 SUB.W W2,#0,W1 BRA NZ,main_edt1 BRA main_cnv ;Case Sw1=0,Sw2=0 ; (4)Edit A/D Data main_edt1: MOV.W ADC_dat,W4 MOV.W #5,W5 MPY W4*W5,A ; accumulators(A/B) = W4 * W5 SFTAC A,#-15 ; 15Bit Plus Shift(accumulators) SAC A,W4 ; accumulators(A/B)[31-15] => W4 MOV.W W4,ADC_dat BRA main_cnv ; (5)Convert 12bit to 16bit main_cnv: MOV.W ADC_dat,W0 MOV.W #4,W1 SL.W W0,W1,W0 MOV.W W0,ADC_dat ; (6)Output D/A Data MOV.W ADC_dat,W0 MOV.W W0,PORTB main_loop_E: BRA main_p ;****************************************************************************************** ; Function Name : wat ; Title : wait function ; Input : ; Output : ; Description : ; W1:Timer_1,W2:Timer_2 ;****************************************************************************************** wat: ; ****************** ; 1.Initialize ; ****************** PUSH.W W0 PUSH.W W1 PUSH.W W2 PUSH.W W3 PUSH.W W4 ; ****************** ; 2.Program main ; ****************** ; (1)wat_1 CLR.W W1 wat_1: MOV.W #0x0001,W3 INC.W W1,W3 MOV.W W3,W1 ; MOV.W #0x0A,W3 ; LP_1 < 0x0A(10) SUB.W W1,W3,W4 BRA LEU,wat_2S BRA wat_e ; ; (2)wat_2 wat_2S: CLR.W W2 wat_2: MOV.W #0x0001,W3 INC.W W2,W3 MOV.W W3,W2 NOP NOP NOP NOP ; MOV.W #0x2,W3 ; LP_2 < 0x2(2) SUB.W W2,W3,W4 BRA LEU,wat_2 BRA wat_1 ; ; ****************** ; 3.End ; ****************** wat_e: POP.W W4 POP.W W3 POP.W W2 POP.W W1 POP.W W0 RETURN ;****************************************************************************************** ; Function Name : InitADC ; Title : Initialize A/D Converter ; Input : ; Output : ;****************************************************************************************** InitADC: ; ******************************* ; 1. Configure the A/D module ; ******************************* ; a) Select port pins as analog inputs(AD1PCFG<15:0>) BCLR AD1PCFGL,#PCFG0 ; //PCFG(12-0) 1:Digital mode, 0:Analog mode BSET AD1PCFGL,#PCFG1 BSET AD1PCFGL,#PCFG2 BSET AD1PCFGL,#PCFG3 BSET AD1PCFGL,#PCFG4 BSET AD1PCFGL,#PCFG5 BSET AD1PCFGL,#PCFG9 BSET AD1PCFGL,#PCFG10 BSET AD1PCFGL,#PCFG11 BSET AD1PCFGL,#PCFG12 BCLR AD1CHS0,#CH0SA0 ; Channel 0 positive input is AN0 BCLR AD1CHS0,#CH0SA1 ; Channel 0 positive input is AN0 BCLR AD1CHS0,#CH0SA2 ; Channel 0 positive input is AN0 BCLR AD1CHS0,#CH0SA3 ; Channel 0 positive input is AN0 BCLR AD1CHS0,#CH0NB ; Channel 0 negative input is VREF ; b) Select voltage reference source to match expected range on analog inputs(AD1CON2<15:13>) BCLR AD1CON2,#VCFG0 ; VR+:AVDD , VR-:AVSS BCLR AD1CON2,#VCFG1 BCLR AD1CON2,#VCFG2 ; c) Select the analog conversion clock to match desired data rate with processor clock (AD1CON3<7:0>) BCLR AD1CON3,#ADCS0 ; TCY/2 BCLR AD1CON3,#ADCS1 BCLR AD1CON3,#ADCS2 BCLR AD1CON3,#ADCS3 BCLR AD1CON3,#ADCS4 BCLR AD1CON3,#ADCS5 BCLR AD1CON3,#ADCS6 BCLR AD1CON3,#ADCS7 ; d) Select the appropriate sample/conversion sequence (AD1CON1<7:5> and AD1CON3<12:8>) BSET AD1CON1,#SSRC0 ; Internal counter ends sampling and starts conversion (auto-convert) BSET AD1CON1,#SSRC1 BSET AD1CON1,#SSRC2 BSET AD1CON3,#SAMC0 ; 1 TAD BCLR AD1CON3,#SAMC1 BCLR AD1CON3,#SAMC2 BCLR AD1CON3,#SAMC3 BCLR AD1CON3,#SAMC4 ; e) Select how conversion results are presented in the buffer (AD1CON1<9:8>) BCLR AD1CON1,#FORM0 ; Integer (0000 00dd dddd dddd) BCLR AD1CON1,#FORM1 ; f) 10-bit or 12-bit Operation Mode bit (AD1CON1<10>) BSET AD1CON1,#AD12B ; 1 = 12-bit, 1-channel ADC operation ; BCLR AD1CON1,#AD12B ; 0 = 10-bit, 4-channel ADC operation ; f) Select interrupt rate (AD1CON2<5:2>) BCLR AD1CON2,#SMPI0 ; Interrupts at the completion of conversion for each sample/convert sequence BCLR AD1CON2,#SMPI1 BCLR AD1CON2,#SMPI2 BCLR AD1CON2,#SMPI3 ; g) Turn on A/D module (AD1CON1<15>) BSET AD1CON1,#ADON ; Turn on the A/D converter ; ******************************* ; 2. Configure A/D interrupt (if required) ; ******************************* ; a) Clear the AD1IF bit ; BCLR IFS0,AD1IF ; Clear the A/D interrupt flag bit ; b) Select A/D interrupt priority ; BSET IEC0,AD1IE ; Enable A/D interrupt RETURN ;****************************************************************************************** ; Function Name : GetADC ; Title : Get A/D Converter Value ; Input : ; Output : ;****************************************************************************************** GetADC: ; ******************************* ; 1.Initialize ; ******************************* PUSH.W W0 PUSH.W W1 PUSH.W W2 PUSH.W W3 ; ******************************* ; 2. Program ; ******************************* ; (1)Set Flag SAMP : ADC Sample Enable bit ; 1=ADC sample-and-hold amplifiers are sampling BSET.W AD1CON1,#SAMP ; (2)Check IFS0(AD1IF) GetADC_1: MOV.W IFS0,W0 CLR.W W1 BSET.W W1,#AD1IF AND.W W0,W1,W2 SUB.W W2,#0,W1 BRA NZ,GetADC_2 BRA GetADC_1 ; (3)Get A/D_Data GetADC_2: MOV.W ADC1BUF0,W0 MOV.W W0,ADC_dat ; ******************************* ; E.End ; ******************************* POP.W W3 POP.W W2 POP.W W1 POP.W W0 RETURN