Witam serdecznie.
Piszę program, w którym muszę zliczać przychodzące impulsy z licznika energetycznego do procka. Aby nie zliczać impulsów pochodzących od drgań styków wymyśliłam takie rozwiązanie.
Jeśli na INT0 przyjedzie zbocze opadające, włącz licznik T0. Gdy licznik przepełni się- minie 32ms i w tym miejscu będzie poziom niski na pinie, to atmega uzna impuls jako dobry. Rozwiązanie to działa.
Licznik T2 odlicza mi 1 sekundę(wysyłam na RS komputera co 5 sekund ilość zliczonych impulsów). T2 w trybie asynchronicznym, kwarc 32, 768Hz.
Problem tkwi w tym, że jeśli włączę licznik T2 to impulsy nie są naliczane, nie wchodzi w przerwanie od T0 lub INT0. Nie wiem jak z tym problemem sobie poradzić. Proszę o pomoc. Jestem początkująca:)
Piszę program, w którym muszę zliczać przychodzące impulsy z licznika energetycznego do procka. Aby nie zliczać impulsów pochodzących od drgań styków wymyśliłam takie rozwiązanie.
Jeśli na INT0 przyjedzie zbocze opadające, włącz licznik T0. Gdy licznik przepełni się- minie 32ms i w tym miejscu będzie poziom niski na pinie, to atmega uzna impuls jako dobry. Rozwiązanie to działa.
Licznik T2 odlicza mi 1 sekundę(wysyłam na RS komputera co 5 sekund ilość zliczonych impulsów). T2 w trybie asynchronicznym, kwarc 32, 768Hz.
Problem tkwi w tym, że jeśli włączę licznik T2 to impulsy nie są naliczane, nie wchodzi w przerwanie od T0 lub INT0. Nie wiem jak z tym problemem sobie poradzić. Proszę o pomoc. Jestem początkująca:)
#define F_CPU 4000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#define UART_BAUD 9600 //prędkość transmisji
#define UART_CONST (F_CPU/(16ul*UART_BAUD)-1)
unsigned char x=0;
volatile unsigned char copiec=0;
volatile unsigned char impuls=0;
volatile unsigned char i=0, sekunda=0;
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) ); /* Wait for empty transmit buffer */
UDR = data; /* Put data into buffer, sends the data */
}
unsigned char USART_Receive( void )
{
while ( !(UCSRA & (1<<RXC)) ); /* Wait for data to be received */
return UDR; /* Get and return received data from buffer */
}
void USART_Init( unsigned int ubrr )
{
UBRRH = (unsigned char)(ubrr>>8); /* Set baud rate */
UBRRL = (unsigned char)ubrr;
UCSRB = (1<<RXEN)|(1<<TXEN); /* Enable Receiver and Transmitter */
UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); /* Set frame format: 8data, 2stop bit */
}
SIGNAL(SIG_INTERRUPT0)
{
TCCR0 = (0<<CS00)| (0<<CS01) | (1<<CS02); //wlacz t0
}
ISR(TIMER0_OVF_vect){ //przerwanie co 16 ms
i++;
if (i==2){ //zeby bylo przerwanie co 32ms
i=0;
if (bit_is_clear(PIND,2)){
PORTD ^=_BV(7); //dioda
impuls++;
TCCR0 =0; //wylacz T0
}
}
}
ISR (TIMER2_OVF_vect){ //co 1s
sekunda++;
if (sekunda==5 && copiec==1){
konwertuj_imp(impuls); //co 5 sekund transmisja na rs ilosc impulsow
napisz(" "); //2 spacje
sekunda=0;
PORTD ^=_BV(7); //dioda
}
}
int main(void){
DDRD=0b10000000; //dioda PD.7 licznik PD.2
PORTD=0b10000100;//
//ustawienia TIMER0 ->co 16 ms
TCCR0 = (0<<CS00)| (0<<CS01) | (1<<CS02); // preskaler fclk/256
TCNT0 = 0; //wartosc poczatkowa 16ms
//ustawienia TIMER2 ->co 1 s
ASSR |= _BV(AS2); // TC2 z taktowania zegarem CPU na generator asynchroniczny
TCCR2 = (1<<CS20)| (0<<CS21) | (1<<CS22); // preskaler fclk/128
TCNT2 = 0; //wartosc poczatkowa 32768/128/256=1hz, czyli co 1s
sei();// globalne odblokowanie przerwań
GIMSK=0b01000000; // Port INT0 is set (one)
MCUCR = 0b00000010; // The rising edge of INT0 generates
// an interrupt request.
USART_Init(UART_CONST);
TIMSK = 1<<TOIE0; // włącz przerwania z TC0
while (1){
x=USART_Receive();
if (x=='s'){
sekunda=0;
copiec=1;
napisz("\rIlosc impulsow aktualizowana co 5 sekund:\r");
TIMSK = 1<<TOIE2; //wlacz t2 czyli wysylaj co 5 s stan impulsow
}
}
}
