Lichti01
27.05.2018, 21:34
HI zusammen,
ich habe ein Problem mit den Timer0 und Timer1 des ATtiny2313A.
Vorab mal der Code um den es geht.
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#define LED1 1
uint8_t i;
#define a 50 //Zeit in ms/10 für Blinkfrequenz der LED1
uint16_t b;
//variablen für entprellung
#define TASTERPORT PIND
#define TASTERBIT PIND3
//Entprellung
char taster(void)
{
static unsigned char zustand;
char rw = 0;
if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gedrueckt (steigende Flanke)
{
zustand = 1;
rw = 1;
}
else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gehalten
{
zustand = 2;
rw = 0;
}
else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT))) //Taster wird losgelassen (fallende Flanke)
{
zustand = 3;
rw = 0;
}
else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT))) //Taster losgelassen
{
zustand = 0;
rw = 0;
}
else if (((zustand == 1) || (zustand == 2)) && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gehalten
{
zustand = 2;
rw = 0;
}
return rw;
}
int main(void)
{
DDRB = 0b00000010;
//Einstellung Interrupt
PORTD = 0b00000100;
GIMSK = (1<<INT0);
MCUCR = (1<<ISC01); //The falling edge of INT0 generates an Interrupt
i=0;
b=2*a;
//Globale interrupts aktivieren
sei();
while (1)
{
if (i==0)
{
PORTB &=~ (1<<LED1);
}
if ((i>=1) && (i<=a))
{
PORTB |= (1<<LED1);
}
if ((i>=1) && (i>a) && (i<=b))
{
PORTB &=~ (1<<LED1);
if (i==b)
{
i=1;
}
}
}
}
ISR(INT0_vect)
{
_delay_ms(50);
TIMSK ^= (1<<OCIE0A); //Ineterrupt aktivieren
TCCR0A ^= (1<<WGM01); //CTC-Mode aktivieren
OCR0A ^= 155; //Interrupt auslösen bei Zählerstand (10ms)
TCCR0B ^= ((1<<CS00) | (1<<CS01)); //Timer starten mit Prescaler 64
if (i==0)
{
i=1;
}
if (i>=1)
{
i=0;
}
}
ISR(TIMER0_COMPA_vect)
{
i++;
}
Ich habe den Timer0 (8-bit-Timer) im CTC-Modus mit dem Prescaler64 laufen. Wenn der Timer bis 155 gezählt hat sind 10ms vergangen und ein Interrupt wird ausgelöst. Mit dem Timer wird der Blinckintervall einer LED gesteuert. Das funktioniert auch einwandfrei. Wenn ich aber nun den Timer1 (16-bit-Timer) genauso einstelle blinkt die LED allerdings nur sehr sehr langsam.
Was mir auch noch aufgefallen ist wenn ich den 8-bit-Timer mit dem Prescaler8 laufen lasse und bis 125 zähle sollte 1ms vergangen sein. Variable a setzte ich dann auf 500 da ja 500ms/1ms= 500 ist. Da blinkt meine LED auch nicht wie sie soll.
Wenn ich das mit den Timern und Presaclern richtig verstanden habe müsste der Blinckrythmus beim 16-Bit-Timer doch genau so sein wie beim 8-Bit-Timer. Bzw. wenn ich nur bis 1ms zähle müsste es doch auch übereinstimmen.
Errechnet habe ich den Zählerstand mit folgender Formel:
Systemtakt[Hz]/Prescaler/1000*Zeit[ms]
Hoffe ich habe mein Problem verständlich geschildert.
Danke schon einmal im voraus
Gruß Lichti01
ich habe ein Problem mit den Timer0 und Timer1 des ATtiny2313A.
Vorab mal der Code um den es geht.
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#define LED1 1
uint8_t i;
#define a 50 //Zeit in ms/10 für Blinkfrequenz der LED1
uint16_t b;
//variablen für entprellung
#define TASTERPORT PIND
#define TASTERBIT PIND3
//Entprellung
char taster(void)
{
static unsigned char zustand;
char rw = 0;
if(zustand == 0 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gedrueckt (steigende Flanke)
{
zustand = 1;
rw = 1;
}
else if (zustand == 1 && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gehalten
{
zustand = 2;
rw = 0;
}
else if (zustand == 2 && (TASTERPORT & (1<<TASTERBIT))) //Taster wird losgelassen (fallende Flanke)
{
zustand = 3;
rw = 0;
}
else if (zustand == 3 && (TASTERPORT & (1<<TASTERBIT))) //Taster losgelassen
{
zustand = 0;
rw = 0;
}
else if (((zustand == 1) || (zustand == 2)) && !(TASTERPORT & (1<<TASTERBIT))) //Taster wird gehalten
{
zustand = 2;
rw = 0;
}
return rw;
}
int main(void)
{
DDRB = 0b00000010;
//Einstellung Interrupt
PORTD = 0b00000100;
GIMSK = (1<<INT0);
MCUCR = (1<<ISC01); //The falling edge of INT0 generates an Interrupt
i=0;
b=2*a;
//Globale interrupts aktivieren
sei();
while (1)
{
if (i==0)
{
PORTB &=~ (1<<LED1);
}
if ((i>=1) && (i<=a))
{
PORTB |= (1<<LED1);
}
if ((i>=1) && (i>a) && (i<=b))
{
PORTB &=~ (1<<LED1);
if (i==b)
{
i=1;
}
}
}
}
ISR(INT0_vect)
{
_delay_ms(50);
TIMSK ^= (1<<OCIE0A); //Ineterrupt aktivieren
TCCR0A ^= (1<<WGM01); //CTC-Mode aktivieren
OCR0A ^= 155; //Interrupt auslösen bei Zählerstand (10ms)
TCCR0B ^= ((1<<CS00) | (1<<CS01)); //Timer starten mit Prescaler 64
if (i==0)
{
i=1;
}
if (i>=1)
{
i=0;
}
}
ISR(TIMER0_COMPA_vect)
{
i++;
}
Ich habe den Timer0 (8-bit-Timer) im CTC-Modus mit dem Prescaler64 laufen. Wenn der Timer bis 155 gezählt hat sind 10ms vergangen und ein Interrupt wird ausgelöst. Mit dem Timer wird der Blinckintervall einer LED gesteuert. Das funktioniert auch einwandfrei. Wenn ich aber nun den Timer1 (16-bit-Timer) genauso einstelle blinkt die LED allerdings nur sehr sehr langsam.
Was mir auch noch aufgefallen ist wenn ich den 8-bit-Timer mit dem Prescaler8 laufen lasse und bis 125 zähle sollte 1ms vergangen sein. Variable a setzte ich dann auf 500 da ja 500ms/1ms= 500 ist. Da blinkt meine LED auch nicht wie sie soll.
Wenn ich das mit den Timern und Presaclern richtig verstanden habe müsste der Blinckrythmus beim 16-Bit-Timer doch genau so sein wie beim 8-Bit-Timer. Bzw. wenn ich nur bis 1ms zähle müsste es doch auch übereinstimmen.
Errechnet habe ich den Zählerstand mit folgender Formel:
Systemtakt[Hz]/Prescaler/1000*Zeit[ms]
Hoffe ich habe mein Problem verständlich geschildert.
Danke schon einmal im voraus
Gruß Lichti01