Hi everyone
I am using DSPIC33FJ256MC710-I/PT and I try to scan 2 ADC pins (AN22, AN23 )simultaneously. I want to use DMA for ADC sampling and I read a lot of document about it in Microchip but I have problem how to read from DMA buffer.
in the Microchip documentation , I face some codes that they are not cleared in MikroC pro for dspic like:
__eds__ int bufferA[NUMSAMP] __attribute__( (eds, space(dma)) );
__eds__ int bufferB[NUMSAMP] __attribute__( (eds, space(dma)) );
#else
int bufferA[NUMSAMP] __attribute__( (space(xmemory)) );
int bufferB[NUMSAMP] __attribute__( (space(xmemory)) );
#endif
void ProcessADCSamples( __eds__ int *adcBuffer );
void ProcessADCSamples( __eds__ int *adcBuffer )
{
/* Do something with ADC Samples */
}
void __attribute__ ( (interrupt, auto_psv) ) _DMA0Interrupt( void )
DMA0STAL = __builtin_dmaoffset( &bufferA );
DMA0STAH = __builtin_dmapage( &bufferA );
DMA0STBL = __builtin_dmaoffset( &bufferB );
DMA0STBH = __builtin_dmapage( &bufferB );
How to convert this codes from MPLAB to MikroC pro for dspic??
I read some topics in this forum about how to read DMA register like :
viewtopic.php?f=101&t=23974
but it is not clear for me
could you please help me how to read from DMA register and what is the DMA address?
in my dspic
DMA_START_ADDRESS = 0x7800;
Are there any examples of ADC to DMA in a mikroC project ?
please help me
thank you in advance
best regards
examples of ADC to DMA in a mikroC project
- uros.cvetinovic
- mikroElektronika team
- Posts: 803
- Joined: 14 Dec 2015 09:24
Re: examples of ADC to DMA in a mikroC project
Hi,
Unfortunately, we don't have library, nor any example regarding DMA.
I can suggest you to check this document, DMA is well described there:
http://ww1.microchip.com/downloads/en/D ... 70182C.pdf
Use MCU's registers for accessing DMA.
Best regards,
Uros
Unfortunately, we don't have library, nor any example regarding DMA.
I can suggest you to check this document, DMA is well described there:
http://ww1.microchip.com/downloads/en/D ... 70182C.pdf
Use MCU's registers for accessing DMA.
Best regards,
Uros
-
- Posts: 12
- Joined: 08 Nov 2016 17:22
Re: examples of ADC to DMA in a mikroC project
Hi
thank you so much Uros because of your attention and helpful link
I read the document but Sorry I am new in dspic and I have question
I write the code but I have some problems that I cannot the show DMA value on the LCD screen
I mean I do not know how to read DMA register (which register I have to read) and show them on LCD
could you please or anybody help me
thank you so much in advance
/// 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 = 0x4000;
dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8
void InitADC(){
////// ADC config/////
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
AD1CON1bits.ASAM = 0; // 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; //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.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0
AD1CSSH.CSS17=1; // Enable AN17 for channel scan
AD1CSSH.CSS18=1; // Enable AN18 for channel scan
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;
DMA5STB = &dma_bufferB;
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1; // Enable DMA
}
/*=============================================================================
_DMA0Interrupt(): ISR name is chosen from the device linker script.
=============================================================================*/
unsigned int DmaBuffer = 0;
int flag = 0;
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
DmaBuffer ^= 1;
flag = 1;
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;
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
InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order
InitAdc1(); // Initialize the A/D converter to convert Channel 5
while(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;
}
}
thank you so much Uros because of your attention and helpful link
I read the document but Sorry I am new in dspic and I have question
I write the code but I have some problems that I cannot the show DMA value on the LCD screen
I mean I do not know how to read DMA register (which register I have to read) and show them on LCD
could you please or anybody help me
thank you so much in advance
/// 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 = 0x4000;
dma unsigned int dma_bufferB[24][4] absolute 0x7808;//Offset 8
void InitADC(){
////// ADC config/////
AD1CON1bits.FORM = 0; // Data Output Format: UnSigned Integer
AD1CON1bits.SSRC = 7; // Internal counter ends sampling and starts conversion (auto-convert)
AD1CON1bits.ASAM = 0; // 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; //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.CH0NB = 0; // MUXA -ve input selection (Vref-) for CH0
AD1CSSH.CSS17=1; // Enable AN17 for channel scan
AD1CSSH.CSS18=1; // Enable AN18 for channel scan
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;
DMA5STB = &dma_bufferB;
IFS0bits.DMA0IF = 0; //Clear the DMA interrupt flag bit
IEC0bits.DMA0IE = 1; //Set the DMA interrupt enable bit
DMA0CONbits.CHEN=1; // Enable DMA
}
/*=============================================================================
_DMA0Interrupt(): ISR name is chosen from the device linker script.
=============================================================================*/
unsigned int DmaBuffer = 0;
int flag = 0;
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void)
{
DmaBuffer ^= 1;
flag = 1;
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;
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
InitDma0(); // Initialise the DMA controller to buffer ADC data in conversion order
InitAdc1(); // Initialize the A/D converter to convert Channel 5
while(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;
}
}
- uros.cvetinovic
- mikroElektronika team
- Posts: 803
- Joined: 14 Dec 2015 09:24
Re: examples of ADC to DMA in a mikroC project
Hi,
Unfortunately, user's projects are out of scope of technical support.
I can suggest you to check reference manual that I gave you in details.
Can you also tell me if you have any problem regarding communication with LCD itself regardless of DMA?
Best regards,
Uros
Unfortunately, user's projects are out of scope of technical support.
I can suggest you to check reference manual that I gave you in details.
Can you also tell me if you have any problem regarding communication with LCD itself regardless of DMA?
Best regards,
Uros
-
- Posts: 12
- Joined: 08 Nov 2016 17:22
Re: examples of ADC to DMA in a mikroC project
Hi Dear Uros
you are right
thank you for your help
when I want to scan one ADC pin, I have no problem and I can get good result and show it on LCD without any problem
my problem is how to use DMA for 2 Pins
you are right
thank you for your help
when I want to scan one ADC pin, I have no problem and I can get good result and show it on LCD without any problem
my problem is how to use DMA for 2 Pins