/*==============================================================================
par Silicium628
derniere mise à jour 18 aout 2014
================================================================================
ATmega8
Generateur HF 200MHz - DDS AD9951 et ATmega8
-Affichage LCD 2 x 16 caractères
================================================================================
*/
#define F_CPU 16000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "dm_lcd.c" // l'attribution des pins/ports pour le LCD (et le type de LCD) est faite dans le fichier "dm_lcd.h"
#define bouton_L 0b00000001
// #define bouton_U 0b00000010
// #define bouton_D 0b00000100
#define bouton_R 0b00001000
char * version = "1.0";
uint16_t valeur16b;
uint16_t frequence;
uint8_t pos;
uint8_t pos_curseur;
uint8_t etat;
uint16_t compteur1;
void init_ports (void) // ports perso
// 0 = entree, 1=sortie ; les 1 sur les pins en entrees activent les R de Pull Up (tirage à VCC)
{
DDRB |= 0b11111111; // portB[1] = sortie (OC1A = sortie PWM 16 bits du timer1)
PORTB = 0b00000000;
DDRC = 0b11111111;
PORTC = 0b00000000;
DDRD = 0b11111010; // portD[0] entrée codeur_ROT ; portD[2] entee INT0
PORTD = 0b00000101;
}
void InitADC (void)
{
ADCSRA = _BV(ADEN) | _BV(ADPS2); // Activate ADC with Prescaler 16 --> 1Mhz/16 = 62.5kHz
ADMUX |= 0b11000101; //Bit 7:6 – REFS1:0: ADC Reference Selection Bits =11 -> Internal 2.56V Voltage Reference with external capacitor at AREF pin ; Bits 0:3 - Analog Channel Selection Bits
// ici Select pin ADC5 using MUX avec ref tension interne = 2.56V
}
void InitINTs (void)
{
GICR |= 0b01000000; // gere les INTs - bit9 ->INT0 request - voir page 67 du pdf
MCUCR |= 0b00000010; // The falling edge of INT0 generates an interrupt request. p:67 du pdf
}
void init_variables(void)
{
frequence = 1000;
}
/************************
// traitement du codeur_rot()
// codeur incrémental code Gray avec en plus fonction bouton poussoir
// le codeur rotatif utilisé est toujours à 11 en position stable
// dans le sens CW il fait 11->01->00->10->11
// et par conséquent dans le sens CCW il fait 11->10->00->01->11
// 11
// 01
// 00
// 10
// 11
// il suffit de connecter un bit sur le pin INT0 (PD2) et de déclencher l'INT sur front descendant (passage de 0 à 1)
// cette INT lira alors l'état de l'autre bit (connecté à PD0 par exemple). Cet état diffère suivant le sens de rotation
*************************/
ISR(BADISR_vect)
{
// évite de planter si une int est enable et pas de procedure associée écrite (ce qui fait reseter l'ATmega)
}
ISR (INT0_vect)
{
//interruption sur front descendant sur l'entree Int0
// declenchee par la rotation du codeur_ROT
etat = PIND & 0b00000001;
if (etat == 0) { frequence ++;} else {frequence--;}
}
void lcd_gotoxy_clrEOL (int x, int y)
// place le curseur en x,y et efface jusqu'a la fin de la ligne
{
lcd_gotoxy(x, y);
uint8_t i;
for (i=x; i<20; i++)
{ lcd_puts(" "); }
lcd_gotoxy(x, y);
}
void lcd_aff_nb (uint16_t valeur, uint8_t nb_chiffres, uint8_t nb_decimales)
{
//affiche un nombre en representation decimale
unsigned char r ;
char tbl[7];
uint8_t i;
for (i=1; i<=nb_chiffres; i++)
{
r=48 + valeur % 10; // modulo (reste de la division)
valeur /= 10; // quotient
tbl[i]=r;
}
for (i=1; i<=nb_chiffres; i++)
{
if (i== (nb_chiffres - nb_decimales +1) ) { lcd_puts("."); }
lcd_putc(tbl[nb_chiffres +1 -i]);
}
}
void lcd_aff_bin (unsigned long int valeur, int nb_digits)
{
//affiche un nombre en representation binaire
// 16 bits max
unsigned char r ;
char tbl[17];
uint8_t i;
for (i=1; i<=nb_digits; i++)
{
r= 48 + valeur % 2; // modulo (reste de la division)
valeur /= 2; // quotient
tbl[i]=r;
};
for (i=1; i<=nb_digits; i++)
{
lcd_putc(tbl[nb_digits +1 -i]);
}
}
void affiche_frequence()
{
lcd_gotoxy_clrEOL (0, 1);
lcd_aff_nb (frequence, 5, 0);
}
/*
void test_codeur_rot()
{
// pour test des états (diffèrent suivant modèles) du codeur rotatif pas à pas code gray
// le mien est toujours à 11 en position stable
// dans le sens CW il fait 11->01->00->10->11
// et par conséquent dans le sens CCW il fait 11->10->00->01->11
lcd_clrscr();
while (1)
{
code_rot = PIND & 0b00000011;
lcd_gotoxy(0,0);
lcd_aff_bin (code_rot, 2);
_delay_ms(10);
}
}
*/
int main (void)
{
init_variables();
init_ports();
InitINTs();
// InitADC();
lcd_init(LCD_DISP_ON_CURSOR);
lcd_clrscr();
lcd_home();
lcd_puts("GeneHF AD9951");
lcd_gotoxy(0,1);
lcd_puts("version ");
lcd_puts(version);
_delay_ms(1000);
//lcd_clrscr();
sei();
while(1)
{
compteur1++;
if (compteur1 >= 10000)
{
affiche_frequence();
compteur1=0;
}
_delay_us(10);
}
}