Chciałbym prosić osoby działające na forum o sprawdzenie kodu i toku myślenia (komunikacja SPI z DDS AD9833). uC nie generuje sygnału SCK - w ogóle nic
Kod: Zaznacz cały
//Stałe
#define F_CPU 16000000UL
#define SPI_DDR DDRB
#define SPI_MOSI_BIT PB3
#define SPI_SCK_BIT PB5
#define SPI_CS_BIT PB1
#define SPI_SPR (1<<SPR1)
#define AD_FSELECT 11
#define AD_FREQ0 (1<<14)
#define AD_FREQ1 (1<<15)
#define AD_B28 13
#define AD_FSYNC_DDR DDRB
#define AD_FSYNC_BIT PB1
#define AD_SLEEP1 7
#define AD_SLEEP12 6
#define AD_RESET 8
#define AD_F_MCLK 25000000
#define AD_2POW28 268435456
#define AD_FREQ_CALC(freq) (uint32_t)(((double)AD_2POW28/(double)AD_F_MCLK*freq)*4)
/***************/
#include <avr/io.h>
#include <util/delay.h>
typedef struct {
float freq[2];
float phase[2];
float mod_freq;
uint8_t freq_out;
uint8_t phase_out;
uint8_t mode; //sinus
uint16_t command_reg;
} ad9833_opcje_t;
ad9833_opcje_t ad9833_opcje;
void AD_FSYNC_LO();
void AD_FSYNC_HI();
void spi_init();
void spi_send_byte(uint8_t data);
//funkcja odpowiedzialna za wysylanie weartosci 16-bitowej
static inline void ad9833_send(uint16_t packet){
spi_send_byte((uint8_t)(packet>>8));
spi_send_byte((uint8_t)packet);
}
/***********************************/
//pozostale
/*************************************************/
void ad9833_set_freq_out(uint8_t freq_out){
ad9833_opcje.freq_out = freq_out;
switch (freq_out){
case 0:
ad9833_opcje.command_reg &= ~(1<<AD_FSELECT); //Ad_fselect = 11 zeruje ten bit w rejestrze
break;
case 1:
ad9833_opcje.command_reg |= (1<<AD_FSELECT); //Wstawia 1 do bitu
break;
case 2:
//TODO
break;
}
AD_FSYNC_LO();
ad9833_send(ad9833_opcje.command_reg);
AD_FSYNC_HI();
}
void ad9833_set_frequency(double freq){
uint32_t freq_reg;
freq_reg = AD_FREQ_CALC(freq);
ad9833_opcje.freq[AD_FREQ0] = freq; //Zapisuje czestotliwosc do struktury
AD_FSYNC_LO();
ad9833_send((1<<AD_B28) | ad9833_opcje.command_reg); //jezeli command_reg jest 1 to wybierany jest FREQ1
ad9833_send(AD_FREQ0 | (0x3FFF&(uint16_t)(freq_reg>>2 )));
ad9833_send(AD_FREQ0 | (0x3FFF&(uint16_t)(freq_reg>>16)));
AD_FSYNC_HI();
}
//funkcja glowna
void ad9833_init(void){
//init FSYNC pin (aka Chip select)
ad9833_opcje.command_reg |= (1<<AD_B28);
AD_FSYNC_DDR |= (1<<AD_FSYNC_BIT);
AD_FSYNC_HI();
//some datasheet-proscribed delay here
_delay_us(10);
//start as half-asleep
AD_FSYNC_LO();
ad9833_send((1<<AD_SLEEP12)|(1<<AD_RESET)); //bit 6 = 1 to DAC bez mocy; Reset = 1 zeruje wewnetrzne rejestry.
ad9833_opcje.command_reg |= (1<<AD_SLEEP12); //przepisuje wartosc do struktury
AD_FSYNC_HI();
//set some nice default values
ad9833_set_frequency(0);
ad9833_set_freq_out(0);
}
/*************************************/
int main(void)
{
spi_init();
ad9833_init();
ad9833_set_freq_out(0);
ad9833_set_frequency(5000);
while(1)
{
}
}
/****/
void spi_init(){
SPI_DDR |= (1<<SPI_MOSI_BIT)|(1<<SPI_SCK_BIT)|(1<<SPI_CS_BIT);
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}
void spi_send_byte(uint8_t data){
SPDR = data;
while(!(SPSR & (1<<SPIF)));
}
void AD_FSYNC_LO()
{
PORTB &=~(1<<PB1);
_delay_us(5); //dobre wyrażenie
}
void AD_FSYNC_HI()
{
_delay_us(5);
PORTB |=(1<<PB1);
}