: sobota 30 mar 2013, 15:22
Pyra, co chcesz osiągnąć w tym programie? Od tego zacznijmy.
...czyli forum miłośników światełek... ;-)
https://www.swiatelka.pl/
w IOTN26.H mam:Pyra pisze:Jak wspomniałem, pprzypisanie na sztywno wektora 7, kompiluje bez błędów, ale program nie działa...
Kod: Zaznacz cały
/* Timer/Counter1 Overflow */
#define TIMER1_OVF1_vect_num 5
#define TIMER1_OVF1_vect _VECTOR(5)
#define SIG_OVERFLOW1 _VECTOR(5)
/* Timer/Counter0 Overflow */
#define TIMER0_OVF0_vect_num 6
#define TIMER0_OVF0_vect _VECTOR(6)
#define SIG_OVERFLOW0 _VECTOR(6)
/* USI Start */
#define USI_STRT_vect_num 7
#define USI_STRT_vect _VECTOR(7)
#define SIG_USI_START _VECTOR(7)
Kod: Zaznacz cały
//ATTiny 26 regulator napięcia PWM z mostkiem H do kolejki
// PA0-ADC0 nastawa - potencjometr
// PA1-ADC1 pomiar prądu
// PA4 START rozruch
// PA5 STOP zatrzymanie
// PA6 do przodu
// PA7 do tyłu
// PB1 PWM przód
// PB3 przód
// PB2 PWM tył
// PB3 tył
// PB4 przeciążenie
// PB5 prędkość OK
#include <avr/io.h>
//#include <util/delay.h>
#include <avr/interrupt.h>
unsigned int short nastawnik;
unsigned int short jazda=0;
unsigned int short predkosc;
void przyciski() //deklaracja funkcji sprawdzania przycisków
{
if (((PINA &_BV(PA6))==0) && OCR1A<20)
{
PORTB&=(0<<PB2);
// _delay_ms(1);
TCCR1A=0b00100011; //PWMa
PORTB|=(1<<PB0);
}
if (((PINA &_BV(PA7))==0) && OCR1A<20)
{
PORTB&=(0<<PB0);
// _delay_ms(1);
TCCR1A=0b10000011; //PWMb
PORTB|=(1<<PB2);
}
if ((PINA & _BV(PA4))==0)
{
jazda=0;
}
if ((PINA & _BV(PA5))==0)
{
jazda=1;
}
}
void nastawa() //pomiar napięcia sterującego
{
nastawnik=ADCH;
}
void timer0init()
{
TIMSK|=_BV(TOIE0);
TCCR0=0b00000101;
TCNT0=200;
}
ISR(TIMER0_OVF_vect)
//ISR(_VECTOR(7))
//{
// predkosc=OCR1A;
// if ((jazda>0) && (OCR1A<nastawnik))
// {
// predkosc++;
// }
// if ((jazda==0) && (OCR1A>20))
// {
// predkosc++;
// }
// OCR1A=predkosc;
// OCR1B=predkosc;
// TCNT0=200;
//}
{
static uint8_t LED=0b010;
LED^=0b110;
uint8_t tmp=PORTB & 0b11111001;
PORTB=(tmp | LED);
}
int main()
{
TCCR1B=0b111; //konfig PWM
OCR1C=0xFF;
DDRB=0b00001111;
// DDRB|=(1<<PB1) | (1<<PB3);
PORTA|=_BV(PA6) | _BV(PA7) | _BV(PA4) | _BV(PA5); //podciągnięcie przycisków
ADMUX=0b00100000;
ADCSR=0b11100011;
OCR1A=0x01;
OCR1B=0x15;
timer0init();
sei();
for(;;)
{
nastawa();
// OCR1A = nastawnik;
// OCR1B =nastawnik;
// _delay_ms(50);
przyciski();
}
Opierałem się na datasheet i tam jest w tabelce na stronie 67 napisane:ElSor pisze:Także chyba obsłużyć chcesz nie to przerwanie.
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TCCR0 |= (1<<CS02) | (1<<CS00);
TIMSK = (1<<TOIE0); // Timer/Counter1 Output Compare Interrupt Enable
DDRB = (1<<PB1);
}
ISR(TIMER0_OVF0_vect)
{
PORTB ^= (1<<PB1);
}
int main()
{
timer_init();
sei();
while(1);
}
Nic tylko się cieszyć - można spokojnie zająć się swoimi sprawami.Pyra pisze:PS: Żona się na mnie obraziła i poszła spać
Wygląda, że winowajcą było zjedzone "0" w nazwie przerwania.Pyra pisze:Po nieskończonej ilości prób i poprawek... program po raz kolejny przekopiowany, zaczął działać pod AS 5.1, "nagle" też AS 4.19, zaczął rozpoznawać nazwę przerwania od przepełnienia Timer0...
Też do tego doszedłem, ale... dostałem na PW program od grega i też na początku nie chciał chodzić. Potem po kilku próbach, zmianach itp, ponownie go skopiowałem i wkleiłem i zaczął działać. Był on jednak napisany na przerwanie COMPARE, zacząłem przerabiać i w końcu ruszyło też na OVF0...ElSor pisze:Wygląda, że winowajcą było zjedzone "0" w nazwie przerwania.
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TCCR0 |= (1<<CS02) | (1<<CS00); //prescaler 1024
TIMSK = (1<<TOIE0); // Timer/Counter0 przepełnienie
DDRB = (1<<PB1); //wystawienie 1 na PB1
}
ISR(TIMER0_OVF0_vect) //program przerwania od przepełnienia Timer0
{
PORTB ^= (1<<PB1); //zmiana stanu portu PB1 na przeciwny
}
int main()
{
timer_init();
sei(); //włączenie globalnych przerwań
while(1);
}
Właśnie z ADC trochę powalczyłem. Z trybu ciągłej konwersji przeszedłem na pojedynczą, bo musiałem przełączać kanały, a po takiej operacji pierwszy pomiar jest przekłamany bo zmiana kanału dokonuje się podczas konwersji i otrzymujemy poprzedni wynik. Jeśli chodzi o pojedyncze wyzwalanie, doczytałem że czas konwersji może trwać do 270cykli. Przy próbach, uzyskałem stabilne pomiary po umieszczeniu zwłoki 300µs od ustawienia bitu ADSC. Nie starałem się tu za bardzo przyspieszać programu, poprzednia wartość, która była niewłaściwa to było 200µs.ElSor pisze:(w zasadzie zostało mi ADC, timer i wybudzanie z trybu uśpienia).