1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <avr/io.h>
#include "u8g.h"
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <stdio.h>
#define bit_get(p,m) ((p) & (m))
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_flip(p,m) ((p) ^= (m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define LONGBIT(x) ((unsigned long)0x00000001 << (x))
u8g_t Ecran;
#define FREQ_ECH 700UL // fréquence à la quelle on veut mesurer
#define NB_ECH 14 // nombre d'échantillons à mesurer
uint16_t TC1_VAL = (65535UL - F_CPU / FREQ_ECH); // valeur pour Timer 1 pour la mesure à la bonne fréquence
volatile uint8_t nb_mesure = 0; // nb de mesure prise **** en volatile pour eviter bug compilateur ****
uint8_t data[NB_ECH]; //__attribute__((section (".eeprom"))); // valeurs mesurées
void adc_init()
{
// AREF = AVcc
ADMUX = (1<<REFS0)|(1<<ADLAR);
// ADC Enable and prescaler of 16
ADCSRA = (1<<ADEN)|(1<<ADPS2);
}
uint8_t adc_read(uint8_t ch) // mesure sur 8 bits
{
// select the corresponding channel 0~7
// ANDing with ’7? will always keep the value
// of ‘ch’ between 0 and 7
ch &= 0b00000111; // AND operation with 7
ADMUX = (ADMUX & 0xF8)|ch;
// start single convertion
// write ’1? to ADSC
ADCSRA |= (1<<ADSC);
// wait for conversion to complete
// ADSC becomes ’0? again
// till then, run loop continuously
while(ADCSRA & (1<<ADSC));
return (ADCH);
}
ISR(TIMER1_OVF_vect)
{
TCNT1 = TC1_VAL; // recharge le compteur
data[nb_mesure] = adc_read(0); // enregistre la mesure
nb_mesure++; // incrémente le compteur de mesure
}
ISR(INT0_vect)
{
TCNT1 = 0xFFFE; // charge le compteur à une valeur proche pour la mesure
TCCR1B = _BV(CS10); // active le comptage a une fréquence horloge = F_CPU
}
int main(void)
{
uint8_t i = 0;
for (i = 0; i < NB_ECH; i++) data[i] = 0;
DDRB = _BV(PB1);
PORTB |= _BV(PB1); //allume l'écran
PORTD = 0b00000000; // config du port D
DDRD = ~(1<<PD2); // PORTD en sortie sauf PD2 où se trouve INT0
GICR = 1<<INT0; // Active INT0
MCUCR = 1<<ISC01 | 1<<ISC00; // Trigger INT0 sur front montant
TCCR1A = 0;
TCCR1B = 0; // bloque le comptage a une fréquence horloge = 0
TIMSK = _BV(TOIE1); // autorise l'interruption d'overflow
TCNT1 = 0; // met le competur à 0
u8g_InitSPI(&Ecran, &u8g_dev_st7920_128x64_sw_spi,PN(1,7),PN(1,5), PN(1,0), U8G_PIN_NONE, U8G_PIN_NONE);
// init écran GLCD
adc_init(); // init du convertisseur analogique / numérique
sei(); // active les interruptions
while(1)
{ // boucle d'attente
while (nb_mesure >= NB_ECH) //si j'ai fait assez de mesure ...
{
cli(); // bloque les IT
PORTD = 0; // eteint la LED indicatrice ce mesure
u8g_FirstPage(&Ecran);
do {
for (i = 0; i < NB_ECH; i++)
{
u8g_DrawLine(&Ecran, 4*i, data[i]>>2,4*(i+1), data[i+1]>>2);
}
} while( u8g_NextPage(&Ecran) );
TCCR1B = 0; // desactive le timer 1 : prescaler = 0
//GICR = 1<<INT0; // réactive l'interruption 0
nb_mesure = 0; // réinitialise les mesures
PORTD |= 1<<PD3;
sei(); // activation des interruptions
}
}
} |
Partager