[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