Hi everyone
I am using DSPIC33FJ256MC710-I/PT and my compiler is MiKroC pro for DSpic I want to scan 2 ADC pin (AN17 , AN18), and as we know we have to use DMA to scan simultaneously, here is my code but when I program my micro controller I faced '0'
/// Setup of LCD////
sbit LCD_RS at LATF8_bit;
sbit LCD_EN at LATD3_bit;
sbit LCD_D4 at LATC13_bit;
sbit LCD_D5 at LATD0_bit;
sbit LCD_D6 at LATD2_bit;
sbit LCD_D7 at LATF7_bit;
sbit LCD_RS_Direction at TRISF8_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISC13_bit;
sbit LCD_D5_Direction at TRISD0_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISF7_bit;
dma unsigned int dma_bufferA[24][4] absolute 0x7800;//Offset 0 DMA_START_ADDRESS = 0x7800;
//dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8
dma unsigned int dma_bufferB[24][4] absolute 0x7A00;//Offset 200
unsigned int DmaBuffer = 0;
unsigned int ch17=0;
unsigned int ch18=0;
int flag = 0;
char str[16];
char str_1[16];
void InitADC(){
////// ADC config/////
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer (Q15 format) Figure 16-14: ADC Output Format 70183D.pdf//
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
AD1CON1bits.ASAM = 1; // Sampling begins when SAMP bit is set (for now)
AD1CON1bits.AD12B = 1; // 12-bit ADC operation
AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode
AD1CON2bits.VCFG=0; //Vref+=AVDD Vref-=AVSS//
AD1CON2bits.SMPI = 1; // (NUM_CHS2SCAN-1); // 2 ADC Channel is scanned
AD1CON2bits.CHPS = 0; // Converts CH0/CH1 When AD12B = 1, CHPS<1:0> is: U-0, Unimplemented, Read as ‘0’
AD1CON2bits.CSCNA=1; //Scan inputs // Scan Input Selections for CH0+ during Sample A bit
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.SAMC = 2; // Auto Sample Time = 2*Tad
AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*3 = 75ns (13.3Mhz)
// ADC Conversion Time for 10-bit Tc=14*Tad = 900ns (1.1MHz)
//for 500 Khz sampling in 12-bit 1/500KHz=2*10^-6=200 ns
//200ns=14Tad-->Tad=142ns---> ADCS+1=40M*142ns=5.71--> ADCS=~4
AD1CON4bits.DMABL = 2; // Each buffer contains 4 words
//AD1CSSH/AD1CSSL: A/D Input Scan Selection Register
///??? AD1CHS0bits.CH0SB = 0b10110; //17=10001 22=0b10110 // MUXA +ve input selection (AN0) for CH0
AD1CHS0bits.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0
AD1CSSHbits.CSS17=1; // Enable AN17 for channel scan
AD1CSSHbits.CSS18=1; // Enable AN18 for channel scan
//AD1CSSH=0x40;//0x2; //ADC1 INPUT SCAN SELECT REGISTER HIGH
AD1CSSL=0; //ADC1 INPUT SCAN SELECT REGISTER Low
IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1; // Turn on the A/D converter
}
// DMA0 configuration
// Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
// AMODE: Peripheral Indirect Addressing Mode
// MODE: Continuous, Ping-Pong Mode
// IRQ: ADC Interrupt
void initDma0(void)
{
DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode
DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0;
DMA0CNT = 7; //(SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;
DMA0REQ = 13; // Select ADC1 as DMA Request source
// DMA0STA = __builtin_dmaoffset(BufferA);
// DMA0STB = __builtin_dmaoffset(BufferB);
DMA5STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset
DMA5STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address
// DMA0STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset
// DMA0STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1; // Enable DMA
}
void Timer1Interrupt() iv IVT_ADDR_DMA5INTERRUPT
{
if(DmaBuffer == 0)
{
ch17=&dma_bufferA[17][4];
ch18=&dma_bufferA[18][4];
// ProcessADCSamples(&BufferA[18][0]);
}
else
{
ch17=&dma_bufferB[17][4];
ch18=&dma_bufferB[17][4];
//ProcessADCSamples(&BufferB[17][0]);
// ProcessADCSamples(&BufferB[18][0]);
}
DmaBuffer ^= 1;
LATF.F4=~LATF.F4;
IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag
}
void main() {
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
AD1PCFGHbits.PCFG17 = 0; // AN17 as Analog Input
AD1PCFGHbits.PCFG18 = 0; // AN18 as Analog Input
PORTA=0;
PORTC=0;
TRISA.F6= 1;
TRISA.F7= 1;
TRISF.F4= 0;
TRISF.F5= 0;
TRISB.F12= 0;
TRISB.F13= 0;
TRISC.F2= 1; // AN17
TRISC.F3= 1; // AN18
///////////////PLL configue////////
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
OSCCONbits.COSC=0x03; //0b 011 Primary oscillator (XT, HS, EC) with PLL
OSCCONbits.OSWEN=0x1; //
CLKDIVbits.PLLPRE=0; // N1=2 N1=PLLPRE+2
CLKDIVbits.PLLPOST=0; // N2=2 N2=2*(PLLPost+1)
PLLFBDbits.PLLDIV=38; // M=40 M=PLLDIV+2
////////////// Disable Watch Dog Timer////////
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
/////////////////
Lcd_init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"Hello");
delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
InitAdc(); // Initialize the A/D converter to convert Channel 5
InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order
while(1){
intToStr(ch17,str);
Lcd_Out(1,1,str);
intToStr(ch18,str_1);
Lcd_Out(1,2,str_1);
Delay_ms(50);
// LATF.F4=0;
LATF.F5=1;
LATB.F12=0;
LATB.F13=1;
delay_ms(50);
// LATF.F4=1;
LATF.F5=0;
LATB.F12=1;
LATB.F13=0;
}
}
Could you please help me what my fault is?
Is there anybody have example the ADC to DMA and showing on LCD in dspic?
Thank you in advance
Kind regards
I am using DSPIC33FJ256MC710-I/PT and my compiler is MiKroC pro for DSpic I want to scan 2 ADC pin (AN17 , AN18), and as we know we have to use DMA to scan simultaneously, here is my code but when I program my micro controller I faced '0'
/// Setup of LCD////
sbit LCD_RS at LATF8_bit;
sbit LCD_EN at LATD3_bit;
sbit LCD_D4 at LATC13_bit;
sbit LCD_D5 at LATD0_bit;
sbit LCD_D6 at LATD2_bit;
sbit LCD_D7 at LATF7_bit;
sbit LCD_RS_Direction at TRISF8_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISC13_bit;
sbit LCD_D5_Direction at TRISD0_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D7_Direction at TRISF7_bit;
dma unsigned int dma_bufferA[24][4] absolute 0x7800;//Offset 0 DMA_START_ADDRESS = 0x7800;
//dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8
dma unsigned int dma_bufferB[24][4] absolute 0x7A00;//Offset 200
unsigned int DmaBuffer = 0;
unsigned int ch17=0;
unsigned int ch18=0;
int flag = 0;
char str[16];
char str_1[16];
void InitADC(){
////// ADC config/////
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer (Q15 format) Figure 16-14: ADC Output Format 70183D.pdf//
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
AD1CON1bits.ASAM = 1; // Sampling begins when SAMP bit is set (for now)
AD1CON1bits.AD12B = 1; // 12-bit ADC operation
AD1CON1bits.ADDMABM = 0; // DMA buffers are built in scatter/gather mode
AD1CON2bits.VCFG=0; //Vref+=AVDD Vref-=AVSS//
AD1CON2bits.SMPI = 1; // (NUM_CHS2SCAN-1); // 2 ADC Channel is scanned
AD1CON2bits.CHPS = 0; // Converts CH0/CH1 When AD12B = 1, CHPS<1:0> is: U-0, Unimplemented, Read as ‘0’
AD1CON2bits.CSCNA=1; //Scan inputs // Scan Input Selections for CH0+ during Sample A bit
AD1CON3bits.ADRC = 0; // ADC Clock is derived from Systems Clock
AD1CON3bits.SAMC = 2; // Auto Sample Time = 2*Tad
AD1CON3bits.ADCS = 3; // ADC Conversion Clock Tad=Tcy*(ADCS+1)= (1/40M)*3 = 75ns (13.3Mhz)
// ADC Conversion Time for 10-bit Tc=14*Tad = 900ns (1.1MHz)
//for 500 Khz sampling in 12-bit 1/500KHz=2*10^-6=200 ns
//200ns=14Tad-->Tad=142ns---> ADCS+1=40M*142ns=5.71--> ADCS=~4
AD1CON4bits.DMABL = 2; // Each buffer contains 4 words
//AD1CSSH/AD1CSSL: A/D Input Scan Selection Register
///??? AD1CHS0bits.CH0SB = 0b10110; //17=10001 22=0b10110 // MUXA +ve input selection (AN0) for CH0
AD1CHS0bits.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0
AD1CSSHbits.CSS17=1; // Enable AN17 for channel scan
AD1CSSHbits.CSS18=1; // Enable AN18 for channel scan
//AD1CSSH=0x40;//0x2; //ADC1 INPUT SCAN SELECT REGISTER HIGH
AD1CSSL=0; //ADC1 INPUT SCAN SELECT REGISTER Low
IFS0bits.AD1IF = 0; // Clear the A/D interrupt flag bit
IEC0bits.AD1IE = 0; // Do Not Enable A/D interrupt
AD1CON1bits.ADON = 1; // Turn on the A/D converter
}
// DMA0 configuration
// Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to DMA RAM
// AMODE: Peripheral Indirect Addressing Mode
// MODE: Continuous, Ping-Pong Mode
// IRQ: ADC Interrupt
void initDma0(void)
{
DMA0CONbits.AMODE = 2; // Configure DMA for Peripheral indirect mode
DMA0CONbits.MODE = 2; // Configure DMA for Continuous Ping-Pong mode
DMA0PAD=(int)&ADC1BUF0;
DMA0CNT = 7; //(SAMP_BUFF_SIZE*NUM_CHS2SCAN)-1;
DMA0REQ = 13; // Select ADC1 as DMA Request source
// DMA0STA = __builtin_dmaoffset(BufferA);
// DMA0STB = __builtin_dmaoffset(BufferB);
DMA5STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset
DMA5STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address
// DMA0STA = &dma_bufferA; // A 16-bit DMA RAM Primary Start Address Offset
// DMA0STB = &dma_bufferB; //A 16-bit DMA RAM Secondary Start Address
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1; // Enable DMA
}
void Timer1Interrupt() iv IVT_ADDR_DMA5INTERRUPT
{
if(DmaBuffer == 0)
{
ch17=&dma_bufferA[17][4];
ch18=&dma_bufferA[18][4];
// ProcessADCSamples(&BufferA[18][0]);
}
else
{
ch17=&dma_bufferB[17][4];
ch18=&dma_bufferB[17][4];
//ProcessADCSamples(&BufferB[17][0]);
// ProcessADCSamples(&BufferB[18][0]);
}
DmaBuffer ^= 1;
LATF.F4=~LATF.F4;
IFS0bits.DMA0IF = 0; // Clear the DMA0 Interrupt Flag
}
void main() {
//AD1PCFGH/AD1PCFGL: Port Configuration Register
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
AD1PCFGHbits.PCFG17 = 0; // AN17 as Analog Input
AD1PCFGHbits.PCFG18 = 0; // AN18 as Analog Input
PORTA=0;
PORTC=0;
TRISA.F6= 1;
TRISA.F7= 1;
TRISF.F4= 0;
TRISF.F5= 0;
TRISB.F12= 0;
TRISB.F13= 0;
TRISC.F2= 1; // AN17
TRISC.F3= 1; // AN18
///////////////PLL configue////////
// Configure Oscillator to operate the device at 40Mhz
// Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
// Fosc= 8M*40/(2*2)=80Mhz for 8M input clock
OSCCONbits.COSC=0x03; //0b 011 Primary oscillator (XT, HS, EC) with PLL
OSCCONbits.OSWEN=0x1; //
CLKDIVbits.PLLPRE=0; // N1=2 N1=PLLPRE+2
CLKDIVbits.PLLPOST=0; // N2=2 N2=2*(PLLPost+1)
PLLFBDbits.PLLDIV=38; // M=40 M=PLLDIV+2
////////////// Disable Watch Dog Timer////////
RCONbits.SWDTEN=0; // Disable Watch Dog Timer
/////////////////
Lcd_init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"Hello");
delay_ms(1000);
Lcd_Cmd(_LCD_CLEAR); // CLEAR display
InitAdc(); // Initialize the A/D converter to convert Channel 5
InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order
while(1){
intToStr(ch17,str);
Lcd_Out(1,1,str);
intToStr(ch18,str_1);
Lcd_Out(1,2,str_1);
Delay_ms(50);
// LATF.F4=0;
LATF.F5=1;
LATB.F12=0;
LATB.F13=1;
delay_ms(50);
// LATF.F4=1;
LATF.F5=0;
LATB.F12=1;
LATB.F13=0;
}
}
Could you please help me what my fault is?
Is there anybody have example the ADC to DMA and showing on LCD in dspic?
Thank you in advance
Kind regards