/*
Firmware pour piloter:
- une carte générateur de signaux ADF4351
- une carte géné AD9850
- une carte Uno Mega2560
- afficheur 480x320 non tactile.
par Silicium628.
CE fichier source "Gene_Wobul_double_ADF4351.cpp" est libre, vous pouvez le redistribuer et/ou le modifier selon
les termes de la Licence Publique Générale GNU.
En ce qui concerne certaines bibliothèques "incluses" (par la directive "#include"), issues du domaine "Arduino", il faut voir au cas par cas.
En particulier la library "UTFT" n'est pas libre, il y a un copyright dans l'entête, que je cite:
"UTFT.h - Arduino/chipKit library support for Color TFT LCD Boards Copyright (C)2010-2014 Henning Karlsen. All right reserved"
Fin de citation.
*/
//================================
#define version "v10.2"
//================================
#include "Gene_Wobul_ADF4351_v10_2.h"
#include <avr/io.h>
#include <stdint.h>
#include <stdlib.h>
#include <util/delay.h>
#include <math.h>
#include "UTFT.cpp"
#include "uart2560_628.c"
#include "ADF4351-628v5.h";
#include "AD9850-628v1.h"
#include <EEPROM.h>
#define portPIN_switch0 PINH
#define portPIN_switch1 PINH
#define portPIN_switch2 PINJ
#define portPIN_switch3 PINH
#define portPIN_switch4 PINH
#define portPIN_switch5 PINJ
#define portPIN_switch6 PINE
#define pin_rot0 0b00000100
#define pin_rot1 0b00001000
#define pin_switch0 0b00000001
#define pin_switch1 0b00000010
#define pin_switch2 0b00000001
#define pin_switch3 0b00001000
#define pin_switch4 0b00010000
#define pin_switch5 0b00000010
#define pin_switch6 0b00001000
#define Crt_AD9850 1
#define Crt_ADF4351 2
#define mode_GENE 1
#define mode_WOBU_dB 2
#define mode_WOBU_mV 3
#define md_saisie_frq 1
#define md_saisie_Hz_div 2
#define md_saisie_dB_div 3
extern uint8_t SmallFont[];
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
UTFT TFT480(HX8357C,38,39,40,41);
AD9850 CarteAD9850;
ADF4351 CarteADF4351;
AffiRect Affi_1a; // fréquence AD9850
AffiRect Affi_1b; // fréquence ADF4351
AffiRect Affi_1c; // afficheur unique pour la fréquence en mode wobulation
AffiRect Affi_2a; // lambda AD9850
AffiRect Affi_2b; // lambda ADF4351
AffiRect Affi_3a; // lambda/2 AD9850
AffiRect Affi_3b; // lambda/2 ADF4351
AffiRect Affi_4a; // lambda/4 AD9850
AffiRect Affi_4b; // lambda/4 ADF4351
AffiRect Affi_5;
AffiRect Affi_6;
AffiRect Affi_7;
AffiRect Affi_8;
AffiRect Affi_9;
AffiRect Affi_10;
AffiRect Affi_11;
AffiRect Affi_12;
AffiRect Affi_13;
AffiRect Affi_14;
AffiRect Affi_R0;
AffiRect Affi_R1;
AffiRect Affi_R2;
AffiRect Affi_R3;
AffiRect Affi_R4;
AffiRect Affi_R5;
AffiV AffiV_01;
AffiV AffiV_02;
LED LED_a; // "LOCK" pour l'ADF4351
LED LED_b1; // "ON" pour l'AD9850
LED LED_b2; // "ON" pour l'ADF4351
LED LED0;
LED LED1;
LED LED2;
LED LED3;
LED LED4;
uint8_t couleur[3];
uint8_t rouge[3]={255, 0, 0};
uint8_t orange[3]={245, 121, 0};
uint8_t jaune[3]={255, 255, 0};
uint8_t jaune_sombre[3]={220, 220, 0};
uint8_t jaune_tres_sombre[3]={100, 100, 0};
uint8_t vert[3]={0, 255, 0};
uint8_t cyan[3]={0, 255, 255};
uint8_t cyan_sombre[3]={0, 200, 200};
uint8_t bleu_pale[3]={160, 240, 255};
uint8_t bleu_clair[3]={0, 100, 255};
uint8_t bleu[3]={0, 0, 255};
uint8_t violet[3]={200, 0, 255};
uint8_t noir[3]={0, 0, 0};
uint8_t gris[3]={150, 150, 150};
uint8_t blanc[3]={255, 255, 255};
uint8_t couleur_gain[3];
uint8_t switches;
uint8_t memo_switches;
uint8_t SW_mode; // = 1..2..3 (par lecture d'un inverseur 3 positions) 1=[gene freq] ; 2=[Wobu dB] ; 3=[Wobu mV]
uint8_t SW_saisie; // = 1..2..3 (par lecture d'un inverseur 3 positions) 1=[Freq] ; 2=[MHz/div] ; 3=[dB & offset]
uint8_t SW_rapide; // = 0..1 (par lecture d'un inverseur 2 positions) 0=[balayage normal] ; 1=[balayage rapide]
uint8_t SW_polarite; // = 0..1 (par lecture d'un inverseur 2 positions) sens de variation de la tension du signal acquisition
uint8_t SW_carte; // = 1..2 (par lecture d'un inverseur 2 positions) 1=[AD9850] ; 2=[ADF4351]
parametres params1;
int addr_params1=0; // en EEprom
uint16_t x0, y0;
uint16_t x_7seg, y_7seg;
uint32_t memo_frequence1; // fréquence de sortie de l'AD9850;
uint32_t memo_frequence2; // fréquence de sortie de l'ADF4351; en multiples de 10 kHz
uint32_t frq_centrale;
uint32_t frq_min_AD98, frq_max_AD98;
uint32_t frq_min_ADF43, frq_max_ADF43;
uint32_t pas_frq_gene_AD98;
uint32_t pas_frq_gene_ADF43;
uint32_t pas_frq_wobu_AD98;
uint32_t pas_frq_wobu_ADF43;
float F_mark;
float lambda_a; // longueur d'onde en cm AD9850
float lambda_b; // longueur d'onde en cm ADF4351
float F_affi_min, F_affi_max;
uint8_t DIV;
uint16_t FRAC;
uint32_t MOD;
uint32_t INTA;
uint32_t kHz_div; // pas de wobulation
uint32_t facteurs_mult[13] = {1, 2 , 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000};
uint8_t dB_div;
uint32_t mV_div;
int polarite = 1;
uint8_t etat;
uint16_t compteur1;
uint8_t raffraichir;
uint8_t afficher_freq;
uint8_t envoyer_data;
uint8_t stop =0;
float position;
uint16_t valeur_lue; // par le convertisseur ADC
uint8_t depassement;
uint32_t EE_adrs_freq0;
uint16_t tableau_acq[470];
/**
RAPPEL variables avr-gcc
TYPE nb octets
char 1 -128 .. 127 (ou caractères)
unsigned char 1 0 .. 255
uint8_t 1 (c'est la même chose que l'affreux 'unsigned char')
char toto[n] n
int 2 -32768 .. 32767
int16_t 2 idem 'int'
short int 2 pareil que int (?)
unsigned int 2 0 .. 65535
uint16_t 2 idem 'unsigned int'
long int 4 octets -2 147 483 648 à 2 147 483 647
int32_t 4 octets -> 32 bits ; idem long int
long long int 8 octets -> 64 bits
unsigned long int 4 octets -> 32 bits ; 0 .. 4 294 967 295 (4,2 x 10^9)
uint32_t 4 32 bits ; idem 'unsigned long int'
float 4
double ATTENTION ! 4 octets (oui, 32 bits ! et pas 64 bits (8 octets) comme en C standard)
La déclaration char JOUR[7][9];
réserve l'espace en mémoire pour 7 mots contenant 9 caractères (dont 8 caractères significatifs).
**/
void init_ports (void)
{
// 0 = entree, 1=sortie ; les 1 sur les pins en entrees activent les R de Pull Up (tirage à VCC)
DDRD = 0b11110000;
PORTD = 0b00001111;
DDRE = 0b11110111;
PORTE = 0b00001000;
DDRF = 0b11101110;
PORTF = 0b00000000;
DDRH = 0b11100100;
PORTH = 0b00011011;
DDRJ = 0b11111100;
PORTJ = 0b00000011;
DDRK = 0b11111111;
PORTK = 0b00000000;
// REMARQUE : les ports et pins utilisés par le circuit ADF4351 sont définis dans les fichiers "ADF4351-628v{x}.h"
}
/**
The ADC module contains a prescaler, which generates an acceptable ADC clock fre-
quency from any CPU frequency above 100 kHz. The prescaling is set by the ADPS bits
in ADCSRA
**/
void InitADC()
{
//SFIOR = 0b10000000; // ADTS2,1,0 = 100 -> ADC declenché par Timer0 Overflow - p:218
/** ========= REGITRE ADMUX ======= **/
ADMUX = 0b11000000;
//Bit 7:6 = ADC Reference Selection = 11 -> Internal 2.56V Voltage Reference with external capacitor at AREF pin - p:281 du datasheet ATmega2560
//Bits 0:5 - Analog Channel Selection Bits et gain éventuel - p282
// ici: Select pin ADC0 using MUX avec ref tension 2.56V interne - pas de gain.
/** ========= REGITRE ADCSRA ======= **/
// voir p:285
ADCSRA = 0b10000101; // Activate ADC; Prescaler=f/32; bit5=0 -> Auto-Trigger desable
// bits [0..2] = ADPS -> Prescaler
// ADPS = 010; Prescaler=f/4 gamme 8-90 kHz
// ADPS = 011; Prescaler=f/8 gamme 4-56 kHz
// ADPS = 100; Prescaler=f/16 gamme 2-31 kHz
// ADPS = 101; Prescaler=f/32 gamme 1-15 kHz
// ADPS = 110; Prescaler=f/64 gamme 300Hz- 8kHz
// ADPS = 111; Prescaler=f/128 gamme 200Hz- 4300 Hz
//bit5 = ADATE (ADC Auto Trigger Enable)
//Bit7 – ADEN: ADC Enable Writing this bit to one enables the ADC. By writing it to zero, the ADC is turned off.
}
template <class T> void EEPROM_write_Struct(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
for (int i = 0; i < sizeof(value); i++) { EEPROM.write(ee++, *p++); }
}
template <class T> void EEPROM_read_Struct(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
for (int i = 0; i < sizeof(value); i++) { *p++ = EEPROM.read(ee++); }
}
void save_params_to_EEPROM()
{
EEPROM_write_Struct(addr_params1, params1);
}
void load_params_from_EEPROM()
{
EEPROM_read_Struct(addr_params1, params1);
}
int freeRam()
{
extern int __heap_start, *__brkval;
int v;
return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
void int_EXT_setup()
{
// voir 15. External Interrupts (ATmega2560.pdf p:109)
EICRA |= 0b00001010; // bits[1,0] = 10 -> int0 sur front descendant; bits[3,2] = 10 -> int1 sur front descendant; - p:110
EIMSK |= 0b00000011; // bit[0]=1 -> INT0 enable ; bit[1]=1 -> INT1 enable - parag 15.2.3 EIMSK - p:111
}
void setCouleur(uint8_t *couleur_i, uint8_t R, uint8_t V,uint8_t B)
{
couleur_i[0]=R;
couleur_i[1]=V;
couleur_i[2]=B;
}
void init_variables(void)
{
load_params_from_EEPROM();
// penser à changer la valeur de la clé suivante après toute modif de la "struct parametres" pour forcer le reparamétrage
if (params1.cle != 187) // à la première programmation la clé ne sera pas correcte => reset bas niveau
{
params1.cle = 187; // cle ok pour les fois suivantes (ainsi on ne repassera plus pas cette condition)
params1.offset_y =0;
params1.gain=1;
params1.pos_curFreq_gene_AD98 = 4; // valeur de départ; on peut la modifier (détermine le digit en surbrillance pour la fréquence)
params1.pos_curFreq_gene_ADF43 = 4;
params1.pos_curFreq_wobu_AD98 = 4;
params1.pos_curFreq_wobu_ADF43 = 4; // valeur de départ; on peut la modifier (détermine le facteur kHz/div au départ)
params1.pos_curseur_wob = 2;
params1.pos_mark = 300;
params1.frequence_AD9850 = 10000; // 1.0 kHz
params1.frequence_ADF4351 = 3500; // 35.00 MHz
}
pas_frq_gene_AD98=1; for (int n=1; n<params1.pos_curFreq_gene_AD98; n++) { pas_frq_gene_AD98 *=10; } // <- ne surtout pas toucher cette ligne de calcul auto
pas_frq_gene_ADF43=1; for (int n=1; n<params1.pos_curFreq_gene_ADF43; n++) { pas_frq_gene_ADF43 *=10; } // <- ne surtout pas toucher cette ligne de calcul auto
pas_frq_wobu_AD98=1; for (int n=1; n<params1.pos_curFreq_wobu_AD98; n++) { pas_frq_wobu_AD98 *=10; } // <- ne surtout pas toucher cette ligne de calcul auto
pas_frq_wobu_ADF43=1; for (int n=1; n<params1.pos_curFreq_wobu_ADF43; n++) { pas_frq_wobu_ADF43 *=10; } // <- ne surtout pas toucher cette ligne de calcul auto
if (SW_carte == Crt_AD9850) {kHz_div=1;}
if (SW_carte == Crt_ADF4351) {kHz_div=10;}
kHz_div *= facteurs_mult[params1.pos_curseur_wob]; // <- ne surtout pas toucher cette ligne de calcul auto
dB_div =1; dB_div *= facteurs_mult[params1.gain]; // <- ne surtout pas toucher cette ligne de calcul auto
mV_div =1; mV_div *= facteurs_mult[params1.gain]; // <- ne surtout pas toucher cette ligne de calcul auto
setCouleur(couleur_gain, 0, 255, 0);
envoyer_data = 0;
frq_min_AD98 = 1; // 1 dixième de Hz -> 0.1Hz
frq_max_AD98 = 50e6 * 10; // 50 000 000 0 représentant 50 000 000.0 Hz soit (50e6 x 10) dixièmes de Hz -> 50.0MHz
borne_frequence_AD9850();
frq_min_ADF43 = 3300; // 33.00 MHz - La PLL de l'ADF4351 décroche en dessous de 32MHz environ (voir led LOCK en mode GENE)
frq_max_ADF43 = 440000; //4400.00 MHz = 4.4 GHz
borne_frequence_ADF4351();
compteur1 = 0;
depassement = 0;
raffraichir=1;
afficher_freq=1;
}
void borne_frequence_AD9850()
{
if ( (params1.frequence_AD9850) < frq_min_AD98) {params1.frequence_AD9850 = frq_min_AD98;}
if ( (params1.frequence_AD9850) > frq_max_AD98) {params1.frequence_AD9850 = frq_max_AD98;}
}
void borne_frequence_ADF4351()
{
if ( (params1.frequence_ADF4351) < frq_min_ADF43) {params1.frequence_ADF4351 = frq_min_ADF43;}
if ( (params1.frequence_ADF4351) > frq_max_ADF43) {params1.frequence_ADF4351 = frq_max_ADF43;}
}
void inc_FRQ_AD9850()
{
uint32_t pF3m = pas_frq_wobu_AD98 * 10000;
if (SW_mode == mode_GENE)
{
if ( (params1.frequence_AD9850 + pas_frq_gene_AD98) <= frq_max_AD98) {params1.frequence_AD9850 += pas_frq_gene_AD98;}
borne_frequence_AD9850();
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV))
{
if ( (params1.frequence_AD9850 + pF3m) <= frq_max_AD98) {params1.frequence_AD9850 += pF3m;}
borne_frequence_AD9850();
}
}
void dec_FRQ_AD9850()
{
uint32_t pF3m = pas_frq_wobu_AD98 * 10000;
if (SW_mode == mode_GENE)
{
if (params1.frequence_AD9850 >= pas_frq_gene_AD98) {params1.frequence_AD9850 -= pas_frq_gene_AD98;}
borne_frequence_AD9850();
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV))
{
if (params1.frequence_AD9850 >= pF3m) {params1.frequence_AD9850 -= pF3m;}
borne_frequence_AD9850();
}
}
void inc_FRQ_ADF4351()
{
if (SW_mode == mode_GENE)
{
if ( (params1.frequence_ADF4351 + pas_frq_gene_ADF43) <= frq_max_ADF43) {params1.frequence_ADF4351 += pas_frq_gene_ADF43;}
borne_frequence_ADF4351();
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV))
{
if ( (params1.frequence_ADF4351 + pas_frq_wobu_ADF43) <= frq_max_ADF43) {params1.frequence_ADF4351 += pas_frq_wobu_ADF43;}
borne_frequence_ADF4351();
}
}
void dec_FRQ_ADF4351()
{
if (SW_mode == mode_GENE)
{
if (params1.frequence_ADF4351 >= pas_frq_gene_ADF43) {params1.frequence_ADF4351 -= pas_frq_gene_ADF43;}
borne_frequence_ADF4351();
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV))
{
if (params1.frequence_ADF4351 >= pas_frq_wobu_ADF43) {params1.frequence_ADF4351 -= pas_frq_wobu_ADF43;}
borne_frequence_ADF4351();
}
}
void inc_offset()
{
params1.offset_y += 10;
if ( params1.offset_y > 2000) {params1.offset_y = 2000;}
Affi_12.affiche_valeur(params1.offset_y, 5, "");
}
void dec_offset()
{
params1.offset_y -= 10;
if (params1.offset_y < -2000) {params1.offset_y = -2000;}
Affi_12.affiche_valeur(params1.offset_y, 5, "");
}
void inc_pos_curseur_frq()
{
uint8_t cur_max;
uint8_t n;
//Rappel : SW_mode -> 1=[gene freq] ; 2=[Wobu dB] ; 3=[Wobu mV]
if (SW_carte == Crt_AD9850)
{
if (SW_mode == mode_GENE)
{
cur_max = 9;
if (params1.pos_curFreq_gene_AD98 < cur_max) {params1.pos_curFreq_gene_AD98++ ;}
pas_frq_gene_AD98=1;
for (n=1; n<params1.pos_curFreq_gene_AD98; n++) { pas_frq_gene_AD98 *=10; }
}
else // ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV)) // WOBULATION
{
cur_max = 5;
if (params1.pos_curFreq_wobu_AD98 < cur_max) {params1.pos_curFreq_wobu_AD98++ ;}
pas_frq_wobu_AD98=1;
for (n=1; n<params1.pos_curFreq_wobu_AD98; n++) { pas_frq_wobu_AD98 *=10; }
}
}
if (SW_carte == Crt_ADF4351)
{
if (SW_mode == mode_GENE)
{
cur_max = 6;
if (params1.pos_curFreq_gene_ADF43 < cur_max) {params1.pos_curFreq_gene_ADF43++ ;}
pas_frq_gene_ADF43=1;
for (n=1; n<params1.pos_curFreq_gene_ADF43; n++) { pas_frq_gene_ADF43 *=10; }
}
else // ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV)) // WOBULATION
{
cur_max = 6;
if (params1.pos_curFreq_wobu_ADF43 < cur_max) {params1.pos_curFreq_wobu_ADF43++ ;}
pas_frq_wobu_ADF43=1;
for (n=1; n<params1.pos_curFreq_wobu_ADF43; n++) { pas_frq_wobu_ADF43 *=10; }
}
}
}
void dec_pos_curseur_frq()
{
uint8_t n;
if (SW_carte == Crt_AD9850)
{
if (SW_mode == mode_GENE)
{
if (params1.pos_curFreq_gene_AD98 > 1) {params1.pos_curFreq_gene_AD98--;}
pas_frq_gene_AD98=1;
for (n=1; n<params1.pos_curFreq_gene_AD98; n++) { pas_frq_gene_AD98 *=10; }
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV)) // WOBULATION
{
if (params1.pos_curFreq_wobu_AD98 > 1) {params1.pos_curFreq_wobu_AD98--;}
pas_frq_wobu_AD98=1;
for (n=1; n<params1.pos_curFreq_wobu_AD98; n++) { pas_frq_wobu_AD98 *=10; }
}
}
if (SW_carte == Crt_ADF4351)
{
if (SW_mode == mode_GENE) // GENE
{
if (params1.pos_curFreq_gene_ADF43 > 1) {params1.pos_curFreq_gene_ADF43--;}
pas_frq_gene_ADF43=1;
for (n=1; n<params1.pos_curFreq_gene_ADF43; n++) { pas_frq_gene_ADF43 *=10; }
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV)) // WOBULATION
{
if (params1.pos_curFreq_wobu_ADF43 > 1) {params1.pos_curFreq_wobu_ADF43--;}
pas_frq_wobu_ADF43=1;
for (n=1; n<params1.pos_curFreq_wobu_ADF43; n++) { pas_frq_wobu_ADF43 *=10; }
}
}
}
void inc_pas_curseur_wob()
{
uint8_t cur_max;
if (SW_carte == Crt_ADF4351) { cur_max = 12;}
if (SW_carte == Crt_AD9850) { cur_max = 9;}
if (params1.pos_curseur_wob > cur_max) {params1.pos_curseur_wob = cur_max;}
if (params1.pos_curseur_wob < cur_max) {params1.pos_curseur_wob++ ;}
}
void dec_pas_curseur_wob()
{
if (params1.pos_curseur_wob > 0) {params1.pos_curseur_wob--;}
}
void affiche_freq_marqueur()
{
Affi_10.affiche_float(F_mark, 6, 2, "");
TFT480.setColor(100, 100, 100);
}
void affi_marqueur()
{
uint16_t memo_pos_mark;
uint16_t y_i, y2;
memo_pos_mark = params1.pos_mark;
if((memo_pos_mark % 47)==0) { TFT480.setColor(120, 120,120); } else { TFT480.setColor(0, 0, 0); }
if(memo_pos_mark == 235) { TFT480.setColor(255, 100,100); }
TFT480.drawLine(params1.pos_mark, 81, params1.pos_mark, 318);// efface le marqueur avant de le deplacer (et retrace le réticule en jouant sur les couleurs)
//re-quadrillage H (juste les points qui ont été effacés)
for (int i=1; i<10; i++)
{
y2= 81 + 24*i;
TFT480.setColor(60, 60, 60);
TFT480.drawPixel(memo_pos_mark, y2);
}
if (etat == 1) { if (params1.pos_mark > 1) {params1.pos_mark --;} }
else { if ( params1.pos_mark <= 469) {params1.pos_mark ++;} if ( params1.pos_mark > 470) {params1.pos_mark = 470;} }
TFT480.setColor(200, 0, 255);
TFT480.drawLine(params1.pos_mark, 81, params1.pos_mark, 318); // retrace le marqueur à sa nouvelle position
TFT480.setColor(0, 255, 0);
y_i=tableau_acq[memo_pos_mark];
TFT480.drawPixel(memo_pos_mark, y_i); // <=== retrace le signal effacé
affiche_freq_marqueur();
}
void affi_min_max()
{
TFT480.setFont(SmallFont);
//RAPPEL: void printNumF(double num, byte dec, int x, int y, char divider='.', int length=0, char filler=' ');
TFT480.setColor(0, 180, 255);
TFT480.printNumF(F_affi_min/100.0, 2, 2, 304, '.', 8, ' ');
TFT480.printNumF(F_affi_max/100.0, 2, 400, 304, '.', 8, ' ');
}
ISR (INT0_vect)
{
cli();
//interruption sur front descendant sur l'entree Int0 déclenchée par la rotation du codeur_ROT (1) -> FRQ
etat =(PIND & pin_rot0) == pin_rot0;
switch (SW_mode)
{
case mode_GENE :
{
if(SW_carte == Crt_AD9850) { if(etat == 0) {inc_FRQ_AD9850();} else {dec_FRQ_AD9850();} }
if(SW_carte == Crt_ADF4351) { if(etat == 0) {inc_FRQ_ADF4351();} else {dec_FRQ_ADF4351();} }
}
break;
case mode_WOBU_dB :
case mode_WOBU_mV :
{
switch (SW_saisie)
{
case md_saisie_Hz_div :
{
affi_marqueur();
}
break;
case md_saisie_frq :
{
setCouleur(couleur_gain, 0, 255, 0);
if(SW_carte == Crt_AD9850) { if(etat == 0) {inc_FRQ_AD9850();} else {dec_FRQ_AD9850();} }
if(SW_carte == Crt_ADF4351) { if(etat == 0) {inc_FRQ_ADF4351();} else {dec_FRQ_ADF4351();} }
}
break;
case md_saisie_dB_div :
{
switch (SW_mode)
{
case mode_WOBU_dB : //saisie OFFSET - gain dB/div
{
setCouleur(couleur_gain, 0, 255, 255);
if(etat == 0) {params1.gain += 1;} else {params1.gain -= 1;}
if(params1.gain<0) {params1.gain=0;}
if(params1.gain>3) {params1.gain=3;}
dB_div =1;
dB_div *= facteurs_mult[params1.gain];
Affi_11.affiche_valeur(dB_div, 2, "");
}
break;
case mode_WOBU_mV : //saisie OFFSET - gain mV/div
{
setCouleur(couleur_gain, 0, 255, 255);
if(etat == 1) {params1.gain += 1;} else {params1.gain -= 1;}
if(params1.gain<3) {params1.gain=3;}
if(params1.gain>12) {params1.gain=12;}
mV_div =1;
mV_div *= facteurs_mult[params1.gain];
if (params1.gain == 3)
{
Affi_11.setCouleurTxt(bleu);
Affi_11.affiche_texte("min");
_delay_ms(300);
}
Affi_11.setCouleurTxt(jaune);
affiche_V_div();
}
break;
}
break;
}
break;
}
break;
}
}
envoyer_data = 1;
stop =1;
//raffraichir=1;
afficher_freq=1;
sei();
}
ISR (INT1_vect)
{
cli();
//interruption sur front descendant sur l'entree Int1 déclenchée par la rotation du codeur_ROT (2)
// uint8_t n;
etat =(PIND & pin_rot1) == pin_rot1;
if (SW_mode == mode_GENE)
{
if(etat == 1) { inc_pos_curseur_frq(); } else { dec_pos_curseur_frq();}
envoyer_data = 1;
}
else // MODES WOBULATEUR
{
switch (SW_saisie)
{
case md_saisie_dB_div :
if(etat == 0) { inc_offset();} else { dec_offset();}
break;
case md_saisie_Hz_div :
{
if(etat == 0) {inc_pas_curseur_wob();} else {dec_pas_curseur_wob();}
if (SW_carte == Crt_AD9850) {kHz_div=1;}
if (SW_carte == Crt_ADF4351) {kHz_div=10;}
kHz_div *= facteurs_mult[params1.pos_curseur_wob];
if (params1.pos_curseur_wob == 0)
{
Affi_9.setCouleurTxt(bleu);
Affi_9.affiche_texte("min");
_delay_ms(300);
}
if (params1.pos_curseur_wob == 12)
{
Affi_9.setCouleurTxt(rouge);
Affi_9.affiche_texte("MAX");
_delay_ms(300);
}
}
break;
case md_saisie_frq :
{
if(etat == 1) {inc_pos_curseur_frq(); } else {dec_pos_curseur_frq();}
envoyer_data = 1;
}
break;
}
}
envoyer_data = 1;
stop =1; // ==> provoque la sortie de la boucle de balayage (voir "BOUCLE DE BALAYAGE" dans fonction "loop", ligne 1552 environ)
afficher_freq=1;
sei();
}
ISR(TIMER3_COMPA_vect)
{ }
void acquisition_data_WOB()
{
uint16_t acqH;
uint16_t val = 0;
PORTF |= 0b00000010; // signal test
ADCSRA |= _BV(ADSC); //Start conversion - resolution 10bits
while (ADCSRA & _BV(ADSC) ) {;} // attend la fin de la conversion
PORTF &= ~0b00000010;
val = ADCL;
acqH = ADCH; // passage à 16 bits pour pouvoir décaller
val += (acqH << 8);
valeur_lue = val;
/** pour afficher le résultat, pour test (en connectant une tension connue sur l'entrée ADC)
TFT480.setFont(BigFont);
TFT480.setColor(255, 255, 100);
TFT480.print("ADC", 20, 180);
TFT480.printNumI(valeur_lue, 145, 180, 4, '0');
// résultat [0...1023] pour [0V .. 2.54V]
**/
}
void affiche_entete()
{
TFT480.setColor(64, 64, 64);
TFT480.fillRect(0, 0, 479, 13); // bandeau en haut
TFT480.setColor(30, 30, 30);
TFT480.fillRect(0, 300, 479, 319); // bandeau en bas
TFT480.setColor(255,255,255);
TFT480.setFont(SmallFont);
TFT480.print("GENE-Wobu 0.1Hz .. 4400MHz - AD9850 + ADF4351", CENTER, 1);
// TFT480.setBackColor(64, 64, 64);
TFT480.setColor(255,255,255);
TFT480.print(version, 5, 300);
TFT480.setColor(255,255,255);
TFT480.print("ATmega2560 - ", 100, 300);
TFT480.setColor(255,255,255);
TFT480.print("Silicium628", 210, 300);
}
void init_afficheurs_wob()
{
if (SW_carte == Crt_AD9850)
{
Affi_9.init(220, 40, 120, 35," Hz/div"); Affi_9.setCouleurTxt(bleu_pale);
Affi_10.init(220, 0, 140, 35,"Mark"); Affi_10.setCouleurTxt(violet);
if (SW_mode == mode_WOBU_dB)
{
Affi_11.init(355, 0, 110, 35,"dB/div"); Affi_11.setCouleurTxt(jaune);
}
if (SW_mode == mode_WOBU_mV)
{
Affi_11.init(375, 0, 90, 35," V/dv"); Affi_11.setCouleurTxt(jaune);
}
Affi_12.init(355, 40, 110, 35,"Offset"); Affi_12.setCouleurTxt(vert);
}
if (SW_carte == Crt_ADF4351)
{
Affi_9.init(220, 40, 120, 35," Hz/div"); Affi_9.setCouleurTxt(bleu_pale);
Affi_10.init(220, 0, 120, 35,"Mark"); Affi_10.setCouleurTxt(violet);
if (SW_mode == mode_WOBU_dB)
{
Affi_11.init(355, 0, 110, 35,"dB/div"); Affi_11.setCouleurTxt(jaune);
}
if (SW_mode == mode_WOBU_mV)
{
Affi_11.init(355, 0, 110, 35," V/div"); Affi_11.setCouleurTxt(jaune);
}
Affi_12.init(355, 40, 110, 35,"Offset"); Affi_12.setCouleurTxt(vert);
}
}
void affiche_pas_DIV(uint8_t couleur)
{
if (kHz_div<1000)
{
Affi_9.init(220, 40, 120, 35,"kHz/div");
if (couleur == 0)
{
Affi_9.setCouleurTxt(blanc);
Affi_9.affiche_valeur(kHz_div, 6, "");
}
else
{
Affi_9.setCouleurTxt(jaune);
Affi_9.affiche_valeur(kHz_div, 6, "");
}
}
else
{
Affi_9.init(220, 40, 120, 35,"MHz/div");
if (couleur == 0)
{
Affi_9.setCouleurTxt(blanc);
Affi_9.affiche_valeur(kHz_div/1000, 6, "");
}
else
{
Affi_9.setCouleurTxt(jaune);
Affi_9.affiche_valeur(kHz_div/1000, 6, "");
}
}
}
void affiche_V_div()
{
if (SW_carte == Crt_AD9850)
{
if (mV_div<1000)
{
Affi_11.init(375, 0, 90, 35,"mV/dv");
Affi_11.affiche_valeur(mV_div, 5, "");
}
else
{
Affi_11.init(375, 0, 90, 35," V/div");
Affi_11.affiche_valeur(mV_div/1000, 5, "");
}
}
if (SW_carte == Crt_ADF4351)
{
if (mV_div<1000)
{
Affi_11.init(355, 0, 110, 35,"mV/div");
Affi_11.affiche_valeur(mV_div, 5, "");
}
else
{
Affi_11.init(375, 0, 110, 35," V/div");
Affi_11.affiche_valeur(mV_div/1000, 5, "");
}
}
}
void init_afficheurs_var_ADF()
{
uint16_t xp1 = 145;
uint16_t yp1 = 120;
uint8_t dy1 = 60;
Affi_5.init(xp1, yp1, 75, 50,"Div"); Affi_5.setCouleurTxt(orange); Affi_5.setCouleurCadre(gris);
Affi_6.init(xp1, yp1+dy1, 75, 50,"FRAC"); Affi_6.setCouleurTxt(orange); Affi_6.setCouleurCadre(gris);
Affi_7.init(xp1, yp1+dy1*2, 75, 50,"MOD"); Affi_7.setCouleurTxt(orange); Affi_7.setCouleurCadre(gris);
Affi_8.init(xp1+80, yp1, 85, 50,"INTA"); Affi_8.setCouleurTxt(orange); Affi_8.setCouleurCadre(gris);
uint16_t xp2 = 385;
uint16_t yp2 = 40;
uint8_t dy2 = 40;
Affi_R0.init(xp2, yp2, 80, 35,"R0"); Affi_R0.setCouleurTxt(jaune_sombre); Affi_R0.setCouleurCadre(gris);
Affi_R1.init(xp2, yp2+dy2, 80, 35,"R1"); Affi_R1.setCouleurTxt(jaune_sombre); Affi_R1.setCouleurCadre(gris);
Affi_R2.init(xp2, yp2+dy2*2, 80, 35,"R2"); Affi_R2.setCouleurTxt(jaune_sombre); Affi_R2.setCouleurCadre(gris);
Affi_R3.init(xp2, yp2+dy2*3, 80, 35,"R3"); Affi_R3.setCouleurTxt(jaune_sombre); Affi_R3.setCouleurCadre(gris);
Affi_R4.init(xp2, yp2+dy2*4, 80, 35,"R4"); Affi_R5.setCouleurTxt(jaune_sombre); Affi_R4.setCouleurCadre(gris);
Affi_R5.init(xp2, yp2+dy2*5, 80, 35,"R5"); Affi_R5.setCouleurTxt(jaune_sombre); Affi_R5.setCouleurCadre(gris);
}
void efface_ecran()
{
TFT480.setColor(0, 0, 0);
// TFT480.fillRect(0, 14, 479, 309); // efface
TFT480.fillRect(0, 0, 479, 319); // efface
}
void trace_ecran()
{
if (SW_mode == mode_GENE)
{
efface_ecran();
affiche_entete();
TFT480.setBackColor(0, 0, 0);
TFT480.setColor(180,180,180);
TFT480.setFont(BigFont);
Affi_1a.init(5, 20, 358, 80, "FREQ AD9850");
Affi_1b.init(5, 165, 210, 80,"FREQ ADF4351"); Affi_1b.setCouleurTxt(bleu); Affi_1b.setCouleurCadre(gris);
Affi_1a.setCouleurTxt(bleu);
Affi_1b.setCouleurTxt(bleu);
TFT480.setFont(BigFont);
TFT480.setBackColor(20, 20, 20);
TFT480.setColor(0, 255, 0);
TFT480.print("AD9850", 376, 20);
Affi_2a.init(5, 110, 130, 40,"Lambda "); Affi_2a.setCouleurTxt(jaune); Affi_2a.setCouleurCadre(gris);
Affi_3a.init(140, 110, 130, 40,"Lambda/2"); Affi_3a.setCouleurTxt(jaune); Affi_3a.setCouleurCadre(gris);
Affi_4a.init(275, 110, 130, 40,"Lambda/4"); Affi_4a.setCouleurTxt(jaune); Affi_4a.setCouleurCadre(gris);
TFT480.setColor(0, 255, 0);
TFT480.drawLine(0, 160, 479, 160);
// init_afficheurs_var_ADF();
TFT480.setFont(BigFont);
TFT480.setBackColor(20, 20, 20);
TFT480.setColor(0, 255, 255);
TFT480.print("ADF4351", 365, 165);
Affi_2b.init(5, 250, 130, 40,"Lambda "); Affi_2b.setCouleurTxt(jaune); Affi_2b.setCouleurCadre(gris);
Affi_3b.init(140, 250, 130, 40,"Lambda/2"); Affi_3b.setCouleurTxt(jaune); Affi_3b.setCouleurCadre(gris);
Affi_4b.init(275, 250, 130, 40,"Lambda/4"); Affi_4b.setCouleurTxt(jaune); Affi_4b.setCouleurCadre(gris);
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV))
{
TFT480.setColor(10, 10, 5);
TFT480.fillRect(0, 0, 479, 319); // efface tout
if(SW_carte == Crt_AD9850)
{
Affi_1c.init(0, 0, 210, 80,"Fo AD9850"); Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(gris);
}
if(SW_carte == Crt_ADF4351)
{
Affi_1c.init(0, 0, 210, 80,"Fo ADF4351"); Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(gris);
}
init_afficheurs_wob();
trace_pannel_graph();
}
affi_helps();
}
void trace_pannel_graph()
{
TFT480.setColor(0, 0, 0);
TFT480.fillRect(0, 80, 479, 319);
TFT480.setColor(180, 180, 180);
TFT480.drawRect(0, 80, 479, 319);
//quadrillage V
uint16_t n;
uint16_t x;
for ( n=1; n<10; n++)
{
x= 47*n;
if (n==5) { TFT480.setColor(120, 120,120); } else { TFT480.setColor(60, 60, 60); }
TFT480.drawLine(x, 81, x, 318);
}
//quadrillage H
uint16_t y;
for (n=1; n<10; n++)
{
y= 81 + 24*n;
if (n==5) { TFT480.setColor(120, 120,120); } else { TFT480.setColor(60, 60, 60); }
TFT480.drawLine(1, y, 478, y);
}
}
void efface_centre_graph()
{
TFT480.setColor(0, 0, 0);
TFT480.fillRect(101, 101, 349, 299);
TFT480.setColor(0, 200, 200);
TFT480.drawRect(100, 100, 350, 300);
TFT480.setColor(200, 0, 0);
TFT480.drawLine(235, 101, 235, 299);
TFT480.setColor(200,200,200);
TFT480.setFont(SmallFont);
TFT480.print("Mode balayage rapide", 150, 306);
}
void trace_sinusoide()
{
TFT480.setColor(0, 255, 0);
for (uint16_t n=0; n<470; n++)
{
float x, y;
x= (float)n/470.0*2.0*M_PI;
y=190-80*sin(5*x);
TFT480.drawPixel(n, y);
}
}
void TFT_affiche_chiffre_7seg(uint8_t num, uint16_t x_i, uint16_t y_i )
{
TFT480.setFont(SevenSegNumFont);
TFT480.printNumI(num, x_i, y_i);
}
void TFT_aff_nb_form3 (uint32_t valeur, uint8_t nb_chiffres, uint8_t curseur, uint8_t R, uint8_t G, uint8_t B, uint8_t SB, uint16_t x_i, uint16_t y_i)
{
//affiche un nombre en représentation decimale en séparant les groupes de 3 chiffres
unsigned char r ;
char tbl[10];
uint8_t i;
x_7seg = x_i;
y_7seg = y_i;
curseur=nb_chiffres +1 -curseur;
for (i=1; i<=nb_chiffres; i++)
{
r=valeur % 10; // modulo (reste de la division)
valeur /= 10; // quotient
tbl[i]=r;
}
for (i=1; i<= nb_chiffres; i++)
{
TFT480.setColor(R,G,B);
if ((i==curseur) && (SB == 1))
{
TFT480.setColor(0,250,250);
}
TFT_affiche_chiffre_7seg(tbl[nb_chiffres +1 -i], x_7seg, y_7seg);
x_7seg+=30;
uint8_t m, k, u, d;
m = nb_chiffres-7;
k = nb_chiffres-4;
u = nb_chiffres-1;
d = nb_chiffres;
if (i== m)
{
TFT480.setFont(BigFont);
TFT480.setColor(180,180,180);
TFT480.print("M",x_7seg, y_7seg+30);
x_7seg+=15;
}
if (i== k)
{
TFT480.setFont(BigFont);
TFT480.setColor(180,180,180);
TFT480.print("k",x_7seg, y_7seg+30);
x_7seg+=15;
}
if (i== u)
{
TFT480.setFont(BigFont);
TFT480.setColor(220,220,220);
TFT480.print(".",x_7seg, y_7seg+30);
x_7seg+=15;
}
if (i== d)
{
TFT480.setFont(BigFont);
TFT480.setColor(220,220,220);
TFT480.print("Hz",x_7seg, y_7seg+30);
}
}
}
void TFT_aff_nb_form3b (uint32_t valeur, uint8_t nb_chiffres, uint8_t nb_dec, uint8_t curseur, uint8_t R, uint8_t G, uint8_t B, uint8_t SB, uint16_t x_i, uint16_t y_i)
{
//affiche un nombre en représentation décimale avec séparateur 'M' à gauche des 2 chiffres de droite
unsigned char r ;
char tbl[7];
uint8_t i, m;
x_7seg = x_i;
y_7seg = y_i;
curseur=nb_chiffres +1 -curseur;
for (i=1; i<=nb_chiffres; i++)
{
r=valeur % 10; // modulo (reste de la division)
valeur /= 10; // quotient
tbl[i]=r;
}
for (i=1; i<= nb_chiffres; i++)
{
TFT480.setColor(R,G,B);
if ((i==curseur) && (SB == 1) )
{
TFT480.setColor(0,250,250); // surbrillance du digit sélectionné
}
TFT_affiche_chiffre_7seg(tbl[nb_chiffres +1 -i], x_7seg, y_7seg);
x_7seg+=30;
m = nb_chiffres - nb_dec;
if (i==m)
{
TFT480.setFont(BigFont);
TFT480.setColor(200,200,200);
TFT480.print("M",x_7seg, y_7seg+30); // affichage du separateur 'M' (M comme Megahertz)
x_7seg+=15;
}
}
}
// ===================================================================================================================================================
void setup()
{
init_ports();
init_variables();
scrute_switches();
TFT480.InitLCD();
TFT480.setFont(SmallFont);
TFT480.clrScr();
int_EXT_setup();
CarteADF4351.init();
CarteADF4351.mute(0);
AffiV_01.init(469, 110); AffiV_01.setCouleur(noir);
AffiV_02.init(469, 305); AffiV_02.setCouleur(noir);
/* POUR INFO - ces lignes peuvent être commentées */
//int free_RAM;
//free_RAM = freeRam();
//TFT480.setFont(BigFont);
//TFT480.setColor(255, 255, 100);
//TFT480.print(version, 20, 160);
//TFT480.setColor(0, 200, 200);
//TFT480.print("free_RAM", 20, 180);
//TFT480.printNumI(free_RAM, 145, 180, 6, ' ');
//TFT480.print("octets", 250, 180);
//_delay_ms(2000);
/* ********************************************** */
trace_pannel_graph();
// trace_sinusoide();
// _delay_ms(1000);
trace_ecran();
if (SW_rapide == 1) { efface_centre_graph();}
//init_leds_switches();
InitADC();
sei(); // enable interruptions
envoyer_data = 1;
}
void affiche_valeurs_registres()
{
Affi_R0.affiche_HEXA(CarteADF4351.registers[0]);
Affi_R1.affiche_HEXA(CarteADF4351.registers[1]);
Affi_R2.affiche_HEXA(CarteADF4351.registers[2]);
Affi_R3.affiche_HEXA(CarteADF4351.registers[3]);
Affi_R4.affiche_HEXA(CarteADF4351.registers[4]);
Affi_R5.affiche_HEXA(CarteADF4351.registers[5]);
}
void affiche_lambda_a()
{
if (params1.frequence_AD9850 >= 60000)
{
Affi_2a.affiche_float(lambda_a/100.0, 4, 2, "m ");
Affi_3a.affiche_float(lambda_a/200.0, 4, 2, "m ");
Affi_4a.affiche_float(lambda_a/400.0, 4, 1, "m ");
}
else
{
Affi_2a.affiche_texte("-------");
Affi_3a.affiche_texte("-------");
Affi_4a.affiche_texte("-------");
}
}
void affiche_lambda_b()
{
if (params1.frequence_ADF4351 >= 300 )
{
if(lambda_b <= 100)
{
Affi_2b.affiche_float(lambda_b, 4, 1, "cm");
Affi_3b.affiche_float(lambda_b/2, 4, 1, "cm");
Affi_4b.affiche_float(lambda_b/4, 4, 1, "cm");
}
else
{
Affi_2b.affiche_float(lambda_b/100.0, 4, 2, "m ");
Affi_3b.affiche_float(lambda_b/200.0, 4, 2, "m ");
Affi_4b.affiche_float(lambda_b/400.0, 4, 2, "m ");
}
}
else
{
Affi_2b.affiche_texte("-------");
Affi_3b.affiche_texte("-------");
Affi_4b.affiche_texte("-------");
}
}
void affiche_params()
{
DIV = CarteADF4351.DIV; Affi_5.affiche_valeur(DIV, 4, " ");
FRAC = CarteADF4351.FRAC; Affi_6.affiche_valeur(FRAC, 4, " ");
MOD = CarteADF4351.MOD; Affi_7.affiche_valeur(MOD, 4, " ");
INTA = CarteADF4351.INTA; Affi_8.affiche_valeur(INTA, 5, " ");
}
void init_leds()
{
LED_b1.init(388, 70, 255,0,0,10, "ON" );
LED_b2.init(388, 200, 255,0,0,10, "ON" );
if (SW_carte == Crt_ADF4351)
{
LED_a.init(388, 230, 0,255,0,10, "LOCK" );
}
}
void init_leds_switches()
{
LED0.init(452, 8, 255,0,0,5, "" );
LED1.init(452, 18, 255,255,0,5, "" );
LED2.init(462, 8, 0,255,0,5, "" );
LED3.init(472, 8, 0,255,255,5, "" );
LED4.init(472, 18, 0,0,255,5, "" );
}
void calcul_lambda_a()
{
lambda_a = 3e11/params1.frequence_AD9850; // en cm
}
void calcul_lambda_b()
{
lambda_b = 3e6/params1.frequence_ADF4351; // en cm
}
void affi_helps() // Ecriture verticales au bord droit de l'écran pour rappeler la fonction des boutons + coloration des afficheurs
{
if (SW_mode == mode_GENE) //GENE
{
AffiV_01.affiche_texte_V(" FREQ");
AffiV_02.affiche_texte_V(" DIGIT");
if (SW_carte == Crt_AD9850)
{
Affi_1a.setCouleurCadre(jaune_sombre);
Affi_1a.flashFond(jaune_sombre);
Affi_1b.setCouleurCadre(gris);
}
if (SW_carte == Crt_ADF4351)
{
Affi_1b.setCouleurCadre(jaune_sombre);
Affi_1b.flashFond(jaune_sombre);
Affi_1a.setCouleurCadre(gris);
}
}
if ((SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV) )//WOBULATEUR
{
if (SW_saisie == md_saisie_dB_div)
{
//saisie OFFSET
setCouleur(couleur_gain, 0, 255, 255);
if (SW_mode == mode_WOBU_dB) { AffiV_01.affiche_texte_V(" Gain");}
if (SW_mode == mode_WOBU_mV) { AffiV_01.affiche_texte_V(" dB/div");}
AffiV_02.affiche_texte_V(" OFFSET");
Affi_11.setCouleurCadre(jaune_sombre); Affi_11.flashFond(jaune_sombre);
Affi_12.setCouleurCadre(jaune_sombre); Affi_12.flashFond(jaune_sombre);
Affi_9.setCouleurCadre(gris);
Affi_10.setCouleurCadre(gris);
}
if( SW_saisie == md_saisie_Hz_div)
{
//saisie PAS
AffiV_01.affiche_texte_V(" MARQUEUR");
AffiV_02.affiche_texte_V(" Hz/div");
Affi_10.setCouleurCadre(jaune_sombre); Affi_10.flashFond(jaune_sombre);
Affi_9.setCouleurCadre(jaune_sombre); Affi_9.flashFond(jaune_sombre);
Affi_11.setCouleurCadre(gris);
Affi_12.setCouleurCadre(gris);
}
if (SW_saisie == md_saisie_frq)
{
//saisie FREQ
AffiV_01.affiche_texte_V(" FREQ");
AffiV_02.affiche_texte_V(" DIGIT");
Affi_9.setCouleurCadre(gris);
Affi_10.setCouleurCadre(gris);
Affi_11.setCouleurCadre(gris);
Affi_12.setCouleurCadre(gris);
}
}
}
void scrute_switches()
{
//Le pin est tiré à 1 (VCC) par R tirage interne de l'ATmega; Il est forcé à 0 par la fermeture du contact.
SW_mode=2; // SW_mode -> 3 positions
if ((portPIN_switch0 & pin_switch0) == 0) {SW_mode = 1;}
if ((portPIN_switch1 & pin_switch1) == 0) {SW_mode = 3;}
SW_saisie=md_saisie_Hz_div; // SW_saisie -> 3 positions
if ((portPIN_switch3 & pin_switch3) == 0) {SW_saisie = md_saisie_dB_div;}
if ((portPIN_switch4 & pin_switch4) == 0) {SW_saisie = md_saisie_frq;}
SW_rapide=0;
if ((portPIN_switch2 & pin_switch2) == 0) {SW_rapide = 1;}
SW_polarite=0;
if ((portPIN_switch5 & pin_switch5) == 0) {SW_polarite = 1;}
if (SW_polarite == 0) {polarite = -1;} else {polarite = 1;} // la variable "polarite" est utilisée comme facteur dans le calcul de l'acquisition
SW_carte=Crt_AD9850;
if ((portPIN_switch6 & pin_switch6) == 0) {SW_carte = Crt_ADF4351;}
memo_switches = switches;
switches = 0;
switches |= SW_mode;
switches |= SW_saisie << 2;
switches |= SW_rapide << 4 ;
switches |= SW_polarite << 5 ;
switches |= (SW_carte-1) << 6 ;
if ((switches & 0b01000000) != (memo_switches & 0b01000000)) // si SW_carte a changé
{
stop = 1;
efface_ecran();
init_variables();
raffraichir=1;
afficher_freq = 1;
}
if ((switches & 0b01111111) != (memo_switches & 0b01111111))
{
trace_ecran();
envoyer_data = 1;
raffraichir=1;
afficher_freq = 1;
}
}
double recadre(double valeur_i)
{
double y2;
double y_min, y_max;
if (SW_mode == mode_WOBU_dB) // pour détecteur log
{
/**
- la réponse du détecteur log AD8318 = 25mV/dB
- l'ADC de l'ATmega convertit 2.56V -> 1024 pas (0..1023) soit 1024/2560mV = 0.4pas/mV (voir fonction InitADC() -> Internal 2.56V Voltage Reference)
- 1dB => 25mV => 25x0.4pas => 10pas
- echelle de la valeur lue = Ech = 10pas/dB
- le panel graphique fait 320-80 = 240px en Y
- ce panel graphique est divisé en 10 divisions qui font chacune 240/10 = 24 pixels
- en position 1dB/div le gain doit être 1dB => 10pasADC => 1divY => 24px
- gain(1dB/div) = G1 = 24/10 px/pasADC = 2.4
**/
if (SW_rapide == 0) { y_min=83; y_max =317;} else { y_min=101; y_max =299;}
y2 = 200 + (-1.0) * (params1.offset_y + (2.4 / dB_div) * polarite * valeur_i );
if (y2<y_min) {y2=y_min;}
if (y2>y_max) {y2=y_max;}
return y2;
}
if (SW_mode == mode_WOBU_mV) // pour détecteur linéaire
{
/**
- l'ADC de l'ATmega convertit 2.56V -> 1024 pas (0..1023) soit 1024/2560mV = 0.4pas/mV
- le panel graphique fait 320-80 = 240px en Y
- ce panel graphique est divisé en 10 divisions qui font chacune 240/10 = 24 pixels
- pour obtenir un affichage de 1mV/div soit 0.4pas/div soit 0.4pas/24pix le facteur de proportion = 24/0.4 = 60 pix/pas
**/
if (SW_rapide == 0) { y_min=83; y_max =317;} else { y_min=101; y_max =299;}
y2 = 200 + polarite * ( (params1.offset_y + (60.0 / mV_div) * valeur_i ) );
if (y2<y_min) {y2=y_min;}
if (y2>y_max) {y2=y_max;}
return y2;
}
}
void loop()
{
double Fd0, Fd1, Fmin, Fmax, increment_F;
// double Fcentrale;
double y_float;
uint16_t y, memo_y, y_repos, y2;
uint8_t i;
uint8_t SB;
uint8_t c;
raffraichir = 1;
afficher_freq = 1;
while(1)
{
scrute_switches();
//------------------------------------------------------------------------------------------------------------------
// GENERATEUR SIMPLE
//------------------------------------------------------------------------------------------------------------------
if (SW_mode == mode_GENE)
{
if(envoyer_data > 0)
{
envoyer_data = 0;
calcul_lambda_a();
calcul_lambda_b();
Fd0 = (double) params1.frequence_AD9850; // pour l'AD9850 - Fd0 = fréquence en 1/10 Hz c.a.d 10x fréquence en Hz
affiche_lambda_a();
Fd1 = params1.frequence_ADF4351 / 100.0; // pour l'ADF4351 - Fd1 = fréquence en MHz (avec decimales, c'est un réel (double))
affiche_lambda_b();
init_leds();
LED_b1.setEtat(1);
LED_b2.setEtat(1);
CarteAD9850.out_F(Fd0); // le paramètre = fréquence en 1/10 Hz c.a.d à 10x fréquence en Hz, ce qui permet une précision du 1/10 Hz
_delay_us(10);
Affi_1a.setCouleurTxt(bleu); //Affi_1a.setCouleurCadre(jaune_sombre);
SB=0 ; if (SW_carte == Crt_AD9850) {SB=1;}
Affi_1a.affiche_frequence_9(params1.frequence_AD9850, SB); // (avec de grands chiffres 7 segments)
CarteADF4351.setFreq(Fd1);
CarteADF4351.Write_All_Register();
_delay_us(10);
if ((PIN_ADF4351_A & pin_MUXOUT) == pin_MUXOUT) { LED_a.setEtat(1); } else { LED_a.setEtat(0);}
//affiche_params();
//affiche_valeurs_registres();
Affi_1b.setCouleurTxt(bleu); //Affi_1b.setCouleurCadre(jaune_sombre);
SB=0 ; if (SW_carte == Crt_ADF4351) {SB=1;}
c = params1.pos_curFreq_gene_ADF43;
Affi_1b.affiche_frequence_6(params1.frequence_ADF4351, 2, c, SB); // (avec de grands chiffres 7 segments)
save_params_to_EEPROM();
}
}
//------------------------------------------------------------------------------------------------------------------
// WOBULATEUR
//------------------------------------------------------------------------------------------------------------------
else // mode wobulation (SW_mode == mode_WOBU_dB) || (SW_mode == mode_WOBU_mV)
{
if (raffraichir == 1)
{
raffraichir=0;
if(SW_carte == Crt_AD9850)
{
Affi_1c.init(0, 0, 210, 78,"Fo AD9850");
Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(jaune_sombre);
}
if(SW_carte == Crt_ADF4351)
{
Affi_1c.init(0, 0, 210, 78,"Fo ADF4351");
Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(jaune_sombre);
}
init_afficheurs_wob();
save_params_to_EEPROM();
}
if (SW_rapide == 1) { efface_centre_graph();}
if (afficher_freq == 1)
{
afficher_freq=0;
if (SW_saisie == md_saisie_frq)
{
if(SW_carte == Crt_AD9850)
{
//Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(jaune_sombre);
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_5(params1.frequence_AD9850/10000, 3, c, 1); // surbrilllance 1 digit
}
if(SW_carte == Crt_ADF4351)
{
//Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(jaune_sombre);
c = params1.pos_curFreq_wobu_ADF43;
Affi_1c.affiche_frequence_6(params1.frequence_ADF4351, 2, c, 1); // surbrilllance 1 digit
}
}
else // modes saisie paramètres de wobulation (SW_saisie == md_saisie_Hz_div) ||(SW_saisie == md_saisie_dB_div)
{
if(SW_carte == Crt_AD9850)
{
Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(gris);
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_5(params1.frequence_AD9850/10000, 3, c, 1); // surbrilllance 1 digit
}
if(SW_carte == Crt_ADF4351)
{
Affi_1c.setCouleurTxt(bleu); Affi_1c.setCouleurCadre(gris);
c = params1.pos_curFreq_wobu_ADF43;
Affi_1c.affiche_frequence_6(params1.frequence_ADF4351, 2, c, 0); // pas de chiffre en surbrilllance
}
}
}
if(SW_carte == Crt_AD9850)
{
affiche_pas_DIV(1);
frq_centrale = params1.frequence_AD9850; // fréquence en 1/10 Hz c.a.d 10x fréquence en Hz
increment_F = 1e5 * kHz_div / 470.0;
Fmin = frq_centrale-235*increment_F;
Fmax = frq_centrale+235*increment_F;
F_mark =(Fmin + ((double) params1.pos_mark * increment_F))/1e4;
F_affi_min=Fmin/1e2;
if (F_affi_min < frq_min_AD98) {F_affi_min = frq_min_AD98;}
F_affi_max=Fmax/1e2;
if (F_affi_max > frq_max_AD98) {F_affi_max = frq_max_AD98;}
}
if(SW_carte == Crt_ADF4351)
{
affiche_pas_DIV(0);
//Fcentrale = params1.frequence_ADF4351 / 100.0;
increment_F = kHz_div / 470.0;
Fmin = params1.frequence_ADF4351-235*increment_F;
Fmax = params1.frequence_ADF4351+235*increment_F;
F_mark =(Fmin + ((double) params1.pos_mark * increment_F)) / 100.0;
F_affi_min=Fmin;
if (F_affi_min < frq_min_ADF43) {F_affi_min = frq_min_ADF43;}
F_affi_max=Fmax;
if (F_affi_max > frq_max_ADF43) {F_affi_max = frq_max_ADF43;}
}
// acquisition_data_WOB();
// y=valeur_lue;
// ******************************************
affiche_freq_marqueur();
if (SW_mode == mode_WOBU_dB) {Affi_11.affiche_valeur(dB_div, 2, "");}
if (SW_mode == mode_WOBU_mV) {affiche_V_div();}
Affi_12.affiche_valeur(params1.offset_y, 5, "");
// BOUCLE DE BALAYAGE - incrémente la fréquence et affiche le graphique en temps réel
// for (int n=0; n<470; n++)
uint8_t dn=1; if (SW_rapide == 1) {dn =5;}
int n=0; if (SW_rapide == 1) {n =100;}
uint16_t n_max =470; if (SW_rapide == 1) {n_max =350;}
stop=0;
while ((n<n_max) && (stop ==0)) // stop set à 1 par les INT0 et INT1
{
if(raffraichir==1)
{
raffraichir=0;
affiche_pas_DIV(0);
Affi_1c.setCouleurTxt(bleu);
if (SW_saisie == md_saisie_frq)
{
if (SW_carte == Crt_AD9850 )
{
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_6(params1.frequence_AD9850/1000, 4, c, 1); // (grands chiffres + surbrillance 1 digit)
}
if (SW_carte == Crt_ADF4351 )
{
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_6(params1.frequence_ADF4351, 2, c, 1); // (grands chiffres + surbrillance 1 digit)
}
}
else
{
if (SW_carte == Crt_AD9850 )
{
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_6(params1.frequence_AD9850/1000, 4, c, 0); // (grands chiffres, pas de surbrillance digit )
F_affi_min=Fmin;
if (F_affi_min < frq_min_AD98) {F_affi_min = frq_min_AD98;}
F_affi_max=Fmax;
if (F_affi_max > frq_max_AD98) {F_affi_max = frq_max_AD98;}
}
if (SW_carte == Crt_ADF4351 )
{
c = params1.pos_curFreq_wobu_AD98;
Affi_1c.affiche_frequence_6(params1.frequence_ADF4351, 2, c, 0); // (grands chiffres, pas de surbrillance digit )
F_affi_min=Fmin;
if (F_affi_min < frq_min_ADF43) {F_affi_min = frq_min_ADF43;}
F_affi_max=Fmax;
if (F_affi_max > frq_max_ADF43) {F_affi_max = frq_max_ADF43;}
}
}
affiche_pas_DIV(0);
affiche_freq_marqueur();
affi_min_max();
}
depassement =0;
// GENERATION DU SIGNAL
if (SW_carte == Crt_AD9850 )
{
Fd1 = (Fmin + n * increment_F);
if (Fd1 < frq_min_AD98) {Fd1 = frq_min_AD98; depassement =1;}
if (Fd1 > frq_max_AD98) {Fd1 = frq_max_AD98; depassement =1;}
//Fd1 = Fd1 / 10.0;
CarteAD9850.out_F(Fd1); // le paramètre = fréquence en 1/10 Hz c.a.d à 10x fréquence en Hz, ce qui permet une précision du 1/10 Hz
}
if (SW_carte == Crt_ADF4351 )
{
Fd1 = (Fmin + n * increment_F);
if (Fd1 < frq_min_ADF43) {Fd1 = frq_min_ADF43; depassement =1;}
if (Fd1 > frq_max_ADF43) {Fd1 = frq_max_ADF43; depassement =1;}
Fd1 = Fd1 / 100.0; // Fd1 en MHz (avec 2 décimales)
CarteADF4351.setFreq(Fd1);
}
_delay_ms(1);
acquisition_data_WOB();
memo_y=y;
y_float = recadre((float)valeur_lue); // règlage de offset et amplitude pour entrer dans le cadre d'affichage
y = (uint16_t)y_float;
if (y>317) {y=317;}
tableau_acq[n]=y; // mémorisation de la courbe (recadrée) en SRAM
if(SW_rapide == 0)
{
TFT480.setColor(255, 255, 255);
if(n<465) {TFT480.drawLine(n+2, y-3, n+2, y+3);} // petit tiret vertical pour faire joli (spot) et montrer l'avancement
if((n % 47)==0) { TFT480.setColor(60, 60, 60); } else { TFT480.setColor(0, 0, 0); }
if(n == 235) { TFT480.setColor(255, 100,100); }
if (n== params1.pos_mark) { TFT480.setColor(200, 0, 255); }
TFT480.drawLine(n, 81, n, 318); // efface toute une ligne verticale tout en redessinant le reticule V et le marqueur (en jouant sur les couleurs)
TFT480.setColor(100, 100, 100);
//quadrillage H
for (int i=1; i<10; i++)
{
y2= 81 + 24*i;
if (i==5) { TFT480.setColor(120, 120,120); } else { TFT480.setColor(60, 60, 60); }
TFT480.drawPixel(n, y2);
}
}
TFT480.setColor(0, 255, 0);
if (depassement == 0) // en fréquence
{
if(n>(20*dn)) {TFT480.drawLine(n-dn, memo_y, n, y);} // <=== trace le signal normal *****
}
else
{
TFT480.setColor(255, 0, 0);
TFT480.drawLine(n-1, 318, n, 318); // trace une ligne rouge H
TFT480.drawLine(n-1, 310, n, 310);
}
if ((n==80) || (n==460)) { affi_min_max(); }
n+=dn;
scrute_switches();
if ((switches & 0b00001111) != (memo_switches & 0b00001111)) { stop=1; }
}
// _delay_ms(1000); // pause pour pouvoir prendre des photos facilement;
}
}
}
/** ***********************************************************************************
CLASS AffiRect // affiche un nombre ou un petit texte dans un rectangle
***************************************************************************************/
// Constructeur
AffiRect::AffiRect()
{
}
void AffiRect::init(uint16_t x, uint16_t y, uint16_t dx, uint16_t dy, char txt_etiquette_i[12])
{
x0 = x;
y0 = y;
dx0 = dx;
dy0 = dy;
for (int i=0; i<12; i++) {txt_etiquette[i]=txt_etiquette_i[i];}
txt_etiquette[12]='\0'; // zero terminal
TFT480.setBackColor(0, 0, 0);
TFT480.setColor(10, 10, 5);
TFT480.setColor(Rcadre, Vcadre, Bcadre);
TFT480.drawRect(x0, y0+5, x0+dx0, y0+dy0);
traceCadre();
affi_etiquette();
}
void AffiRect::traceCadre()
{
TFT480.setColor(Rcadre, Vcadre, Bcadre);
TFT480.drawRect(x0, y0+5, x0+dx0, y0+dy0);
}
void AffiRect::affi_etiquette()
{
TFT480.setBackColor(0, 0, 0);
TFT480.setFont(BigFont);
TFT480.setColor(180,180,180); // couleur de l'étiquette
TFT480.print(txt_etiquette, x0, y0); // Etiquette
}
void AffiRect::setCouleurTxt(uint8_t *couleur_i)
{
Rtxt=couleur_i[0];
Vtxt=couleur_i[1];
Btxt=couleur_i[2];
}
void AffiRect::setCouleurCadre(uint8_t *couleur_i)
{
Rcadre=couleur_i[0];
Vcadre=couleur_i[1];
Bcadre=couleur_i[2];
TFT480.setColor(Rcadre, Vcadre, Bcadre);
TFT480.drawRect(x0, y0+5, x0+dx0, y0+dy0);
TFT480.setBackColor(0, 0, 0);
TFT480.setFont(BigFont);
TFT480.setColor(180,180,180); // couleur de l'étiquette
TFT480.print(txt_etiquette, x0, y0); // Etiquette (pour écrire volaontairement par dessus le cadre))
}
void AffiRect::setCouleurFond(uint8_t *couleur_i)
{
Rfond=couleur_i[0];
Vfond=couleur_i[1];
Bfond=couleur_i[2];
}
void AffiRect::flashFond(uint8_t *couleur_i)
{
Rfond=couleur_i[0];
Vfond=couleur_i[1];
Bfond=couleur_i[2];
TFT480.setColor(Rfond, Vfond, Bfond);
TFT480.fillRect(x0, y0, x0+dx0, y0+dy0);
_delay_ms(10);
TFT480.setColor(10, 10, 5);
TFT480.fillRect(x0, y0, x0+dx0, y0+dy0);
traceCadre();
affi_etiquette();
}
void AffiRect::affiche_frequence_5(uint32_t F_i, uint8_t nb_dec_i, uint8_t pos_cur, uint8_t SB_i) // sur 5 digits ; SB = surbrillance 1 digit
{
uint16_t x_7seg;
uint16_t y_7seg;
uint8_t p2;
x_7seg = x0+10;
y_7seg = y0+20;
TFT480.setBackColor(0, 0, 0);
TFT_aff_nb_form3b (F_i, 5, nb_dec_i, pos_cur, Rtxt, Vtxt, Btxt, SB_i, x_7seg, y_7seg); // 5 chiffres significatifs
}
void AffiRect::affiche_frequence_6(uint32_t F_i, uint8_t nb_dec_i, uint8_t pos_cur, uint8_t SB_i) // sur 6 digits ; SB = surbrillance 1 digit
{
uint16_t x_7seg;
uint16_t y_7seg;
uint8_t p2;
x_7seg = x0+10;
y_7seg = y0+20;
TFT480.setBackColor(0, 0, 0);
TFT_aff_nb_form3b (F_i, 6, nb_dec_i, pos_cur, Rtxt, Vtxt, Btxt, SB_i, x_7seg, y_7seg); // 6 chiffres significatifs
}
void AffiRect::affiche_frequence_9(uint32_t F_i, uint8_t SB_i) // sur 9 digits (8 + 1 décimale); SB_i = surbrillance 1 digit
{
uint16_t x_7seg;
uint16_t y_7seg;
uint8_t p2;
x_7seg = x0+10;
y_7seg = y0+20;
p2 = params1.pos_curFreq_gene_AD98;
TFT480.setBackColor(0, 0, 0);
TFT_aff_nb_form3 (F_i, 9, p2, Rtxt, Vtxt, Btxt, SB_i, x_7seg, y_7seg);
}
void AffiRect::affiche_valeur(uint32_t valeur, uint8_t nb_chiffres, char txt_unite_i[3])
{
for (int i=0; i<3; i++) {txt_unite[i]=txt_unite_i[i];}
txt_unite[3]='\0'; // zero terminal
TFT480.setBackColor(0, 0, 0);
TFT480.setColor(Rtxt, Vtxt, Btxt);
TFT480.setFont(BigFont);
TFT480.printNumI(valeur, x0+5,y0+18, nb_chiffres, ' ');
TFT480.setFont(BigFont);
TFT480.print(txt_unite, x0+80,y0+18); // ex : mm, kHz, etc...
}
void AffiRect::affiche_float(float valeur, uint8_t nb_chiffres, uint8_t nb_dec, char txt_unite_i[3])
{
for (int i=0; i<3; i++) {txt_unite[i]=txt_unite_i[i];}
txt_unite[3]='\0'; // zero terminal
TFT480.setBackColor(0, 0, 0);
TFT480.setColor(Rtxt, Vtxt, Btxt);
TFT480.setFont(BigFont);
//RAPPEL: void printNumF(double num, byte dec, int x, int y, char divider='.', int length=0, char filler=' ');
TFT480.printNumF(valeur, nb_dec, x0+5,y0+18, ',', nb_chiffres, ' ');
TFT480.setFont(BigFont);
TFT480.print(txt_unite, x0+82,y0+18); // ex : mm, kHz, etc...
}
void AffiRect::affiche_HEXA(uint32_t valeur)
{
// affiche un nombre en representation hexadécimale
// 16 nb_signes hexa max
uint8_t r;
uint8_t i;
char tbl[9];
char signes[17] = "0123456789ABCDEF";