Pierwsze programy w C

To forum jest dla wszystkich pasjonatów mikrokontrolerów AVR Atmela. Wymiana doświadczeń i pomoc dla początkujących w pisaniu programów zarówno w C, Asemblerze jak i BASCOM. Zapraszam znawców tematu, aby pomogli wszystkim początkującym!
ZbeeGin

Post autor: ZbeeGin » 12 sie 2008, 20:37

A co w Twoim programie chcesz zrobić? Ustawić bity wejścia-wyjścia czy ustawić stan na wyjściu?

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 20:57

Stan na wyjściu. Z przykładów tak robią. W sumie używają polecenia sbi które chyba juz kompilatory nie obsluguja.

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 12 sie 2008, 21:02

Do ustalania stanu na wyjściu służy PORTx

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 21:13

Ok. Jak rozumiem najpierw mam ustawić bit a poźniej stan na wyjściu tak ?? Mam taki kod:

Kod: Zaznacz cały

#include <avr/io.h>



int main(void) {

DDRD |= 1<<1;
PORTD |= 1<<1;
DDRB &= ~(1<<1);
PORTB &= ~(1<<1);
	for(;;) {
		
	}

	return(0);
}
Lecz on pali tylko diode podpiętą pod PD1 dlaczego ?

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 12 sie 2008, 21:23

Bo włączyłeś ją i nie zgasiłeś?

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 21:25

juz doszlem. ten zapis 1<<1 pierwszy raz sie z nim spotykam. Teraz pisze _BV(numer portu) i wychodzi super :) dzieki wielkie :)

snow
Użytkownik
Posty: 794
Rejestracja: 16 sty 2007, 3:44
Lokalizacja: lubelskie
Kontakt:

Post autor: snow » 12 sie 2008, 21:26

Możesz pisać 1<<PB1

spark
Użytkownik
Posty: 412
Rejestracja: 25 lis 2004, 15:50
Lokalizacja: Wrocław

Post autor: spark » 12 sie 2008, 21:28

Laik pisze:Jako błąd to widzę po dwa średniki. Chodzi o to ?
Zgadza się.

W mikrokontrolerach AVR z każdym portem związane są 3 rejestry. Tzn. Każdy port ma swoje oddzielne własne 3 rejestry. Są to:

PORTx - jest to rejestr wyjściowy
DDRx - jest to rejestr określający kierunek przesyłania informacji (wejście/wyjście)
PINx - rejestr wejściowy

gdzie x to litera identyfikująca port (w AVR'ach stosuje się przeważnie porty od A do E, np. PORTA lub DDRE).

Jeśli chcesz sterować jakimiś urządzeniami dołączonymi do portu uC np. LED'ami to:
[1] Musisz ustawić rejestr DDRx w odpowiedniej konfiguracji, logiczna jedynka jest informacją dla procesora że dane wyprowadzenie portu jest wyjściem, zaś logiczne 0 - wejściem sygnału. Wpisanie do rejestru stanu 01100111 (67hex 103dec) oznacza ustawienie wyprowadzeń 0-2 oraz 5 i 6 jako wyjście natomiast pozostałe jako wejście.
[2] Po skonfigurowaniu kierunku przesyłania danych należy wystawić odpowiednią konfigurację w rejestrze wyjściowym PORTx. I tak aby z poprzedniego przykładu zaświecić LED'y podłączone do wyprowadzeń 0-2 (przyjmując że są połączone anodami do portów) należy wpisać do rejestru PORTx wartość 00000111 (07hex 7dec). Programowao wygląda to następująco (na przykładzie portu dajmy na to A):

Kod: Zaznacz cały

#include <avr/io.h>

int main(void)
{
	// ustalenie kierunku przesyłania danych
	DDRA = 0x67;

	// zaświecamy 3 LED'y
	PORTA = 0x07;
	
	for(;;)
	{		
	}

	return 0;
}

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 21:35

Jeszcze tylko ten kod nie działa. Ma on ustalić stan niski. Dlaczego on nie działa ?

Kod: Zaznacz cały

DDRB &= ~(1<<1);
PORTB &= ~(1<<1);


[ Dodano: 2008-08-12, 22:39 ]
spark jak liczysz te hexy ?

spark
Użytkownik
Posty: 412
Rejestracja: 25 lis 2004, 15:50
Lokalizacja: Wrocław

Post autor: spark » 12 sie 2008, 21:45

Laik pisze:Jeszcze tylko ten kod nie działa. Ma on ustalić stan niski. Dlaczego on nie działa ?

Kod: Zaznacz cały

DDRB &= ~(1<<1);
PORTB &= ~(1<<1);


[ Dodano: 2008-08-12, 22:39 ]
spark jak liczysz te hexy ?
Bo ustawiasz bit 1 jako wejście w DDRB a nie wyjście.

1<<1 to 00000010
~(1<<1) to 11111101

A hexy... hmmm... mam taki magiczny kalkulator w domu, który liczy mi we wszystkich systemach i ma wbudowaną funkcję konwersji na inny zapis liczbowy, wpisuje po prostu binarnie wartości a on sam już liczy z tego hexy...

Ale w programowaniu możesz też korzystać z zapisu binarnego poprzedzonego znakami 0b np.

Kod: Zaznacz cały

PORTA = 0b00001100;
to dobre rozwiązanie gdy ktoś dopiero się uczy programować AVR'y w C.

Awatar użytkownika
robson
Użytkownik
Posty: 226
Rejestracja: 22 sty 2006, 19:51
Lokalizacja: S.M.
Kontakt:

Post autor: robson » 12 sie 2008, 21:53

Jeśli dobrze rozumiem, to Portb.1 ma być wyjściem a więc np.:

Kod: Zaznacz cały

DDRB |= 1<<1 ;
wtedy rejestr DDRB (czy jak kto woli kierunku), będzie wyglądał tak.:
000000010
Ty ustawiłeś Portb.1 jako wejście i DDRB wyglądał tak.:
000000000

Druga linia bez zmian.

Mogę się mylić jeśli tak to poprawcie mnie i sorki z góry.

[ Dodano: 2008-08-12, 22:53 ]
hehe Spark89 wyprzedziłeś mnie:)

spark
Użytkownik
Posty: 412
Rejestracja: 25 lis 2004, 15:50
Lokalizacja: Wrocław

Post autor: spark » 12 sie 2008, 21:58

robson pisze:Jeśli dobrze rozumiem, to Portb.1 ma być wyjściem a więc np.:

Kod: Zaznacz cały

DDRB |= 1<<1 ;
wtedy rejestr DDRB (czy jak kto woli kierunku), będzie wyglądał tak.:
000000010
Ty ustawiłeś Portb.1 jako wejście i DDRB wyglądał tak.:
000000000

Druga linia bez zmian.

Mogę się mylić jeśli tak to poprawcie mnie i sorki z góry.

[ Dodano: 2008-08-12, 22:53 ]
hehe Spark89 wyprzedziłeś mnie:)
ma się ten refleks szachisty ;p

tak masz rację wszystko się zgadza.

Jeszcze tylko mnie wiercą te operatory logiczne które stawiacie przy przypisywaniu do rejestrów wartości. Stosowanie ich jest dobrym nawykiem jednak w tym przypadku wydaje mi się, że lepiej będzie przypisanie konkretnej wartości do portu czyli:

Kod: Zaznacz cały

DDRA = (1<<1);
zamiast

Kod: Zaznacz cały

DDRA |= (1<<1);
Te drugie stosuje się gdy zależy nam na zachowaniu poprzedniego stanu wartości rejestru a chcemy ustawić tylko konkretnie interesujące nas wyprowadzenia.

Mimo wszystko i jedno i drugie rozwiązanie będzie dobre.

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 22:19

Jeszcze dwa pytanka:
Jaka jest komenda aby uśpić procesor ? coś takiego jak sleep ? i co trzeba dołączyć ?
I Jak sprawdzić czy na nożce procesora występuje stan wysoki.

Awatar użytkownika
robson
Użytkownik
Posty: 226
Rejestracja: 22 sty 2006, 19:51
Lokalizacja: S.M.
Kontakt:

Post autor: robson » 12 sie 2008, 22:37

Jest taki rejestr MCUCR i jego bity od 7 do 4. To, co za pomocą nich można uzyskać (jaki stan uśpienia Idle, Power-down, Power-save itd.), jest ładnie opisane w nocie katalogowej konkretnego układu.

Co trzeba dołączyć do procka? No raczej nic bo w tryby te wchodzisz programowo, ale np z Power-down, już możesz wyjść tylko sprzętowo - RESET.

Laik
Użytkownik
Posty: 242
Rejestracja: 21 maja 2007, 19:19
Lokalizacja: z nienacka

Post autor: Laik » 12 sie 2008, 22:42

a może ktoś pokaże to na przykładzie ? w nocie sama teoria.

[ Dodano: 2008-08-13, 13:48 ]
Laik pisze:a może ktoś pokaże to na przykładzie ? w nocie sama teoria.
//EDIT

Już do rozgryzłem. Polatałem trochę po plikach .h i znalazłem delay.h a komenda to _delay_ms(czas); Pozdrawiam.

[ Dodano: 2008-08-13, 15:02 ]
Tak to jest. Raz z górki raz pod górkę i teraz mam pod :(. Mianowicie napisałem już obsługę wyświetlacza 7seg brzęczyka piezo i dód na jednym projekcie i działało super. Teraz chciałem spróbować obsługo 4x7seg i mam problem.
Rozumiem tak: rejestr DDRB ustala jakie porty podpiąć do masy czy do plusa a PORTB ustala to dobrze rozumiem ? To dlaczego w moim programie :

Kod: Zaznacz cały

#include <avr/io.h>


#define _PB_ON DDRB = 0b0000000;
#define _PD_ON DDRD = 0b1001111;
#define _BUZ DDRD = 0b100000;

int main(void) {

	int show[10];
	
		show[1] = 0b0000110;
		show[2] = 0b1011011;
		show[3] = 0b1001111;
		show[4] = 0b1100110;
		show[5] = 0b1101101;
		show[6] = 0b1111101;
		show[7] = 0b0000111;
		show[8] = 0b1111111;
		show[9] = 0b1101111;
		show[0] = 0b0111111;


_PB_ON;
PORTB = 0b1111111;
_PD_ON;
PORTD = 0b1111111;

	for(;;){
	
	
	}


	return(0);
}
DDRB ma być podłączony do masy cały port a tak nie jest. Jest cały podłączony do +. Dlaczego ?

ODPOWIEDZ