Re: Генератор AD9833+частотомер 6.5 МГц.
Это как-то можно решить?
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
forum.rcl-radio.ru → Разное → Генератор AD9833+частотомер 6.5 МГц.
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Это как-то можно решить?
Опубликуйте скетч который используете
// ATMEGA328 16 MHz
// PD5 frequency input
//AD9833
#define CS PC0
#define MCLK PC1
#define DATA PC2
// ENCODER
#define DT PB0
#define CLK PB1
#define SW PB2
// BUTTON
#define G_ON_OFF PB3
#define FORM PB4
#include <avr/io.h>
#include <util/delay.h>
#include <Wire_low.h> // http://forum.rcl-radio.ru/viewtopic.php?pid=5521#p5521
#include <Lcd1602_i2c_low.h> // http://rcl-radio.ru/wp-content/uploads/2022/03/Lcd1602_i2c_low.zip
Lcd1602_i2c_low lcd(0x27);// адрес I2C
volatile uint8_t _prevValueAB = 0;
volatile uint8_t _currValueAB = 0;
volatile int16_t newPosition = 0;
int position = -999;
int form;
int timer2,times;
volatile byte x;
unsigned long f;
bool w=1,on;
long fg;
long b,h_bit,l_bit;
float k = 0.995265; // устраним погрешность кварца
const long f25 = 25000000;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц
int a[7],i;
int main(){
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0)|(1 << PCINT1);
PORTB |= (1 << PB3)|(1 << PB4);
PORTD |= (1<<PD5); // подтягивающий резистор на PD5 (вход T1)
DDRC |=(1<<CS)|(1<<MCLK)|(1<<DATA);
PORTC |=(1<MCLK)|(1<<CS)|(1<<DATA);
_delay_ms(500);
ad_AD9833();
cli();
// TIMER 1
TCCR1A = 0;
TCCR1B = 0;
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10); //Внешний тактовый источник на выводе T1. Тактирование по фронту
TIMSK1 |= (1 << TOIE1); // бит TOIE1 в регистре TIMSK1 взывает прерывание когда таймер переполняется
// TIMER 2
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 155; // 100 Hz
TCCR2A |= (1 << WGM21);
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
TIMSK2 |= (1 << OCIE2A);
sei();
wire_set(16000000,100000); // тактовая частота контроллера, частота шины I2C
lcd.setInit();
lcd.Clear(); // очистка экрана
lcd.led(1); // включение и отключение подсветки экрана
a[0] = EEPROM_read(0);a[1] = EEPROM_read(1);a[2] = EEPROM_read(2);a[3] = EEPROM_read(3);a[4] = EEPROM_read(4);a[5] = EEPROM_read(5);a[6] = EEPROM_read(6);
form = EEPROM_read(7);
while(1){
if(((PINB >> SW) & 1)==0){i++;if(on==1){w=1;}on=0;if(i>6){i=0;};_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==0){on=1;w=1;i=100;_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==1){on=0;w=1;fg=0;i=0;_delay_ms(300);}
if(((PINB >> FORM) & 1)==0){form++;if(form>2){form=0;}w=1;fg=0;i=0;_delay_ms(300);}
///////////////////////////////////////////////////
if(newPosition != position){position = newPosition;
a[i] = a[i]+newPosition;newPosition=0;
}
///////////////////////////////////////////////////
if(on==0){fg=0;lcd.Curs(1,11);lcd.PrintString(" ");}
if(on==1){lcd.Curs(1,11);lcd.PrintString("*");}
if(w==1){w=0;
lcd.Curs(1,13);
switch(form){
case 0: lcd.PrintString("DAC");WriteAD9833(0x2028);break;
case 1: lcd.PrintString("SIN");WriteAD9833(0x2000);break;
case 2: lcd.PrintString("TRI");WriteAD9833(0x2002);break;
}
EEPROM_write(0,a[0]);EEPROM_write(1,a[1]);EEPROM_write(2,a[2]);EEPROM_write(3,a[3]);EEPROM_write(4,a[4]);EEPROM_write(5,a[5]);EEPROM_write(6,a[6]);
EEPROM_write(7,form);
ad_AD9833();}
///////////////////////////////////////////////////
lcd.Curs(0,0);lcd.PrintString("F ");
lcd.PrintInt(f/1000000);lcd.PrintString(".");
lcd.PrintInt(f/100000%10);
lcd.PrintInt(f/10000%10);
lcd.PrintInt(f/1000%10);lcd.PrintString(".");
lcd.PrintInt(f/100%10);
lcd.PrintInt(f/10%10);
lcd.PrintInt(f%10);
lcd.PrintString(" Hz ");
///////////////////////////////////////////////////
if(a[i]<0){a[i]=0;}if(a[i]>9){a[i]=9;}
lcd.Curs(1,0);lcd.PrintString("G ");
lcd.Curs(1,2);if(i==0){if(timer2-times<50){lcd.PrintInt(a[0]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[0]);}
lcd.Curs(1,3);lcd.PrintString(".");
lcd.Curs(1,4);if(i==1){if(timer2-times<50){lcd.PrintInt(a[1]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[1]);}
lcd.Curs(1,5);if(i==2){if(timer2-times<50){lcd.PrintInt(a[2]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[2]);}
lcd.Curs(1,6);if(i==3){if(timer2-times<50){lcd.PrintInt(a[3]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[3]);}
lcd.Curs(1,7);lcd.PrintString(".");
lcd.Curs(1,8);if(i==4){if(timer2-times<50){lcd.PrintInt(a[4]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[4]);}
lcd.Curs(1,9);if(i==5){if(timer2-times<50){lcd.PrintInt(a[5]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[5]);}
lcd.Curs(1,10);if(i==6){if(timer2-times<50){lcd.PrintInt(a[6]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[6]);}
fg=a[0]*pow(10,6)+a[1]*pow(10,5)+a[2]*pow(10,4)+a[3]*pow(10,3)+a[4]*pow(10,2)+a[5]*pow(10,1)+a[6];
}}// end main/while
ISR (TIMER1_OVF_vect){x++;}// при переполнении увеличить переменную х на 1
ISR (TIMER2_COMPA_vect){
timer2++;
if(timer2==1){
x = 0;TCNT1 = 0;
TCCR1B |= (1 << CS12)|(1 << CS11)|(1 << CS10);}
if(timer2==101){
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10);
f = ((x*65535) + TCNT1);timer2=0;}
}
void WriteAD9833(int data){ // SPI
PORTC |=(1<<MCLK);PORTC &=~(1<<CS);
for(int i = 15; i >= 0; i--){
PORTC |=(1<<MCLK);
if(((data>>i)&0x01)==1){PORTC |=(1<<DATA);}else{PORTC &=~(1<<DATA);}
PORTC &=~(1<<MCLK);_delay_ms(1);}
PORTC |=(1<<CS);
}
void ad_AD9833(){
b = (fg*pow(2,28)/f25)*k;
if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;}
else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;}
WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28
WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB
WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB
WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0
WriteAD9833(0x2028);// 0010 0000 0000 0000 - Exit Reset
}
ISR(PCINT0_vect){
bool pinA = ((PINB >> DT) & 1);
bool pinB = ((PINB >> CLK) & 1);
_currValueAB = (pinA << 1) | pinB;
switch(_prevValueAB | _currValueAB){
case 0b0001: newPosition++;break;
case 0b0100: newPosition--;break;
}
_prevValueAB = _currValueAB << 2;
}
unsigned char EEPROM_read(unsigned int uiAddress){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EECR |= (1<<EERE);// чтение EEPROM
return EEDR; // вывод значения
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EEDR = ucData; // регистр данных
EECR |= (1<<EEMPE);// Разрешение записи в EEPROM
EECR |= (1<<EEPE); // Запись в EEPROM
}
Попробуйте этот скетч, если не заработает буду собирать схему для тестирования
// ATMEGA328 16 MHz
// PD5 frequency input
//AD9833
#define CS PC0
#define MCLK PC1
#define DATA PC2
// ENCODER
#define DT PB0
#define CLK PB1
#define SW PB2
// BUTTON
#define G_ON_OFF PB3
#define FORM PB4
#include <avr/io.h>
#include <util/delay.h>
#include <Wire_low.h> // http://forum.rcl-radio.ru/viewtopic.php?pid=5521#p5521
#include <Lcd1602_i2c_low.h> // http://rcl-radio.ru/wp-content/uploads/2022/03/Lcd1602_i2c_low.zip
Lcd1602_i2c_low lcd(0x27);// адрес I2C
volatile uint8_t _prevValueAB = 0;
volatile uint8_t _currValueAB = 0;
volatile int16_t newPosition = 0;
int position = -999;
int form;
int timer2,times;
volatile byte x;
unsigned long f;
bool w=1,on;
long fg;
long b,h_bit,l_bit;
float k = 0.995265; // устраним погрешность кварца
const long f25 = 25000000;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц
int a[7],i;
int main(){
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0)|(1 << PCINT1);
PORTB |= (1 << PB3)|(1 << PB4);
PORTD |= (1<<PD5); // подтягивающий резистор на PD5 (вход T1)
DDRC |=(1<<CS)|(1<<MCLK)|(1<<DATA);
PORTC |=(1<MCLK)|(1<<CS)|(1<<DATA);
_delay_ms(500);
ad_AD9833();
cli();
// TIMER 1
TCCR1A = 0;
TCCR1B = 0;
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10); //Внешний тактовый источник на выводе T1. Тактирование по фронту
TIMSK1 |= (1 << TOIE1); // бит TOIE1 в регистре TIMSK1 взывает прерывание когда таймер переполняется
// TIMER 2
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 155; // 100 Hz
TCCR2A |= (1 << WGM21);
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
TIMSK2 |= (1 << OCIE2A);
sei();
wire_set(16000000,100000); // тактовая частота контроллера, частота шины I2C
lcd.setInit();
lcd.Clear(); // очистка экрана
lcd.led(1); // включение и отключение подсветки экрана
a[0] = EEPROM_read(0);a[1] = EEPROM_read(1);a[2] = EEPROM_read(2);a[3] = EEPROM_read(3);a[4] = EEPROM_read(4);a[5] = EEPROM_read(5);a[6] = EEPROM_read(6);
form = EEPROM_read(7);
while(1){
if(((PINB >> SW) & 1)==0){i++;if(on==1){w=1;}on=0;if(i>6){i=0;};_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==0){on=1;w=1;i=100;_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==1){on=0;w=1;fg=0;i=0;_delay_ms(300);}
if(((PINB >> FORM) & 1)==0){form++;if(form>2){form=0;}w=1;fg=0;i=0;_delay_ms(300);}
///////////////////////////////////////////////////
if(newPosition != position){position = newPosition;
a[i] = a[i]+newPosition;newPosition=0;
}
///////////////////////////////////////////////////
if(on==0){fg=0;lcd.Curs(1,11);lcd.PrintString(" ");}
if(on==1){lcd.Curs(1,11);lcd.PrintString("*");}
if(w==1){w=0;
lcd.Curs(1,13);
switch(form){
case 0: lcd.PrintString("DAC");WriteAD9833(0x2028);break;
case 1: lcd.PrintString("SIN");WriteAD9833(0x2000);break;
case 2: lcd.PrintString("TRI");WriteAD9833(0x2002);break;
}
_delay_ms(200);
EEPROM_write(0,a[0]);EEPROM_write(1,a[1]);EEPROM_write(2,a[2]);EEPROM_write(3,a[3]);EEPROM_write(4,a[4]);EEPROM_write(5,a[5]);EEPROM_write(6,a[6]);
EEPROM_write(7,form);
ad_AD9833();}
///////////////////////////////////////////////////
lcd.Curs(0,0);lcd.PrintString("F ");
lcd.PrintInt(f/1000000);lcd.PrintString(".");
lcd.PrintInt(f/100000%10);
lcd.PrintInt(f/10000%10);
lcd.PrintInt(f/1000%10);lcd.PrintString(".");
lcd.PrintInt(f/100%10);
lcd.PrintInt(f/10%10);
lcd.PrintInt(f%10);
lcd.PrintString(" Hz ");
///////////////////////////////////////////////////
if(a[i]<0){a[i]=0;}if(a[i]>9){a[i]=9;}
lcd.Curs(1,0);lcd.PrintString("G ");
lcd.Curs(1,2);if(i==0){if(timer2-times<50){lcd.PrintInt(a[0]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[0]);}
lcd.Curs(1,3);lcd.PrintString(".");
lcd.Curs(1,4);if(i==1){if(timer2-times<50){lcd.PrintInt(a[1]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[1]);}
lcd.Curs(1,5);if(i==2){if(timer2-times<50){lcd.PrintInt(a[2]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[2]);}
lcd.Curs(1,6);if(i==3){if(timer2-times<50){lcd.PrintInt(a[3]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[3]);}
lcd.Curs(1,7);lcd.PrintString(".");
lcd.Curs(1,8);if(i==4){if(timer2-times<50){lcd.PrintInt(a[4]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[4]);}
lcd.Curs(1,9);if(i==5){if(timer2-times<50){lcd.PrintInt(a[5]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[5]);}
lcd.Curs(1,10);if(i==6){if(timer2-times<50){lcd.PrintInt(a[6]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[6]);}
fg=a[0]*pow(10,6)+a[1]*pow(10,5)+a[2]*pow(10,4)+a[3]*pow(10,3)+a[4]*pow(10,2)+a[5]*pow(10,1)+a[6];
}}// end main/while
ISR (TIMER1_OVF_vect){x++;}// при переполнении увеличить переменную х на 1
ISR (TIMER2_COMPA_vect){
timer2++;
if(timer2==1){
x = 0;TCNT1 = 0;
TCCR1B |= (1 << CS12)|(1 << CS11)|(1 << CS10);}
if(timer2==101){
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10);
f = ((x*65535) + TCNT1);timer2=0;}
}
void WriteAD9833(int data){ // SPI
PORTC |=(1<<MCLK);PORTC &=~(1<<CS);
for(int i = 15; i >= 0; i--){
PORTC |=(1<<MCLK);
if(((data>>i)&0x01)==1){PORTC |=(1<<DATA);}else{PORTC &=~(1<<DATA);}
PORTC &=~(1<<MCLK);_delay_ms(1);}
PORTC |=(1<<CS);
}
void ad_AD9833(){
b = (fg*pow(2,28)/f25)*k;
if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;}
else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;}
WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28
WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB
WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB
WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0
WriteAD9833(0x2028);// 0010 0000 0000 0000 - Exit Reset
}
ISR(PCINT0_vect){
bool pinA = ((PINB >> DT) & 1);
bool pinB = ((PINB >> CLK) & 1);
_currValueAB = (pinA << 1) | pinB;
switch(_prevValueAB | _currValueAB){
case 0b0001: newPosition++;break;
case 0b0100: newPosition--;break;
}
_prevValueAB = _currValueAB << 2;
}
unsigned char EEPROM_read(unsigned int uiAddress){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EECR |= (1<<EERE);// чтение EEPROM
return EEDR; // вывод значения
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EEDR = ucData; // регистр данных
EECR |= (1<<EEMPE);// Разрешение записи в EEPROM
EECR |= (1<<EEPE); // Запись в EEPROM
}
Хорошо, завтра попробую!
К сожалению ничего не поменялось, все 3 формы показывают прямоугольный сигнал.
// ATMEGA328 16 MHz
// PD5 frequency input
//AD9833
#define CS PC0
#define MCLK PC1
#define DATA PC2
// ENCODER
#define DT PB0
#define CLK PB1
#define SW PB2
// BUTTON
#define G_ON_OFF PB3
#define FORM PB4
#include <avr/io.h>
#include <util/delay.h>
#include <Wire_low.h> // http://forum.rcl-radio.ru/viewtopic.php?pid=5521#p5521
#include <Lcd1602_i2c_low.h> // http://rcl-radio.ru/wp-content/uploads/2022/03/Lcd1602_i2c_low.zip
Lcd1602_i2c_low lcd(0x27);// адрес I2C
volatile uint8_t _prevValueAB = 0;
volatile uint8_t _currValueAB = 0;
volatile int16_t newPosition = 0;
int position = -999;
int form;
int timer2,times;
volatile byte x;
unsigned long f;
bool w=1,on;
long fg;
long b,h_bit,l_bit;
float k = 0.995265; // устраним погрешность кварца
const long f25 = 25000000;// частота кварца, если нет эталонного частотомера установите частоту 25000000 Гц
int a[7],i;
int main(){
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0)|(1 << PCINT1);
PORTB |= (1 << PB3)|(1 << PB4);
PORTD |= (1<<PD5); // подтягивающий резистор на PD5 (вход T1)
DDRC |=(1<<CS)|(1<<MCLK)|(1<<DATA);
PORTC |=(1<MCLK)|(1<<CS)|(1<<DATA);
_delay_ms(500);
ad_AD9833();
cli();
// TIMER 1
TCCR1A = 0;
TCCR1B = 0;
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10); //Внешний тактовый источник на выводе T1. Тактирование по фронту
TIMSK1 |= (1 << TOIE1); // бит TOIE1 в регистре TIMSK1 взывает прерывание когда таймер переполняется
// TIMER 2
TCCR2A = 0;
TCCR2B = 0;
OCR2A = 155; // 100 Hz
TCCR2A |= (1 << WGM21);
TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20);
TIMSK2 |= (1 << OCIE2A);
sei();
wire_set(16000000,100000); // тактовая частота контроллера, частота шины I2C
lcd.setInit();
lcd.Clear(); // очистка экрана
lcd.led(1); // включение и отключение подсветки экрана
a[0] = EEPROM_read(0);a[1] = EEPROM_read(1);a[2] = EEPROM_read(2);a[3] = EEPROM_read(3);a[4] = EEPROM_read(4);a[5] = EEPROM_read(5);a[6] = EEPROM_read(6);
form = EEPROM_read(7);
while(1){
if(((PINB >> SW) & 1)==0){i++;if(on==1){w=1;}on=0;if(i>6){i=0;};_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==0){on=1;w=1;i=100;_delay_ms(300);}
if(((PINB >> G_ON_OFF) & 1)==0 && on==1){on=0;w=1;fg=0;i=0;_delay_ms(300);}
if(((PINB >> FORM) & 1)==0){form++;if(form>2){form=0;}w=1;fg=0;i=0;_delay_ms(300);}
///////////////////////////////////////////////////
if(newPosition != position){position = newPosition;
a[i] = a[i]+newPosition;newPosition=0;
}
///////////////////////////////////////////////////
if(on==0){fg=0;lcd.Curs(1,11);lcd.PrintString(" ");}
if(on==1){lcd.Curs(1,11);lcd.PrintString("*");}
if(w==1){w=0;
EEPROM_write(0,a[0]);EEPROM_write(1,a[1]);EEPROM_write(2,a[2]);EEPROM_write(3,a[3]);EEPROM_write(4,a[4]);EEPROM_write(5,a[5]);EEPROM_write(6,a[6]);
EEPROM_write(7,form);
ad_AD9833();
lcd.Curs(1,13);
switch(form){
case 0: lcd.PrintString("DAC");WriteAD9833(0x2028);break;
case 1: lcd.PrintString("SIN");WriteAD9833(0x2000);break;
case 2: lcd.PrintString("TRI");WriteAD9833(0x2002);break;
}
}
///////////////////////////////////////////////////
lcd.Curs(0,0);lcd.PrintString("F ");
lcd.PrintInt(f/1000000);lcd.PrintString(".");
lcd.PrintInt(f/100000%10);
lcd.PrintInt(f/10000%10);
lcd.PrintInt(f/1000%10);lcd.PrintString(".");
lcd.PrintInt(f/100%10);
lcd.PrintInt(f/10%10);
lcd.PrintInt(f%10);
lcd.PrintString(" Hz ");
///////////////////////////////////////////////////
if(a[i]<0){a[i]=0;}if(a[i]>9){a[i]=9;}
lcd.Curs(1,0);lcd.PrintString("G ");
lcd.Curs(1,2);if(i==0){if(timer2-times<50){lcd.PrintInt(a[0]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[0]);}
lcd.Curs(1,3);lcd.PrintString(".");
lcd.Curs(1,4);if(i==1){if(timer2-times<50){lcd.PrintInt(a[1]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[1]);}
lcd.Curs(1,5);if(i==2){if(timer2-times<50){lcd.PrintInt(a[2]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[2]);}
lcd.Curs(1,6);if(i==3){if(timer2-times<50){lcd.PrintInt(a[3]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[3]);}
lcd.Curs(1,7);lcd.PrintString(".");
lcd.Curs(1,8);if(i==4){if(timer2-times<50){lcd.PrintInt(a[4]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[4]);}
lcd.Curs(1,9);if(i==5){if(timer2-times<50){lcd.PrintInt(a[5]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[5]);}
lcd.Curs(1,10);if(i==6){if(timer2-times<50){lcd.PrintInt(a[6]);}if(timer2-times>=50){lcd.PrintString(" ");}if(timer2-times>100){times=timer2;}}else{lcd.PrintInt(a[6]);}
fg=a[0]*pow(10,6)+a[1]*pow(10,5)+a[2]*pow(10,4)+a[3]*pow(10,3)+a[4]*pow(10,2)+a[5]*pow(10,1)+a[6];
}}// end main/while
ISR (TIMER1_OVF_vect){x++;}// при переполнении увеличить переменную х на 1
ISR (TIMER2_COMPA_vect){
timer2++;
if(timer2==1){
x = 0;TCNT1 = 0;
TCCR1B |= (1 << CS12)|(1 << CS11)|(1 << CS10);}
if(timer2==101){
TCCR1B &= ~(1 << CS12)|(1 << CS11)|(1 << CS10);
f = ((x*65535) + TCNT1);timer2=0;}
}
void WriteAD9833(int data){ // SPI
PORTC |=(1<<MCLK);PORTC &=~(1<<CS);
for(int i = 15; i >= 0; i--){
PORTC |=(1<<MCLK);
if(((data>>i)&0x01)==1){PORTC |=(1<<DATA);}else{PORTC &=~(1<<DATA);}
PORTC &=~(1<<MCLK);_delay_ms(1);}
PORTC |=(1<<CS);
}
void ad_AD9833(){
b = (fg*pow(2,28)/f25)*k;
if(b<16383){l_bit = b + 0x4000 ;h_bit = 0x4000;}
else{h_bit = (b>>14) + 0x4000;l_bit = b - (h_bit<<14) + 0x4000;}
WriteAD9833(0x2100);// 0010 0001 0000 0000 - Reset + DB28
WriteAD9833(l_bit); // 0100 0000 0000 0000 - Freq0 LSB
WriteAD9833(h_bit); // 0100 0000 0000 0000 - Freq0 MSB
WriteAD9833(0xC000);// 1100 0000 0000 0000 - Phase0
WriteAD9833(0x2028);// 0010 0000 0000 0000 - Exit Reset
}
ISR(PCINT0_vect){
bool pinA = ((PINB >> DT) & 1);
bool pinB = ((PINB >> CLK) & 1);
_currValueAB = (pinA << 1) | pinB;
switch(_prevValueAB | _currValueAB){
case 0b0001: newPosition++;break;
case 0b0100: newPosition--;break;
}
_prevValueAB = _currValueAB << 2;
}
unsigned char EEPROM_read(unsigned int uiAddress){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EECR |= (1<<EERE);// чтение EEPROM
return EEDR; // вывод значения
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData){
while(EECR & (1<<EEPE)); // проверка готовности EEPROM
EEARH = ((uiAddress & 0xF0) << 2); // регистр адреса H
EEARL = uiAddress & 0x0F; // регистр адреса L
EEDR = ucData; // регистр данных
EECR |= (1<<EEMPE);// Разрешение записи в EEPROM
EECR |= (1<<EEPE); // Запись в EEPROM
}
Этот вариант заработал, но при режиме синус на выходе всего лишь 200 мВ. Соответственно этого напряжения не хватает для чувствительности частотомера. При режиме меандр на выходе 2,5 В и частотомер показывает правильные значения. Генератор вырабатывает частоту вплоть до 8 мГц , но уже напряжение на выходе всего 20 мВ в режиме синус. Настройку частоты кварца я использовал 24900000 Гц. Показывает все чётко.
Спасибо за Ваш труд !!!
Последний вариант заработал, тоже не переключался в синус и треугольник.
Спасибо.
Коллеги привет!
Поделитесь схемкой усилителя для этого генератора.
Питание будет +/- 5В.
Чтобы отправить ответ, вы должны войти или зарегистрироваться
forum.rcl-radio.ru → Разное → Генератор AD9833+частотомер 6.5 МГц.
Форум работает на PunBB, при поддержке Informer Technologies, Inc
|