Strona 2 z 4
: niedziela 24 mar 2013, 20:23
autor: ptja
Co powiesz na to?
Kod: Zaznacz cały
#include <avr/io.h>
#include <util/delay.h>
void InicjalizujPWM() {
TCCR0A=0xa1;
TCCR0B|=(1<<CS00);
DDRB|=(1<<PB0) | (1<<PB1);
}
void UstawPoziomLED(unsigned int short poziom) {
OCR0A = poziom;
OCR0B =~poziom;
}
int main() {
InicjalizujPWM();
unsigned int kwant = 50;
unsigned int short poziom;
for(;;) {
while (poziom<255) {
UstawPoziomLED(poziom);
_delay_ms(kwant);
poziom++;
};
while (poziom>0) {
UstawPoziomLED(poziom);
_delay_ms(kwant);
poziom--;
};
}
}
lub
Kod: Zaznacz cały
for(;;) {
for (poziom=0; poziom<255; poziom++) {
UstawPoziomLED(poziom);
_delay_ms(kwant);
};
for (poziom=255; poziom>0; poziom--) {
UstawPoziomLED(poziom);
_delay_ms(kwant);
};
}
: niedziela 24 mar 2013, 21:35
autor: Pyra
Witam
ptja pisze:Co powiesz na to?
No i popsułeś mi całą radość...
Zauważyłem że pętla for generuje kod dłuższy o kilka bajtów, bo też próbowałem...
Na razie oswajam się z nową składnią, chwilę potrwało zanim odszukałem wszystkie błędy i poprawnie mi skompilowało.
Brałem opisy z kilku książek i zauważyłem że nie działa mi
sbi, a takie fajne jest...
Pozdrawiam
: niedziela 24 mar 2013, 21:50
autor: ptja
Pyra pisze:Witam
ptja pisze:Co powiesz na to?
No i popsułeś mi całą radość...
raczej zaraziłem uczuciem do "pięknego kodu" (mam taką nadzieję)
: niedziela 24 mar 2013, 21:55
autor: ElSor
Pyra pisze:nie działa mi sbi, a takie fajne jest
Kod: Zaznacz cały
#define SetBit(x,y) x |= (1<<y)
#define ClrBit(x,y) x &= ~(1<<y)
#define NegBit(x,y) x ^= (1<<y)
SetBit zmień sobie na sbi i będziesz miał, to , czego Ci brakuje
: niedziela 24 mar 2013, 22:03
autor: Pyra
Witam
ElSor pisze:SetBit zmień sobie na sbi i będziesz miał, to , czego Ci brakuje
Damy radę.
Jakoś ten sbi zapamiętałem szybciej, ale kombinowanie, żeby je otrzymać chyba mija się z celem... Zobaczymy czy wytrwam, im więcej czytam, tym niej rozumiem
Pozdrawiam
: niedziela 24 mar 2013, 23:01
autor: fredek
Pyra pisze:Brałem opisy z kilku książek i zauważyłem że nie działa mi sbi, a takie fajne jest...
Wolę przesunięcia bitowe ale jak Ciebie to uszczęśliwi do dodaj sobie taką bibliotekę:
avr/sfr_defs.h zestaw makr dla dostępu do portów wejścia/wyjścia:
_BV(x) Zwraca wartość bitu (bit value) x. Zdefiniowany jako (1 << x).
inb(sfr) Czyta bajt z sfr.
outb(sfr, val) Wpisuje val do sfr. Odwrotnie jak inb(sfr).
cbi(sfr, bit) Kasuje bit w sfr.
sbi(sfr, bit) Ustawia bit w sfr.
bit_is_set(sfr, bit) Zwraca wartość różną od 0, jeżeli bit w sfr jest ustawiony, w przeciwnym wypadku 0.
bit_is_clear(sfr, bit) Zwraca wartość różną od 0, jeżeli bit w sfr jest skasowany, w przeciwnym wypadku 0.
loop_until_bit_ist_set(sfr, bit) Wstrzymuje działanie programu (wykonuje pętle) dopóki bit w sfr jest ustawiony.
loop_until_bit_is_clear(sfr, bit) Wstrzymuje działanie programu (wykonuje pętle) dopóki bit w sfr jest skasowany.
No i gratuluję pierwszego programu
: poniedziałek 25 mar 2013, 10:00
autor: pralat
Pyra pisze:Zauważyłem że pętla for generuje kod dłuższy o kilka bajtów
Ja zauważyłem, że kostrukcja:
Kod: Zaznacz cały
while (poziom>0) {
// .....
poziom--;
}
generuje dłuższy kod niż:
Kod: Zaznacz cały
do {
// .....
} while (--poziom > 0);
: poniedziałek 25 mar 2013, 12:16
autor: Pyra
Witam
Na początku po prostu nie mogłem uruchomić pętli "For" i zastosowałem "While".
Zdaje się, że jest różnica w interpretacji pomiędzy Bascomem a C, jeden interpretuje "wykonuj do spełnienia warunku", drugi "wykonuj dopóki warunek spełniony".
No cóż przestawienie się ma swoje haczyki...
Pozdrawiam
: sobota 30 mar 2013, 11:47
autor: Pyra
Witam
No i utknąłem na przerwaniach. Piszę program zasilacza do kolejki, mam już taki napisany w Bascom, więc nie ma żadnych przeszkód sprzętowych, bo chodzi poprawnie.
Problem dotyczy obsługi przerwania od przepełnienia Timer0.
Kod: Zaznacz cały
void timer0init()
{
TIMSK|=_BV(TOIE0);
TCCR0=0b00000101;
TCNT0=200;
}
ISR(TIMER0_OVF_vect)
//ISR(_VECTOR(7))
{
...
}
kompilator kończy ostrzeżeniem
Kod: Zaznacz cały
../ZaskolPWM.c:71:1: warning: 'TIMER0_OVF_vect' appears to be a misspelled signal handler
Dalej, zamieniłem opis przerwania na numer wektora, i kompilator przechodzi bezbłędnie, ale program nadal nie reaguje.
Aby sprawdzić działanie przerwania poza programem głównym przekopiowałem i poprawiłem krótki programik.
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TIMSK=_BV(TOIE1);
TCCR0=_BV(CS02) | _BV(CS00); //Preskaler 256
DDRB|=(_BV(PB1) | _BV(PB2));
}
ISR(_VECTOR(7))
{
static uint8_t LED=0b010;
LED^=0b110;
uint8_t tmp=PORTB & 0b11111001;
PORTB=(tmp | LED);
}
int main()
{
timer_init();
sei();
while(1);
}
Zegar 1MHz ustawiony w opcjach, i nadal nic...
Pozdrawiam
: sobota 30 mar 2013, 12:12
autor: ElSor
Nie napisałeś jaki procek ma to obsłużyć ale możliwe, że błąd jest taki iż nie ma rejestru TCCR0 (w tiny25 musiałby nazywać się TCCR0B).
: sobota 30 mar 2013, 14:40
autor: greg
Widzę tu kilka błędów
Poniżej kod zmieniający stan portu PB1 co 100ms (zegar 1MHz) na bazie Twojego kodu z moimi poprawkami.
Ustawienie wartości licznika OCR0A = 97 daje nam wynikową częstotliwość przerwania:
F_CPU / prescaler / OCR0A = 10Hz
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TCCR0A = (1<<WGM01); // Timer/Counter Mode of Operation -> Clear Timer on Compare Match (CTC) mode
TCCR0B = (1<<CS02) | (1<<CS00); // clkI/O /1024 (From prescaler)
TIMSK = (1<<OCIE0A); // Timer/Counter0 Output Compare Match A Interrupt Enable
OCR0A = 97;
DDRB = (1<<PB1);
}
ISR(TIMER0_COMPA_vect)
{
//static uint8_t LED=0b010;
//LED^=0b110; // wynik: 0b00000101
//uint8_t tmp=PORTB & 0b11111001; // wynik: 0b00000000
//PORTB=(tmp | LED); // wynik: 0b00000101
PORTB ^= (1<<PB1);
}
int main()
{
timer_init();
sei();
while(1);
}
: sobota 30 mar 2013, 14:50
autor: Pyra
Witam
No tak, zabierałem się trzy razy za napisanie i w końcu zapomniałem....
Procek to ATtiny26, rejestry się zgadzają, bo Bascom też go nie wspiera i PWM musiałem konfigurować "na pieszo".
Zastanawia mnie błąd nazwy wektora. Sprawdzałem na stronie opisującej bibliotekę przerwań i pod tą pozycją nie ma tiny26. Wpisanie na pałę numeru wektora (_VECTOR(7)) powoduje, że nie ma już błędu, ale i tak przerwania nie działają.
Wziąłem działającego Bascoma na symulację, sprawdzałem wartości odpowiednich rejestrów i wszystko się zgadzało z dokumentacją.
Postąpiłem zgodnie z wyczytaną sugestią, aby wyłączyć optymalizację kodu (00) ale wtedy pil wynikowy mi urósł do 2050B co przy bascomowych 962B jest wartością tragiczną... nota bene przekroczona została pojemność pamięci.
greg - właśnie chodzi o to, że nie przyjmuje nazw wektorów przerwań ISR(....)
Pozdrawiam
: sobota 30 mar 2013, 15:05
autor: ElSor
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TIMSK=_BV(TOIE1);
TCCR0=_BV(CS02) | _BV(CS00); //Preskaler 256
DDRB|=(_BV(PB1) | _BV(PB2));
}
ISR(TIMER0_OVF_vect)
{
static uint8_t LED=0b010;
LED^=0b110;
uint8_t tmp=PORTB & 0b11111001;
PORTB=(tmp | LED);
}
int main()
{
timer_init();
sei();
while(1);
}
Atmel Studio 6 skompilował bez żadnych uwag.
: sobota 30 mar 2013, 15:19
autor: greg
Mój powyższy kod jest na rodzinę ATtiny25/45/85 i działa, sprawdziłem.
Dla ATtiny26:
Kod: Zaznacz cały
#include <avr/io.h>
#include <avr/interrupt.h>
void timer_init()
{
TCCR1B = (1<<CTC1); // Timer/Counter Mode of Operation -> Clear Timer on Compare Match (CTC) mode
TCCR1B |= (1<<CS13) | (1<<CS11) | (1<<CS10); // Timer/Counter1 Prescale Select CK/1024
TIMSK = (1<<OCIE1A); // Timer/Counter1 Output Compare Interrupt Enable
OCR1A = 97;
DDRB = (1<<PB1);
}
ISR(TIMER1_CMPA_vect)
{
PORTB ^= (1<<PB1);
}
int main()
{
timer_init();
sei();
while(1);
}
Ale tego nie sprawdziłem na procesorze - kompiluje się poprawnie.
P.S.
Błąd w ustawieniach prescalera macie.
: sobota 30 mar 2013, 15:20
autor: Pyra
Witam
U mnie cały czas to samo: "Build succeeded with 1 Warnings..."
Mam wersję 4.19, ale to nie powinno stanowić problemu, bo procek jest starszy.
U mnie tez się kompiluje, tylko mam to ostrzeżenie. Jak wspomniałem, pprzypisanie na sztywno wektora 7, kompiluje bez błędów, ale program nie działa...
Pozdrawiam