Sign up ×
Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. It's 100% free.

I'm using dsPIC33FJ128MC804, i intend to read from ADC and send to UART but via the DMA ( direct memory access ) which is supported in that MCU , i use Mplabx c16 there is a problem with my code i can't figure it , i feel there is nothing wrong but the outcome is 100% nothing

#include <xc.h>

// FBS
#pragma config BWRP = WRPROTECT_OFF     // Boot Segment Write Protect (Boot Segment may be written)
#pragma config BSS = NO_FLASH           // Boot Segment Program Flash Code Protection (No Boot program Flash segment)
#pragma config RBS = NO_RAM             // Boot Segment RAM Protection (No Boot RAM)

// FSS
#pragma config SWRP = WRPROTECT_OFF     // Secure Segment Program Write Protect (Secure segment may be written)
#pragma config SSS = NO_FLASH           // Secure Segment Program Flash Code Protection (No Secure Segment)
#pragma config RSS = NO_RAM             // Secure Segment Data RAM Protection (No Secure RAM)

// FGS
#pragma config GWRP = OFF               // General Code Segment Write Protect (User program memory is not write-protected)
#pragma config GSS = OFF                // General Segment Code Protection (User program memory is not code-protected)

// FOSCSEL
#pragma config FNOSC = PRI              // Oscillator Mode (Primary Oscillator (XT, HS, EC))
#pragma config IESO = ON                // Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)

// FOSC
#pragma config POSCMD = XT              // Primary Oscillator Source (XT Oscillator Mode)
#pragma config OSCIOFNC = OFF           // OSC2 Pin Function (OSC2 pin has clock out function)
#pragma config IOL1WAY = ON             // Peripheral Pin Select Configuration (Allow Only One Re-configuration)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor (Both Clock Switching and Fail-Safe Clock Monitor are disabled)

// FWDT
#pragma config WDTPOST = PS32768        // Watchdog Timer Postscaler (1:32,768)
#pragma config WDTPRE = PR128           // WDT Prescaler (1:128)
#pragma config WINDIS = OFF             // Watchdog Timer Window (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = ON              // Watchdog Timer Enable (Watchdog timer always enabled)

// FPOR
#pragma config FPWRT = PWR128           // POR Timer Value (128ms)
#pragma config ALTI2C = OFF             // Alternate I2C  pins (I2C mapped to SDA1/SCL1 pins)
#pragma config LPOL = ON                // Motor Control PWM Low Side Polarity bit (PWM module low side output pins have active-high output polarity)
#pragma config HPOL = ON                // Motor Control PWM High Side Polarity bit (PWM module high side output pins have active-high output polarity)
#pragma config PWMPIN = ON              // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)

// FICD
#pragma config ICS = PGD1               // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)
#pragma config JTAGEN = OFF             // JTAG Port Enable (JTAG is Disabled)

#define FCY 4000000UL
#include <libpic30.h>


char  HReading ; char LReading ; int dummy ; int dummy2 ; 

/*const char Name[]="UART works\n" ;
const char ADCs[]="ADC1 Reading is : " ;
const char maxvalue[]=" it is the maximum value ";
const char lowvalue[]=" it is the lowest value ";*/
unsigned int ADCreading __attribute__((space (dma))) ;


void __attribute__((interrupt(auto_psv))) _U1TXInterrupt(void)
{
 IFS0bits.U1TXIF = 0 ; 
}
void __attribute__((interrupt(auto_psv))) _DMA0Interrupt(void)
{
    DMA1REQbits.FORCE=1 ; //Force a single DMA transfer 
    IFS0bits.DMA0IF = 0 ;
}
void __attribute__((interrupt(auto_psv))) _DMA1Interrupt(void)
{
    IFS0bits.DMA1IF = 0 ;
}
void __attribute__((interrupt(auto_psv))) _AD1Interrupt(void)
{
    IFS0bits.AD1IF = 0 ; 
}
 void UartConfig(void)
 {
    U1MODEbits.UARTEN=0; //disable  UART 
    U1MODEbits.BRGH=0 ; //  Speed Low
    U1BRG = 12 ; // 9600 
    U1MODEbits.PDSEL=00 ; // 8-bit data , no parity 
    U1MODEbits.STSEL=0 ; // 1 stop bit 
    U1STAbits.URXISEL= 0b00 ; // Interrupt flag bit is set when a character is received
    U1STAbits.UTXISEL0 = 1 ; U1STAbits.UTXISEL1 = 0 ;  // Interrupt is generated when the last transmission is over (that is, the last character is shifted out of the Transmit Shift register) and all the transmit operations are completed
    U1MODEbits.USIDL=0 ; //continue operation in idle mode
    U1MODEbits.IREN=0 ; //IrDA encoder and decoder are disabled , works only at low baud 
    U1MODEbits.RTSMD= 1 ; // RTS simplex mode , no flow control
    U1MODEbits.UEN=00 ; // UxTX and UxRX pins are enabled and used; UxCTS, UxRTS and BCLKx pins are  controlled by port latches
    U1MODEbits.WAKE= 1 ;//  wake-up is enabled
    U1MODEbits.LPBACK = 0 ; // loopback mode is disabled 
    U1MODEbits.ABAUD=0 ; // Baud rate measurement disabled or completed

    U1STAbits.UTXINV = 0 ; // ?? UxTx idle state is 0 if IREN = 0  Transmit Polarity Inversion bit 
    U1STAbits.UTXBRK = 0 ; // 0 = Sync Break transmission is disabled or completed

   U1STAbits.ADDEN = 0 ; // Address Detect mode disabled
    // U1RXREG Receive Register 
    // U1TXREG Transmit Register 
 OSCCON=0x46 ; 
 OSCCON = 0x57 ;
 OSCCONbits.IOLOCK=0 ;  // unlock PPS sequence 
 RPOR11bits.RP23R=0b00011 ;  // PORTC7 as TX 
 RPINR18bits.U1RXR = 22 ; // c6 as RX 
OSCCON=0x46 ; 
OSCCON = 0x57 ;
OSCCONbits.IOLOCK=1 ;  // lock PPS sequence */
   U1MODEbits.UARTEN=1; //enable UART 
    U1STAbits.UTXEN =1  ; // UARTx transmitt is enabled 

 }

  void InterruptConfig()
{
     // clear the flag after configuration 
    SRbits.IPL=000 ;   /* CPU operates at 0 level priority NOTE : Each peripheral 
    interrupt source can be assigned to one of seven priority levels. to disable all set it 111 */
    INTCON1bits.NSTDIS=0 ;                 // Int nesting is enabled 
    INTCON2bits.ALTIVT=0;                   // Use standard (default) vector table
    INTCON2bits.INT0EP= 1;   
    INTCON2bits.INT1EP= 1;
    INTCON2bits.INT2EP= 1;// External interrupt 0 & 1 & 2 are negative edge triggerred



    IEC0bits.AD1IE = 1 ; IEC0bits.DMA0IE = 1 ; IEC0bits.DMA1IE = 1 ; IEC0bits.U1TXIE = 1 ; 
}
  void UartSend(char a)
  {
      U1TXREG = a ; 

      while ( U1STAbits.TRMT!=1)   // Transmit Shift Register is Empty bit  1 = empty 
      { 
      }
  }
  void ADCconfig(void)
  {
      AD1CON1bits.ADON = 0 ; // ADC disabled 
      AD1CON1bits.ADSIDL = 0 ;  // Continue module operation in idle mode 
      AD1CON1bits.ADDMABM = 1 ; // 1 = DMA buffers are written in the order of conversion. The module provides an address to the DMA channel that is the same as the address used for the non-DMA stand-alone buffer
      AD1CON1bits.AD12B = 1 ; // 12bit operation mode 1 channel 
      AD1CON1bits.FORM= 0b00 ; // right justified unsigned 
      AD1CON1bits.SSRC = 0b111 ; // Internal counter ends sampling and starts conversion (auto-convert)
      AD1CON1bits.SIMSAM=0 ; // Samples multiple channels individually in sequence
      AD1CON1bits.ASAM=1 ; // sample automaticaly after last conversion  Automatic trigger 
      /*DONE: ADC Conversion Status bit
1 = ADC conversion cycle is completed
0 = ADC conversion not started or in progress*/
      AD1CON2bits.VCFG=0b000 ; // reference VDD VSS
      AD1CON2bits.CSCNA = 0 ; // do not scan inputs
      AD1CON2bits.SMPI=0b0000; // Increments the DMA address after completion of every sample/conversion operation

        AD1CON2bits.BUFM=0; //Always starts filling the buffer from the start address
AD1CON2bits.ALTS=0 ;//  Always uses channel input selects for Sample A 
AD1CON3bits.ADRC = 0 ; // Clock Derived from System Clock 
AD1CON3bits.SAMC= 0 ; //sample =  Tad 
      AD1CON3bits.ADCS=0b100 ; // 4TCY = TAD the least Tad = 117.6 nano second , 
      AD1CON4bits.DMABL = 000 ; // 001 = Allocates 1 words of buffer to each analog input 
      AD1PCFGLbits.PCFG5=0; //Analog
       AD1PCFGLbits.PCFG6=0 ; //Analog 
        AD1PCFGLbits.PCFG1=0; //Analog
        AD1CHS0bits.CH0SA= 1; //Channel 0 positive input is 5 
                AD1CHS0bits.CH0NA= 0 ; //Channel 0 negative input is VREFL
        //ADCxBUF0 

  }
  void UartSendString(char* x )
  {
      while((*x)!='\0')
      {
          U1TXREG = *x ;

          while ( U1STAbits.TRMT!=1)   // Transmit Shift Register is Empty bit  1 = empty 
          {}
          x++ ;
      }
  }
  void DMAconfig(void)
  {
      // Channel 0  reads from ADC 
      DMA0CONbits.CHEN=0 ; //channel disabled 
            DMA0REQbits.IRQSEL=0b0001101 ; //ADC1 

      DMA0CONbits.SIZE = 0 ; // word ; 
      DMA0CONbits.DIR=0 ; // Read from peripheral and write to DPSRAM 
      DMA0CONbits.HALF = 0 ; // Initiate interrupt when all of the data has been moved
      DMA0CONbits.NULLW=0 ; // Normal operation 
      DMA0CONbits.AMODE = 0b01 ; // Register Indirect without Post-Increment mode
      DMA0CONbits.MODE= 00 ; // continuous no ping pong 
      DMA0REQbits.FORCE=0 ; //Auto
      DMA0PAD =(unsigned int )  &ADC1BUF0  ; 
      DMA0STA = __builtin_dmaoffset(&ADCreading) ;
      DMA0CNT=0 ;  // only one element ;
      IFS0bits.DMA0IF = 0;   //clear flag 

      // channel 1 to send to UART 

      DMA1CONbits.CHEN=0 ; //channel disabled  
      DMA1REQbits.IRQSEL =0b0001100 ;   // uart tX 
      DMA1CONbits.SIZE = 0 ; // word ; 
      DMA1CONbits.DIR=1 ; // Read from DPSRAM address, write to peripheral address
      DMA1CONbits.HALF = 0 ; // Initiate interrupt when all of the data has been moved
      DMA1CONbits.NULLW=0 ; // Normal operation 
      DMA1CONbits.AMODE = 0b01 ; // Register Indirect without Post-Increment mode
      DMA1CONbits.MODE= 00 ; // continuous no ping pong 

     DMA1PAD = ( unsigned int) &U2TXREG;
     DMA1STA=__builtin_dmaoffset(&ADCreading) ;
      DMA1CNT=0 ;  // only one element ;
     IFS0bits.DMA1IF=0 ;    //clear flag 
     DMA0CONbits.CHEN=1 ; //channel enabled  
     DMA1CONbits.CHEN=1 ; //channel enabled   

  }
int main ()
{ 
 I2C1CONbits.I2CEN=0;//Disables the I2Cx module. All I2C? pins are controlled by port functions
 PMCONbits.PMPEN = 0 ; // PMP is disabled  
 P2TCONbits.PTEN=0 ; // PWM time base is off 
 PWM2CON1bits.PEN1H=0;  //  disable PWM pins 
 PWM2CON1bits.PEN1L = 0 ; // 
 TRISCbits.TRISC8=0 ; // Red led output 
 TRISCbits.TRISC9=0 ; // Green led output 
 TRISCbits.TRISC7=0 ; 
 PORTCbits.RC9=1 ; //G LED on 
 PORTCbits.RC8 = 1 ; // R ON 
 InterruptConfig() ;
DMAconfig(); 
ADCconfig() ;
AD1CON1bits.ADON = 1 ; // ADC ON 
 __delay_us(100) ;
UartConfig() ;
      DMA0REQbits.FORCE=1 ; 

while (1)
{

  }

}

share|improve this question
    
unsigned int ADCreading __attribute__((space (dma))) ;..........if this is a variable for your adc value..simply define int ADCredaing. and check –  Vignesh Vicky 2 days ago
    
no , because that must be allocated in the DMA if you just defined it that way the memory address maybe out the DMA authority –  Mohamed Osama 2 days ago

1 Answer 1

up vote 0 down vote accepted

After many tries at last it works , the code for anyone who wants it :

#include <xc.h>

// FBS

pragma config BWRP = WRPROTECT_OFF // Boot Segment Write Protect (Boot Segment may be written)

pragma config BSS = NO_FLASH // Boot Segment Program Flash Code Protection (No Boot program Flash segment)

pragma config RBS = NO_RAM // Boot Segment RAM Protection (No Boot RAM)

// FSS

pragma config SWRP = WRPROTECT_OFF // Secure Segment Program Write Protect (Secure segment may be written)

pragma config SSS = NO_FLASH // Secure Segment Program Flash Code Protection (No Secure Segment)

pragma config RSS = NO_RAM // Secure Segment Data RAM Protection (No Secure RAM)

// FGS

pragma config GWRP = OFF // General Code Segment Write Protect (User program memory is not write-protected)

pragma config GSS = OFF // General Segment Code Protection (User program memory is not code-protected)

// FOSCSEL

pragma config FNOSC = PRI // Oscillator Mode (Primary Oscillator (XT, HS, EC))

pragma config IESO = ON // Internal External Switch Over Mode (Start-up device with FRC, then automatically switch to user-selected oscillator source when ready)

// FOSC

pragma config POSCMD = XT // Primary Oscillator Source (XT Oscillator Mode)

pragma config OSCIOFNC = OFF // OSC2 Pin Function (OSC2 pin has clock out function)

pragma config IOL1WAY = ON // Peripheral Pin Select Configuration (Allow Only One Re-configuration)

pragma config FCKSM = CSDCMD // Clock Switching and Monitor (Both Clock Switching and Fail-Safe Clock Monitor are disabled)

// FWDT

pragma config WDTPOST = PS32768 // Watchdog Timer Postscaler (1:32,768)

pragma config WDTPRE = PR128 // WDT Prescaler (1:128)

pragma config WINDIS = OFF // Watchdog Timer Window (Watchdog Timer in Non-Window mode)

pragma config FWDTEN = ON // Watchdog Timer Enable (Watchdog timer always enabled)

// FPOR

pragma config FPWRT = PWR128 // POR Timer Value (128ms)

pragma config ALTI2C = OFF // Alternate I2C pins (I2C mapped to SDA1/SCL1 pins)

pragma config LPOL = ON // Motor Control PWM Low Side Polarity bit (PWM module low side output pins have active-high output polarity)

pragma config HPOL = ON // Motor Control PWM High Side Polarity bit (PWM module high side output pins have active-high output polarity)

pragma config PWMPIN = ON // Motor Control PWM Module Pin Mode bit (PWM module pins controlled by PORT register at device Reset)

// FICD

pragma config ICS = PGD1 // Comm Channel Select (Communicate on PGC1/EMUC1 and PGD1/EMUD1)

pragma config JTAGEN = OFF // JTAG Port Enable (JTAG is Disabled)

define FCY 4000000UL

include

int dummy ; int dummy2 ; char flag =0; char LReading , HReading ; unsigned int ADCreading[1] attribute((space (dma))) ; unsigned char UARTsignal[2] attribute((space (dma))) ; void interruptconf(void) { SRbits.IPL=000 ; /* CPU operates at 0 level priority NOTE : Each peripheral interrupt source can be assigned to one of seven priority levels. to disable all set it 111 */ INTCON1bits.NSTDIS=1 ; // Int nesting is disabled
INTCON2bits.ALTIVT=0; // Use standard (default) vector table IEC0bits.AD1IE = 0 ; IEC0bits.DMA0IE = 1 ; IEC0bits.DMA1IE = 1 ; IEC0bits.U1TXIE = 0 ; IFS0bits.AD1IF=0 ; IFS0bits.DMA0IF=0 ; IFS0bits.U1TXIF = 0 ; IFS0bits.DMA1IF=0 ; } void ADCconf(void) { AD1CON1bits.ADON = 0 ; // ADC disabled AD1CON1bits.ADDMABM = 1 ; // 1 = DMA buffers are written in the order of conversion. The module provides an address to the DMA channel that is the same as the address used for the non-DMA stand-alone buffer AD1CON1bits.AD12B = 1 ; // 12bit operation mode 1 channel AD1CON1bits.FORM= 0b00 ; // right justified unsigned AD1CON1bits.SSRC = 0b111 ; // Internal counter ends sampling and starts conversion (auto-convert) AD1CON1bits.ASAM=1 ; // sample automaticaly after last conversion Automatic trigger AD1CON2bits.VCFG=0b000 ; // reference VDD VSS AD1CON2bits.CSCNA = 0 ; // do not scan inputs AD1CON2bits.SMPI=0b0000; // Increments the DMA address after completion of every sample/conversion operation AD1CON2bits.BUFM=0; //Always starts filling the buffer from the start address AD1CON2bits.ALTS=0 ;// Always uses channel input selects for Sample A AD1CON3bits.ADRC = 0 ; // Clock Derived from System Clock AD1CON3bits.SAMC= 2 ; // AD1CON3bits.ADCS=0b100 ; // 4TCY = TAD the least Tad = 117.6 nano second , AD1CON4bits.DMABL = 000 ; // 001 = Allocates 1 words of buffer to each analog input AD1PCFGLbits.PCFG5=0; //Analog AD1PCFGLbits.PCFG6=0 ; //Analog AD1PCFGLbits.PCFG1=0; //Analog AD1CHS0bits.CH0SA= 0b00001; //Channel 0 positive input is 5 AD1CHS0bits.CH0NA= 0 ; //Channel 0 negative input is VREFL } void UartSend(char a) { U1TXREG = a ;

  while ( U1STAbits.TRMT!=1)   // Transmit Shift Register is Empty bit  1 = empty 
  { 
  }

} void UARTconf(void) { U1MODEbits.UARTEN=0; //disable UART U1MODEbits.BRGH=0 ; // Speed Low U1BRG = 12 ; // 9600 U1MODEbits.PDSEL=00 ; // 8-bit data , no parity U1MODEbits.STSEL=0 ; // 1 stop bit U1STAbits.URXISEL= 0b00 ; // Interrupt flag bit is set when a character is received U1STAbits.UTXISEL0 = 0 ; U1STAbits.UTXISEL1 = 0 ; // Interrupt generated when any character is transferred to the Transmit Shift register (which ast one location is empty in the transmit buffer) U1MODEbits.USIDL=0 ; //continue operation in idle mode U1MODEbits.IREN=0 ; //IrDA encoder and decoder are disabled , works only at low baud U1MODEbits.RTSMD= 1 ; // RTS simplex mode , no flow control U1MODEbits.UEN=00 ; // UxTX and UxRX pins are enabled and used; UxCTS, UxRTS and BCLKx pins are controlled by port latches U1MODEbits.WAKE= 1 ;// wake-up is enabled U1MODEbits.LPBACK = 0 ; // loopback mode is disabled U1MODEbits.ABAUD=0 ; // Baud rate measurement disabled or completed U1STAbits.UTXINV = 0 ; // ?? UxTx idle state is 0 if IREN = 0 Transmit Polarity Inversion bit U1STAbits.UTXBRK = 0 ; // 0 = Sync Break transmission is disabled or completed U1STAbits.ADDEN = 0 ; // Address Detect mode disabled

} void DMA0conf(void) { //for ADC DMA0CONbits.CHEN=0 ; //channel disabled DMA0PAD =(volatile unsigned int ) &ADC1BUF0 ; DMA0CNT=0 ; // only one element ; DMA0REQbits.IRQSEL=0b0001101 ; //ADC DMA0STA = __builtin_dmaoffset(ADCreading) ; IFS0bits.DMA0IF = 0; //clear flag DMA0CONbits.SIZE = 0 ; // word ; DMA0CONbits.DIR=0 ; // ADC to ram DMA0CONbits.HALF = 0 ; // Initiate interrupt when all of the data has been moved DMA0CONbits.NULLW=0 ; // Normal operation DMA0CONbits.AMODE = 0b01 ; // Register Indirect without Post-Increment mode DMA0CONbits.MODE= 00 ; // continuous no ping pong DMA0REQbits.FORCE=0 ; //Auto DMA0CONbits.CHEN=1 ; //channel enabled

} void DMA1conf(void) { // for TX DMA1CONbits.CHEN=0 ; //channel disabled DMA1REQbits.IRQSEL=0b0001100 ; DMA1PAD =(volatile unsigned int ) &U1TXREG ; DMA1CNT=1 ; // only two element ; DMA1STA = __builtin_dmaoffset(UARTsignal) ;

IFS0bits.DMA1IF = 0;   //clear flag 
DMA1CONbits.SIZE = 1 ; // byte ; 
DMA1CONbits.DIR=1 ; // RAM to TX 
DMA1CONbits.HALF = 0 ; // Initiate interrupt when all of the data has been moved
DMA1CONbits.NULLW=0 ; // Normal operation 
DMA1CONbits.AMODE = 0b00 ; // Register Indirect with Post-Increment mode
DMA1CONbits.MODE= 00 ; // continuous no ping pong 
DMA1REQbits.FORCE=0 ; //Auto
DMA1CONbits.CHEN=1 ; //channel enabled      

} void attribute((interrupt(no_auto_psv))) _DMA0Interrupt(void) { PORTCbits.RC8 = 1 ; // R ON

if(flag == 1 )
{
dummy =ADCreading[0] ;
dummy2 = (0b0000000011111111 & dummy );
LReading = dummy2 ; 
dummy2=0b1111111100000000&dummy ;
dummy2=dummy2>>8 ;
HReading= dummy2 ; 
UARTsignal[1]=HReading; UARTsignal[0]=LReading ; 
flag=0;
}
 IFS0bits.DMA0IF = 0 ;

} void attribute((interrupt(no_auto_psv))) _DMA1Interrupt(void) { flag = 1 ; PORTCbits.RC9 = 1 ; IFS0bits.DMA1IF = 0 ; } void attribute((interrupt(no_auto_psv))) _U1TXInterrupt(void) { IFS0bits.U1TXIF = 0 ; } int main() {

I2C1CONbits.I2CEN=0;//Disables the I2Cx module. All I2C? pins are controlled by port functions

PMCONbits.PMPEN = 0 ; // PMP is disabled
P2TCONbits.PTEN=0 ; // PWM time base is off PWM2CON1bits.PEN1H=0; // disable PWM pins PWM2CON1bits.PEN1L = 0 ; // OSCCON=0x46 ; OSCCON = 0x57 ; OSCCONbits.IOLOCK=0 ; // unlock PPS sequence RPOR11bits.RP23R=0b00011 ; // PORTC7 as TX RPINR18bits.U1RXR = 22 ; // c6 as RX OSCCON=0x46 ; OSCCON = 0x57 ; OSCCONbits.IOLOCK=1 ; // lock PPS sequence */ TRISCbits.TRISC8=0 ; // Red led output TRISCbits.TRISC9=0 ; // Green led output PORTCbits.RC8 = 0 ; // R OFF
PORTCbits.RC9 = 0 ; interruptconf() ; DMA0conf() ; DMA1conf() ; ADCconf() ; UARTconf() ; AD1CON1bits.ADON = 1 ; // ADC enabled __delay_ms(100) ; U1MODEbits.UARTEN=1; //enable UART U1STAbits.UTXEN =1 ; // UARTx transmitt is enabled DMA1REQbits.FORCE=1 ; //Auto while(1) {

}
return 0 ; 

}

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.