Dobrý den,
Nedávno se mi do rukou dostal JTAG debuger a zjistil jsem, že hodnoty z ADC jsou správné. Asi tedy bude problém ve 595. Předem děkuji za rady.
/*
* Minutka.c
*
* Created: 17. 4. 2015 15:08:06
* Author: Petr Liška
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>
//definice portů displeje na portu C
#define MR PC3
#define SHCP PC4
#define STCP PC5
#define OE PC6
#define DS_1 PC2
#define DS_2 PC7
#define tlacitko PD2
#define potenciometer PA0
#define piezo PD3
char vypisovane_cislo_desitky, vypisovane_cislo_jednotky;
volatile char citac = 0;
volatile char adc = 0;
volatile char sviti = 0;
volatile char odpocitavani = 0;
volatile char citac_2 = 0;
char cisla] = {
//hgfedcba
0b00111111, //0
0b00000110, //1
0b01011011, //2
0b01001111, //3
0b01100110, //4
0b01101101, //5
0b01111101, //6
0b00000111, //7
0b01111111, //8
0b01101111 //9
};
ISR (TIMER0_OVF_vect){ //přerušní při přetečení časovače 0
// 2*262,144 = 524,288ms
if(citac_2 == 2){
citac_2=0;
sviti ^= 1;
}
citac_2++;
}
ISR (TIMER1_OVF_vect){ //přerušní při přetečení časovače 1
TCNT1 = 61630; //nastavenie počáteční hodnoty počítadla
citac++;
}
ISR (INT0_vect) { //přerušení při stisku tlačítka (doběžná hrana)
odpocitavani ^= 1;
}
ISR (ADC_vect)
{
adc = (char)ADCH / 2;
}
void init(void)
{
OSCCAL = 0b10101100; // nastavení kalibrační konstanty
//Nastavení vstupních a výstupních pinů
DDRA = 0x00;
DDRB = 0x00;
DDRC = 0xFF;
DDRD = 0xFF;
DDRD &= ~(1 << tlacitko);
//nastavení pull-up rezistoru
PORTD |= (1 << tlacitko);
//vypnutí pieza
PORTD &= ~(1 << piezo);
//595
PORTC |= (1 << MR); //vypnutí master reset
PORTC &= ~(1 << OE); //povolení výstupu na 595
//počítání minut
TIMSK |= (1 << TOIE1); //prerušení při přetečení TCNT1
//ADC
ADMUX |= (1 << REFS0) | (1 << ADLAR);
ADCSRA |= (1 << ADEN) | (1 << ADIF) | (1<<ADATE) | (1<<ADIE) | (1 <<ADPS1) | (1 <<ADPS2) | (1 << ADSC);
//blikání led
TIMSK |= (1 << TOIE0); //prerušenie pri pretečení TCNT0
//ext. přerušení
GICR |= (1 << INT0); //povolení prerušení od INT0
MCUCR |= (1 << ISC01);
sei(); //povolení globálního přerušení
}
void pipani(void) //spouští piezo
{
PORTD |= (1 << piezo);
_delay_ms(200);
PORTD &= ~(1 << piezo);
_delay_ms(200);
}
void vysli_595(void)
{
ADCSRA &= ~(1 << ADEN); // vypnutí AD převodníku
PORTC &= ~(1 << STCP);
for(int i = 0; i != 8; i++)
{
PORTC &= ~(1 << SHCP);
if(vypisovane_cislo_desitky & 0b10000000) //zapis 1 bitu na místo desítek
PORTC &= ~(1 << DS_1);
else
PORTC |= (1 << DS_1);
if(vypisovane_cislo_jednotky & 0b10000000) //zápis 1 bitu na místo jednotek
PORTC &= ~(1 << DS_2);
else
PORTC |= (1 << DS_2);
PORTC |= (1 << SHCP); //nástupná hrana na SHCP
vypisovane_cislo_jednotky <<= 1;
vypisovane_cislo_desitky <<= 1;
}
PORTC |= (1 << STCP); //nástupná hrana na STCP
ADCSRA |= (1 << ADEN) | (1 << ADSC); //zapnutí AD převodníku
}
void prevod_cisla(char cislo) //převádí na desítky a jednotky, zjištuje zda-li se má rozsvítit tečka
{
unsigned char jednotky;
unsigned char desitky;
jednotky = cislo % 10; //zbytek po dělení 10
desitky = cislo / 10; //celoočíselné dělení
vypisovane_cislo_desitky = cisla[desitky];
if(sviti) //pokud se má tečka rozsvítit
vypisovane_cislo_desitky |= (1 << 7); //zmněň bit tečky
else
vypisovane_cislo_desitky &= ~(1 << 7); //zmněň bit tečky
vypisovane_cislo_jednotky = cisla[jednotky];
vysli_595(); //výpis na displej
return;
}
void citani(void) //odpocitava dokud nedojde ke konecné hodnotě
{
while (odpocitavani)
{
if(citac == 60) //pokud uběhla minuta
{
adc--;
citac = 0;
}
prevod_cisla(adc); //převod čísla na desítky a jednotky
if(adc == 0) //pokud čas vypršel
{
while (odpocitavani) //tlačítko není zmáčknuto
{
pipani(); //pípání pieza
}
break; //konec cyklu
}
}
}
void init_citani(void)
{
citac = 0;
ADCSRA &= ~(1 << ADEN); // vypnutí AD převodníku
TCCR1B |= (1 << CS12); //předdelička 256 (32us) zapnutí odpočítávání
TCCR0 |= (1 << CS02) | (1 << CS00); //preddelicka /1024 (1,024ms) zapnutí blikání
citani(); //spouští odpočítávání
TCCR0 &= ~(1 << CS02) | (1 << CS00); // vypnutí blikání
TCCR1B &= ~(1 << CS12); // vypnutí odpočítávání
sviti = 0; //zajistí aby tečka nesvítila
ADCSRA |= (1 << ADEN) | (1 << ADSC); //zapnutí AD převodníku
}
int main(void)
{
init(); //inicializuje procesor(porty,přerušení atd.)
while(1)
{
if (adc > 99) //zajištění aby číslo nemělo více než 2 cifry
adc = 99;
if(odpocitavani) //zjištění zda-li je tlačítko zmáčnuto
{
init_citani(); //inicializuje odpočítavací funkci, která poté volá funkci pro odpočítávání
}
prevod_cisla(adc); //převod čísla na desítky a jednotky a následný výpis na displej
_delay_ms(10);
}
return 0;
}