O programowaniu w C słów kilka

Czyli wszystko co potrzebne prawdziwemu DIY'owi;) Porady, pytania i opisy używanego przez nas sprzętu.
ptja
Posty: 2414
Rejestracja: poniedziałek 31 gru 2012, 12:44
Lokalizacja: Łódź

Post autor: ptja »

Co powiesz na to?

Kod: Zaznacz cały

#include <avr/io.h>
#include <util/delay.h>

void InicjalizujPWM&#40;&#41; &#123;
   TCCR0A=0xa1;
   TCCR0B|=&#40;1<<CS00&#41;;
   DDRB|=&#40;1<<PB0&#41; | &#40;1<<PB1&#41;;
&#125;

void UstawPoziomLED&#40;unsigned int short poziom&#41; &#123;
   OCR0A = poziom;
   OCR0B =~poziom;
&#125;

int main&#40;&#41; &#123;
   InicjalizujPWM&#40;&#41;;

   unsigned int kwant = 50;

   unsigned int short poziom;
   for&#40;;;&#41; &#123;
      while &#40;poziom<255&#41; &#123;
         UstawPoziomLED&#40;poziom&#41;;
         _delay_ms&#40;kwant&#41;;
         poziom++;
      &#125;;
      while &#40;poziom>0&#41; &#123;
         UstawPoziomLED&#40;poziom&#41;;
         _delay_ms&#40;kwant&#41;;
         poziom--;
       &#125;;
   &#125;
&#125;
lub

Kod: Zaznacz cały

   for&#40;;;&#41; &#123;
      for &#40;poziom=0; poziom<255; poziom++&#41; &#123;
         UstawPoziomLED&#40;poziom&#41;;
         _delay_ms&#40;kwant&#41;;
      &#125;;
      for &#40;poziom=255; poziom>0; poziom--&#41; &#123;
         UstawPoziomLED&#40;poziom&#41;;
         _delay_ms&#40;kwant&#41;;
       &#125;;
   &#125;
--
pozdrawiam,
Jarek Andrzejewski
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post autor: Pyra »

Witam
ptja pisze:Co powiesz na to?
No i popsułeś mi całą radość... :razz:

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
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
ptja
Posty: 2414
Rejestracja: poniedziałek 31 gru 2012, 12:44
Lokalizacja: Łódź

Post autor: ptja »

Pyra pisze:Witam
ptja pisze:Co powiesz na to?
No i popsułeś mi całą radość... :razz:
raczej zaraziłem uczuciem do "pięknego kodu" (mam taką nadzieję) :-)
--
pozdrawiam,
Jarek Andrzejewski
Awatar użytkownika
ElSor
Site Admin
Posty: 5041
Rejestracja: niedziela 13 wrz 2009, 12:52
Lokalizacja: Ozimek

Post autor: ElSor »

Pyra pisze:nie działa mi sbi, a takie fajne jest

Kod: Zaznacz cały

#define SetBit&#40;x,y&#41; x |= &#40;1<<y&#41;
#define ClrBit&#40;x,y&#41; x &= ~&#40;1<<y&#41;
#define NegBit&#40;x,y&#41; x ^= &#40;1<<y&#41;
SetBit zmień sobie na sbi i będziesz miał, to , czego Ci brakuje
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post 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
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
fredek
Posty: 372
Rejestracja: poniedziałek 03 maja 2010, 13:58
Lokalizacja: Łódź

Post 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 :mrgreen:
Awatar użytkownika
pralat
Posty: 413
Rejestracja: piątek 16 kwie 2010, 12:27
Lokalizacja: Opole

Post 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 &#40;poziom>0&#41; &#123;
// .....
         poziom--;
&#125; 
generuje dłuższy kod niż:

Kod: Zaznacz cały

do &#123;
// .....
&#125; while &#40;--poziom > 0&#41;; 
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post 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
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post 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&#40;&#41;
&#123;
TIMSK|=_BV&#40;TOIE0&#41;;
TCCR0=0b00000101;
TCNT0=200;
&#125;


ISR&#40;TIMER0_OVF_vect&#41;
//ISR&#40;_VECTOR&#40;7&#41;&#41;
&#123;
...
&#125;
kompilator kończy ostrzeżeniem

Kod: Zaznacz cały

../ZaskolPWM.c&#58;71&#58;1&#58; warning&#58; '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&#40;&#41;
&#123;
TIMSK=_BV&#40;TOIE1&#41;;
TCCR0=_BV&#40;CS02&#41; | _BV&#40;CS00&#41;; //Preskaler 256
DDRB|=&#40;_BV&#40;PB1&#41; | _BV&#40;PB2&#41;&#41;;
&#125;

ISR&#40;_VECTOR&#40;7&#41;&#41;
&#123;
static uint8_t LED=0b010;
LED^=0b110;
uint8_t tmp=PORTB & 0b11111001;
PORTB=&#40;tmp | LED&#41;;
&#125;

int main&#40;&#41;
&#123;
timer_init&#40;&#41;;
sei&#40;&#41;;
while&#40;1&#41;;
&#125;
Zegar 1MHz ustawiony w opcjach, i nadal nic...

Pozdrawiam
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
ElSor
Site Admin
Posty: 5041
Rejestracja: niedziela 13 wrz 2009, 12:52
Lokalizacja: Ozimek

Post 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).
Awatar użytkownika
greg
Posty: 3535
Rejestracja: środa 08 paź 2008, 00:16
Lokalizacja: Wrocław
Kontakt:

Post 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&#40;&#41;
&#123;
	TCCR0A = &#40;1<<WGM01&#41;; // Timer/Counter Mode of Operation -> Clear Timer on Compare Match &#40;CTC&#41; mode
	TCCR0B = &#40;1<<CS02&#41; | &#40;1<<CS00&#41;; // clkI/O /1024 &#40;From prescaler&#41;
	TIMSK = &#40;1<<OCIE0A&#41;; // Timer/Counter0 Output Compare Match A Interrupt Enable
	OCR0A = 97;
	DDRB = &#40;1<<PB1&#41;;
&#125;

ISR&#40;TIMER0_COMPA_vect&#41;
&#123;
	//static uint8_t LED=0b010;
	//LED^=0b110; // wynik&#58; 0b00000101
	//uint8_t tmp=PORTB & 0b11111001; // wynik&#58; 0b00000000
	//PORTB=&#40;tmp | LED&#41;; // wynik&#58; 0b00000101
	PORTB ^= &#40;1<<PB1&#41;;
&#125;

int main&#40;&#41;
&#123;
	timer_init&#40;&#41;;
	sei&#40;&#41;;
	while&#40;1&#41;;
&#125; 
Sterownik extended v3.5 HE <klik>
Instrukcje sterowników w PDF <klik>

kontakt: info(at)krypton(dot)pl
(podstawić @ i . w stosowne miejsca)
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post 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
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
Awatar użytkownika
ElSor
Site Admin
Posty: 5041
Rejestracja: niedziela 13 wrz 2009, 12:52
Lokalizacja: Ozimek

Post autor: ElSor »

Kod: Zaznacz cały

#include <avr/io.h>
#include <avr/interrupt.h>

void timer_init&#40;&#41;
&#123;
	TIMSK=_BV&#40;TOIE1&#41;;
	TCCR0=_BV&#40;CS02&#41; | _BV&#40;CS00&#41;; //Preskaler 256
	DDRB|=&#40;_BV&#40;PB1&#41; | _BV&#40;PB2&#41;&#41;;
&#125;

ISR&#40;TIMER0_OVF_vect&#41; 
&#123;
	static uint8_t LED=0b010;
	LED^=0b110;
	uint8_t tmp=PORTB & 0b11111001;
	PORTB=&#40;tmp | LED&#41;;
&#125;

int main&#40;&#41;
&#123;
	timer_init&#40;&#41;;
	sei&#40;&#41;;
	while&#40;1&#41;;
&#125;
Atmel Studio 6 skompilował bez żadnych uwag.
Awatar użytkownika
greg
Posty: 3535
Rejestracja: środa 08 paź 2008, 00:16
Lokalizacja: Wrocław
Kontakt:

Post 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&#40;&#41;
&#123;
	TCCR1B = &#40;1<<CTC1&#41;; // Timer/Counter Mode of Operation -> Clear Timer on Compare Match &#40;CTC&#41; mode
	TCCR1B |= &#40;1<<CS13&#41; | &#40;1<<CS11&#41; | &#40;1<<CS10&#41;;  // Timer/Counter1 Prescale Select CK/1024
	TIMSK = &#40;1<<OCIE1A&#41;; // Timer/Counter1 Output Compare Interrupt Enable
	OCR1A = 97;
	DDRB = &#40;1<<PB1&#41;;
&#125;

ISR&#40;TIMER1_CMPA_vect&#41;
&#123;
	PORTB ^= &#40;1<<PB1&#41;;
&#125;

int main&#40;&#41;
&#123;
	timer_init&#40;&#41;;
	sei&#40;&#41;;
	while&#40;1&#41;;
&#125; 

Ale tego nie sprawdziłem na procesorze - kompiluje się poprawnie.

P.S.
Błąd w ustawieniach prescalera macie.
Ostatnio zmieniony sobota 30 mar 2013, 23:22 przez greg, łącznie zmieniany 2 razy.
Sterownik extended v3.5 HE <klik>
Instrukcje sterowników w PDF <klik>

kontakt: info(at)krypton(dot)pl
(podstawić @ i . w stosowne miejsca)
Awatar użytkownika
Pyra
Site Admin
Posty: 8527
Rejestracja: niedziela 02 sie 2009, 20:35
Lokalizacja: Gądki

Post 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
Izali miecz godniejszy niżli topór w boju?
Piszmy po polsku, wszak jesteśmy Polakami.
ODPOWIEDZ