Er is nog wel iets raars aan de hand:
Ik moet de reset van de PIC laag houden, pas dan blijft de AD9833 output leveren.
Gisteren werkte het toevallig, omdat ik geen pull-up aan de Reset had hangen...
Wat zit er hier dan fout?
'====================================================================================================
Program Signal
'====================================================================================================
Dim DDS_Value As LongInt 'Divider value for the AD9833Dim DDS_SYNC As sBit At PortB.0
DDS_CLK As sBit At LATB.1 'Change if needed
DDS_DATA As sBit At LATB.2 '
DDS_SYNC As sBit At LATB.3 '
DDS As Word 'DDS ctrl register. Bits used
DDS_Array As Byte[2] At DDS
Const DDS_Mode = 1 'in the AD9833 control register
DDS_Div2 = 3 '
DDS_OpBiten = 5 '
DDS_Sleep12 = 6 '
DDS_Sleep1 = 7 '
DDS_Reset = 8 '
DDS_PSelect = 10 '
DDS_FSelect = 11 '
DDS_HLB = 12 '
DDS_B28 = 13 '
DDS_Freq0 = 14 '
DDS_Freq1 = 15
'==================================================================================================
Sub Procedure ChangeBit(Dim pBitnr As Byte, Dim pValue As Byte)
'==================================================================================================
DDS_Array[pBitnr And 0x1000].(pBitnr And 0x0111) = pValue 'And 0x0111 = pValue
End Sub
'==================================================================================================
Sub Procedure SoftSpi_Write(Dim pVal As Word)
'==================================================================================================
Dim lCnt As Byte
DDS_SYNC = 1
DDS_CLK = 1
DDS_SYNC = 0
For lCnt = 0 to 15
DDS_DATA = (pVal >> lCnt) And 0x0001
DDS_CLK = 0
DDS_CLK = 1
Next lCnt
DDS_CLK = 0
DDS_SYNC = 1
End Sub
'==================================================================================================
Sub Procedure DDS_Init() 'Init the DDS chip
'==================================================================================================
DDS_SYNC = 0 'Select DDS chip (spi #1)
DDS = 0 'All Flags are '0'
ChangeBit(DDS_Reset, 1) '(except the reset flag)
SoftSpi_Write(DDS) '
ChangeBit(DDS_Reset, 0) '
SoftSpi_Write(DDS) '
DDS_SYNC = 1 'Disable chip
End Sub '
'==================================================================================================
Sub Procedure DDS_Set() 'Set value from DDS_Value into the DSS chip
'==================================================================================================
DDS_SYNC = 0 'Select DDS chip (spi #1)
SoftSpi_Write(0x2000) 'Set 2x14bits cmd mode
SoftSpi_Write((DDS_Value And 0x00003FFF) Or 0x4000) 'Low 14 bit word first
SoftSpi_Write((DDS_Value >> 14) Or 0x4000) 'Hi 14 bits
DDS_SYNC = 1 '
End Sub '
Main:
ANSELA = %00000000 'All Port A Digital
ANSELB = %00000000 'All Port B Digital
TRISA = %00100000 'Port A.5 input
TRISB = %00000000 'All Port B Output
OSCCON = %01111000 '16 MHz internal
DDS_INIT()
DDS_SET()
End.Aanvulling:
Ik moet dan:
While True
DDS_SET()
Wend
doen.
En dan de resetknop vast blijven houden (A.5 naar GND).
Pas dan blijft hij lopen. Krijg je wel lamme vingers van.. 
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Kennelijk doet je programma iets met de DDS wat hem inspereert om "niets" te doen.
Zodra je de reset indrukt zal je CPU "helemaal niets" kunnen doen en gaat de AD9833 ineens iets doen. Ehh. Tja, kennelijk doe je iets verkeerd wat de AD9833 dus blokkert om een uitvoer te geven.
Dat kan zijn dat ie denkt dat je nog aan het configureren bent.
Als test kan je alle outputs naar de AD9833 even als inpout zetten (doet de reset ook!) en kijk of het dan wel werkt.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Beide geprobeerd, maar geen resultaat.
Wat wel raar is, dat heel af en toe de puls output komt.
maar dan wel staat te klapperen met ca 0,5 Hz.
Daarom heb ik een nieuwe breadboard gepakt en opnieuw opgezet met nieuwe draadbrugjes.
En de soldeerverbinding van de header op het kleine AD9833 printje opnieuw even gedaan.
Maar het helpt niet.
Er moet iets zijn.
Het is toch niet de bedoeling dat DDS_SET in een While - wend loop zit?
M.a.w. één keer instellen dan moet het ding toch blijven draaien?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Je stelt de frequentie maar een maal in (en wanneer die verandert uiteraard)
Werkt in 5 apparaten hier al 8 jaar (met 24f) zonder problemen...
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Er zit helemaal geen MCLK op..
Deze AD9833 is een printje dat ook in Arduino sketches wordt gebruikt, zonder verdere hardware. Dat werkt daar ook.
Het genereert een blok, sinus of driehoek signaal.
Ik ging er ook van uit dat het ding een oscillator aan boord heeft.
Op het zilveren componentje staat L 25.0. Is dat geen oscillator (of kristal) van 25 Mhz?
[Bericht gewijzigd door Bavelt op (12%)]
Ik heb het printje nog even getest met de Arduino, die werkt goed (geen losse contacten op het printje):
#include <AD9833.h> // Include the library
#define FNC_PIN 10 // Can be any digital IO pin
#define Frequency 1000 // Frequency = 1Hz
//--------------- Create an AD9833 object ----------------
// Note, SCK and MOSI must be connected to CLK and DAT pins on the AD9833 for SPI
AD9833 gen(FNC_PIN); // Defaults to 25MHz internal reference frequency
void setup() {
Serial.begin(9600);
// This MUST be the first command after declaring the AD9833 object
gen.Begin();
// Apply a 1000 Hz sine wave using REG0 (register set 0). There are two register sets: REG0 and REG1.
// Each one can be programmed for:
// Signal type - SINE_WAVE, TRIANGLE_WAVE, SQUARE_WAVE, and HALF_SQUARE_WAVE
// Frequency - 0 to 12.5 MHz
// Phase - 0 to 360 degress (this is only useful if it is 'relative' to some other signal
// such as the phase difference between REG0 and REG1).
// In ApplySignal, if Phase is not given, it defaults to 0.
gen.ApplySignal(SINE_WAVE, REG0, Frequency);
gen.EnableOutput(true); // Turn ON the output - it defaults to OFF
// There should be a 1 Hz square wave on the output of the AD9833
}
void loop() {
}Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Op het zilveren componentje staat L 25.0. Is dat geen oscillator (of kristal) van 25 Mhz?
Dat zal de oscillator zijn die aan MCLK vast zit, daar wordt de uitgangsfrequentie mee gemaakt/ van afgeleid.
Vermoedde ik al.
Maar ondertussen heb ik de PIC i.c.m. het ding nog niet aan de praat.
De hardware is goed, er moet iets zijn in het MB programma dat maakt dat de AD9833 zwijgt.
Wellicht toch nog een enable/disable output flag?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Die .h file staat niks zinvols in, alleen declaraties...
Zou het wel willen uittesten, maar heb hier alleen losse (msop10 is wat lastig...
)
Dit kun je nog proberen:
'==================================================================================================
Sub Procedure SoftSpi_Write(Dim pVal As Word)
'==================================================================================================
Dim lCnt As Byte
DDS_CLK = 1
DDS_SYNC = 0
For lCnt = 0 to 15
DDS_DATA = (pVal >> lCnt) And 0x0001
DDS_CLK = 0
DDS_CLK = 1
Next lCnt
End Sub
[Bericht gewijzigd door Arco op (84%)]
Dat helpt ook niet.
Het enige wat nu werkt is als je in de main:
While True
DDS_SET()
Wend
En dan de resetknop vast blijven houden (MCLR op A.5 enabled).
Dan komt er een keurige sinus uit van 15.625 Hz.
Edit: ik zie wel bij loslaten van Reset knop kleine piefjes op de output met 1 Mhz frequentie.
[Bericht gewijzigd door Bavelt op (16%)]
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Je zou met de scoop het SPI signaal kunnen bekijken (en eventueel vergelijken met de Arduino versie?
Een routine in de Arduino Sketch die de frequentie regelt:
* Set the specified frequency register with the frequency (in Hz)
*/
void AD9833 :: SetFrequency ( Registers freqReg, float frequency ) {
// TODO: calculate max frequency based on refFrequency.
// Use the calculations for sanity checks on numbers.
// Sanity check on frequency: Square - refFrequency / 2
// Sine/Triangle - refFrequency / 4
if ( frequency > 12.5e6 ) // TODO: Fix this based on refFreq
frequency = 12.5e6;
if ( frequency < 0.0 ) frequency = 0.0;
// Save frequency for use by IncrementFrequency function
if ( freqReg == REG0 ) frequency0 = frequency;
else frequency1 = frequency;
int32_t freqWord = (frequency * pow2_28) / (float)refFrequency;
int16_t upper14 = (int16_t)((freqWord & 0xFFFC000) >> 14),
lower14 = (int16_t)(freqWord & 0x3FFF);
// Which frequency register are we updating?
uint16_t reg = freqReg == REG0 ? FREQ0_WRITE_REG : FREQ1_WRITE_REG;
lower14 |= reg;
upper14 |= reg;
// I do not reset the registers during write. It seems to remove
// 'glitching' on the outputs.
WriteControlRegister();
// Control register has already been setup to accept two frequency
// writes, one for each 14 bit part of the 28 bit frequency word
WriteRegister(lower14); // Write lower 14 bits to AD9833
WriteRegister(upper14); // Write upper 14 bits to AD9833
}
Wat een abracadabra... 
Ze zeggen wel eens over dat C: "Write once, read never...."
Op vrijdag 20 december 2024 10:36:51 schreef Arco:
Je zou met de scoop het SPI signaal kunnen bekijken (en eventueel vergelijken met de Arduino versie?
Het SPI signaal komt natuurlijk maar even? (behalve nu ik het even in een loop heb gestopt)
De Soft SPI heeft ook geen SPI_Init nodig?
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Zou dit moeten zijn..
// --------------------- PRIVATE FUNCTIONS --------------------------
/*
* Write control register. Setup register based on defined states
*/
void AD9833 :: WriteControlRegister ( void ) {
uint16_t waveForm;
// TODO: can speed things up by keeping a writeReg0 and writeReg1
// that presets all bits during the various setup function calls
// rather than setting flags. Then we could just call WriteRegister
// directly.
if ( activeFreq == REG0 ) {
waveForm = waveForm0;
waveForm &= ~FREQ1_OUTPUT_REG;
}
else {
waveForm = waveForm1;
waveForm |= FREQ1_OUTPUT_REG;
}
if ( activePhase == REG0 )
waveForm &= ~PHASE1_OUTPUT_REG;
else
waveForm |= PHASE1_OUTPUT_REG;
if ( outputEnabled )
waveForm &= ~RESET_CMD;
else
waveForm |= RESET_CMD;
if ( DacDisabled )
waveForm |= DISABLE_DAC;
else
waveForm &= ~DISABLE_DAC;
if ( IntClkDisabled )
waveForm |= DISABLE_INT_CLK;
else
waveForm &= ~DISABLE_INT_CLK;
WriteRegister ( waveForm );
}
void AD9833 :: WriteRegister ( int16_t dat ) {
/*
* We set the mode here, because other hardware may be doing SPI also
*/
SPI.setDataMode(SPI_MODE2);
/* Improve overall switching speed
* Note, the times are for this function call, not the write.
* digitalWrite(FNCpin) ~ 17.6 usec
* digitalWriteFast2(FNC_PIN) ~ 8.8 usec
*/
WRITE_FNCPIN(LOW); // FNCpin low to write to AD9833
//delayMicroseconds(2); // Some delay may be needed
// TODO: Are we running at the highest clock rate?
SPI.transfer(highByte(dat)); // Transmit 16 bits 8 bits at a time
SPI.transfer(lowByte(dat));
WRITE_FNCPIN(HIGH); // Write done
}
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Op vrijdag 20 december 2024 10:42:54 schreef Bavelt:
Ze zeggen wel eens over dat C: "Write once, read never...."
Sorry hoor, maar dat is duidelijke code die prima te lezen is.
Wat in de arduino code fout gaat is dat je de output enabled nadat je de frequentie hebt ingesteld. Tijdens het frequentie instellen wordt "writecontrolregister" aangeroepen met "output uit" toestand.
Anders zou het zo kunnen zijn dat je nog een nieuwe setfrequency of zoiets moet aanroepen.
Main:
ANSELA = %00000000 'All Port A Digital
ANSELB = %00000000 'All Port B Digital
TRISA = %00100000 'Port A.5 input
TRISB = %00000000 'All Port B Output
OSCCON = %01111000 '16 MHz internal
DDS_INIT()
DDS_SET()
End.
Ik heb geen verstand van basic. Maar ik vraag me wel af wat er gebeurt als het programma klaar is? Begint alles dan niet opnieuw? Ik zou een endless loop verwachten aan het eind.
Arco
Special Member
Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com
Eigenlijk hoort er een while...wend loop in main om de boel draaiende te houden.
De compiler zet wel een eindeloze loop neer ipv end., maar netjes is het niet om daarop te vertrouwen...
Normaliter zit er ook altijd wel een While .. - Wend loop in mijn MB-programma's.
In dit geval was er niet echt een loop nodig.
Maar ik heb hem voor de netheid er toch maar even in gezet.
Niet dat dit helpt; er komt nog steeds niets uit de output van de AD9833...
Ik ben nog steeds aan het worstelen met mijn AD9833.
Ik vond een aardig filmpje op Youtube, waarin duidelijk wordt uitgelegd hoe de structuur van de registers van dit device in elkaar zit, met een voorbeeld wat je moet doen om een 400 Hz sinus te krijgen.
En ik heb even teruggegrepen op een werkend programmaatje dat met de hardware SPI werkt op mijn PIC 16F1847.
En dit aangepast om een word te kunnen versturen.
Dit is dan mijn programma:
'====================================================================================================
Program Signal
' SDO (D1): LATB.2 Pin 8
' SCK (D0): LATB.4 Pin 10
' C_S LATB.3 Pin 9
'====================================================================================================
Dim ClockPin As sbit at LATB.4 'pin 10 'Clock
Datapin As sbit at lATB.2 'pin 8 'SDO
C_S As sbit at LATB.3 'pin 9 'Chip Select
'====================================================================================================
Sub Procedure Write_Reg(dim pDat as Word)
'====================================================================================================
C_S = 1
Spi_Write(pDat)
Spi_Write (pDat >>8)
C_S = 0
Delay_ms(20)
End Sub
Main:
ANSELA = %00000000 'All Port A Digital
ANSELB = %00000000 'All Port B Digital
TRISA = %00100000 'Port A.5 input (MCLR)
TRISB = %00000000 'All Poert B Output
OSCCON = %01110000 '8Mhz internal
C_S = 1
delay_ms(100)
C_S = 0
SPI1_Init()
Delay_ms(100)
C_S = 1
Write_Reg(0x0000)
Write_Reg(0x0100)
Write_Reg(0x2100)
Write_Reg(0x50C7)
Write_Reg(0x4000)
Write_Reg(0xC000)
Write_Reg(0x2002)
C_S = 1
While True 'Dummy loop
Wend
End.
Maar waarom, o waarom werkt dit nu niet?
Er moet iets fout gaan bij het schrijven naar de registers.
De link naar het artikeltje: