[elektro] dsPic C hogyan iskell -> pinpong buffer

elight at gmail.com elight at gmail.com
Wed Jun 5 16:04:57 CEST 2013


Sziasztok.

dsPIC33 -ban szeretnék egy Ping-Pong buffert
létrehozni, de nem eszi meg a MikroC  fordító a
Mikrochip C30 definíciót.

Segítségre lenne szükségem,
  mit is kell érteni az alábbi alatt,
illetve hogyan tudom kifejteni C sorokká.

fractional BufferA[NUMSAMP] __attribute__((space(dma)));    // Ping-pong 
buffer A
fractional BufferB[NUMSAMP] __attribute__((space(dma)));    // Ping-pong 
buffer B


A többivel már megküzdöttem
Az INT -et már működnek.

Az egésznek annyi a célja hogy az analog
bemenetet másolja folyamatosan a
kimenetre, és ha műxik,
azután kellene közé még egy jobbfajta sávszűrő
modjuk 1 - 10kHz -re.

Üdv István


U.I  :-/


A teljesség kedvéért
bemásolom a teljes LIB-et.

A main tulajdonképpen még
semmit se csinál,
( üres loop )
mert ugye itt a INT dolgozgatna..

##################################################x

AdcDacLoopback.h
//---------------------------------------------
#ifndef __ADCDRV1_H__
#define __ADCDRV1_H__

// Sampling Control
#define Fosc        79227500
#define Fcy            (Fosc/2)
#define Fs           103160 //8038 //44211 //25000 // //Hz
#define SAMPPRD    (Fcy/Fs)-1
#define NUMSAMP     256

// Functions
void initAdc(void);
void initDac(void);
void initTmr3(void);
void initDma0(void);
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void);
void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void);
#endif
//-------------------------------------------




AdcDacLoopback.c
//-------------------------------------------------------
// Copyrigt:  Mikrochip

#include "p33fxxxx.h"
#include "dsp.h"
#include "..\h\adcdacLoopback.h"

fractional BufferA[NUMSAMP] __attribute__((space(dma)));    // Ping-pong 
buffer A
fractional BufferB[NUMSAMP] __attribute__((space(dma)));    // Ping-pong 
buffer B

/*============================================================================= 

initAdc() is used to configure A/D to convert channel 4 on Timer event.
It generates event to DMA on every sample/convert sequence.
=============================================================================*/ 

void initAdc(void)
{
     AD1CON1bits.FORM = 3;            // Data Output Format: Signed 
Fraction (Q15 format)
     AD1CON1bits.SSRC = 2;            // Sample Clock Source: GP Timer 
starts conversion
     AD1CON1bits.ASAM = 1;            // ADC Sample Control: Sampling 
begins immediately after conversion
     AD1CON1bits.AD12B = 1;            // 12-bit ADC operation

     AD1CON2bits.CHPS = 0;            // Converts CH0

     AD1CON3bits.ADRC = 0;            // ADC Clock is derived from 
Systems Clock
     AD1CON3bits.ADCS = 3;            // ADC Conversion Clock 
Tad=Tcy*(ADCS+1)= (1/40M)*4 = 100ns
                                     // ADC Conversion Time for 12-bit 
Tc=14*Tad = 1.4us

     AD1CON1bits.ADDMABM = 1;         // DMA buffers are built in 
conversion order mode
     AD1CON2bits.SMPI = 0;            // SMPI must be 0


     //AD1CHS0: A/D Input Select Register
     AD1CHS0bits.CH0SA = 4;            // MUXA +ve input selection (AN4) 
for CH0
     AD1CHS0bits.CH0NA = 0;            // MUXA -ve input selection 
(Vref-) for CH0

     //AD1PCFGH/AD1PCFGL: Port Configuration Register
     AD1PCFGL=0xFFFF;
     AD1PCFGLbits.PCFG4 = 0;            // AN4 as Analog Input


     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
}

/*============================================================================= 

initDac() is used to configure D/A.
=============================================================================*/ 

void initDac(void)
{
     /* Initiate DAC Clock */
     ACLKCONbits.SELACLK = 0;        // FRC w/ Pll as Clock Source
     ACLKCONbits.AOSCMD = 0;            // Auxiliary Oscillator Disabled
     ACLKCONbits.ASRCSEL = 0;        // Auxiliary Oscillator is the 
Clock Source
     ACLKCONbits.APSTSCLR = 7;        // FRC divide by 1

     DAC1STATbits.ROEN = 1;            // Right Channel DAC Output Enabled

     DAC1DFLT = 0x8000;                // DAC Default value is the midpoint

                           // 103.16KHz      // 8.038KHz        // 
44.211KHz    // 25KHz
     DAC1CONbits.DACFDIV = 5;                   //76; //13;             
// 23; //        // Divide High Speed Clock by DACFDIV+1

     DAC1CONbits.FORM = 1;            // Data Format is signed integer
     DAC1CONbits.AMPON = 0;            // Analog Output Amplifier is 
enabled during Sleep Mode/Stop-in Idle mode

     DAC1CONbits.DACEN = 1;            // DAC1 Module Enabled
}

/*======================================================================================= 

Timer 3 is setup to time-out every Ts secs. As a result, the module
will stop sampling and trigger a conversion on every Timer3 time-out Ts.
At that time, the conversion process starts and completes Tc=12*Tad 
periods later.
When the conversion completes, the module starts sampling again. 
However, since Timer3
is already on and counting, about (Ts-Tc)us later, Timer3 will expire 
again and trigger
next conversion.
=======================================================================================*/ 

void initTmr3()
{
     TMR3 = 0x0000;                    // Clear TMR3
     PR3 = SAMPPRD;                    // Load period value in PR3
     IFS0bits.T3IF = 0;                // Clear Timer 3 Interrupt Flag
     IEC0bits.T3IE = 0;                // Clear Timer 3 interrupt enable 
bit

     T3CONbits.TON = 1;                // Enable Timer 3
}

/*============================================================================= 

DMA0 configuration
  Direction: Read from peripheral address 0-x300 (ADC1BUF0) and write to 
DMA RAM
  AMODE: Register indirect with post increment
  MODE: Continuous, Ping-Pong Mode
  IRQ: ADC Interrupt
  ADC stores results stored alternatively between BufferA[] and BufferB[]
=============================================================================*/ 

void initDma0(void)
{
     DMA0CONbits.AMODE = 0;            // Configure DMA for Register 
indirect with post increment
     DMA0CONbits.MODE = 2;            // Configure DMA for Continuous 
Ping-Pong mode

     DMA0PAD = (int)&ADC1BUF0;        // Peripheral Address Register: 
ADC buffer
     DMA0CNT = (NUMSAMP-1);            // DMA Transfer Count is (NUMSAMP-1)

     DMA0REQ = 13;                    // ADC interrupt selected for DMA 
channel IRQ

     DMA0STA = __builtin_dmaoffset(BufferA);    // DMA RAM Start Address A
     DMA0STB = __builtin_dmaoffset(BufferB); // DMA RAM Start Address B

     IFS0bits.DMA0IF = 0;            // Clear the DMA interrupt flag bit
     IEC0bits.DMA0IE = 1;            // Set the DMA interrupt enable bit

     DMA0CONbits.CHEN = 1;            // Enable DMA channel
}

/*============================================================================= 

_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;                    // Ping-pong buffer select flag
     flag = 1;                        // Ping-pong buffer full flag
      IFS0bits.DMA0IF = 0;            // Clear the DMA0 Interrupt Flag
}

/*============================================================================= 

_DAC1RInterrupt(): ISR name is chosen from the device linker script.
=============================================================================*/ 

void __attribute__((interrupt, no_auto_psv)) _DAC1RInterrupt(void)
{
     IFS4bits.DAC1RIF = 0;             // Clear Right Channel Interrupt 
Flag
}

###################################  END



More information about the Elektro mailing list