Estoy usando dsPIC33FJ128MC804, tengo la intención de leer desde ADC y enviarlo a UART, pero a través del DMA (acceso directo a la memoria) que se admite en esa MCU, uso Mplabx c16, hay un problema con mi código que no puedo imagínalo, siento que no hay nada malo, pero el resultado es 100% nada
#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)!='#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)!='%pre%')
{
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)
{
}
')
{
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)
{
}
}