(26-01-2012 1:00)SP9LAP napisał(a): Witam!
Proponuję omówić po linijce program z lekcji nr 5, bo prawdę mówiąc "utraciłem chwilowo w tym momencie kontakt z bazą" na tyle, że nawet nie wiem o co spytać.
Ale weś napisz, tu linijki kodu których nie rozumiesz. bp jak zaczne sie rozwodzić nad wszystkimi to mi dnia nie starczy
.
(26-01-2012 8:48)SQ9JXB napisał(a): 11- port D
Jesteś pewien ? Pamiętam jak napisałeś
SQ9JXB napisał(a):Dopiero wprowadzenie poprawki Kolegi Bogdana SP3IQ jest wyświetlenie ABCD_
a to była "poprawka" dla wyświetlacza na
porcie A
SQ9JXB napisał(a):12- 4 porty we/wy , również mogą pełnić inne funkcje, ale nie bardzo rozumiem sposób numeracji wyprowadzeń Atmegi. Ale myślę że w dokumentacji Atmegi to wyczytam
może źle mnie zrozumiałeś, chodzi mi o to że np. PORT C ma wyprowadzenia:
PC0, PC1, PC3, PC4, PC5, PC6, PC7. Czyli od zera do 7.
Jeszcze Ci powiem o rejestrach ... poniżej kilka przykładów rejestrów które już mogłeś zobaczyć w moim kursie:
DDRA, DDRB, DDRC, DDRD, PORTA, PORTB, PORTC, PORTD, PINA, PINB, PINC, PIND.
Rejestr to tak jakby 8-bitowa (czyli jednobajtowa) pamięć, której zawartość zmieniasz poprzez przypisanie np.
lub poprzez podanie pewnych stanów na wyprowadzenia w przypadku gdy port jest ustawiony jako wejścia.
DDRx to rejestry odpowiedzialne za ustawienie "kierunkowości" wyprowadzeń PORTUx - czyli ustawia poszczególne wyprowadzenia portu na wejścia lub wyjścia wedle reguły 0 to wejście, 1 to wyjście.
(tu akurat jest portA).
PORTx to rejestry które sa odpowiedzialne za stan logiczny wyprowadzeń portów, wedle tej samej reguły co powyżej. zmianę tych stanów osiągamy na przykład poprzez
PINx to rejestry "mówiące" nam jakie są stany na poszczególnych wyprowadzeniach PORTUx - rejestry do odczytu - wykorzystywane oczywiście najczęściej w przypadku gdy port jest wejściem. Czyli zapodajemy fizycznie jakieś stany na portx i możemy za pomocą rejestru PINx odczytać je, przypisując tę wartość jakiejś zmiennej, przykład (przypuśćmy że cały PORT B jest wejściem)
po tym zabiegu zmiennej y przypisujemy wartość według stanów logicznych podanych z zewnątrz na wejścia(wyprowadzenia) portuB. Inaczej mówiąc ... y staje się jakąś liczbą, która reprezentuje stany logiczne podane na wyprowadzenia PORTU B
Dobra... czas na to abyście nie tylko korzystali z gotowców ale też umieli sami zrobić projekt w AVR Studio. I właśnie taki zrobimy:
1. Włączcie AVR Studio - powinno wyskoczyć takie okno:
Kliknijcie na "New Project"
2. Potem wybierzcie "AVR GCC" i resztę tak jak zaznaczyłem na rysunku. wybierzcie sobie katalog w którym macie wszystkie dotychczasowe lekcje,
następnie klikacie "Next" i zaznaczacie to co na rysunku
3. Otworzy sie nowy projekt i jeden pusty plik ( nowy.c ). Wklejcie do niego poniższy kod
Kod:
#include <avr/io.h>
#include <util/delay.h>
#include "lcd_alfanum.h" // wkleja tu zawartość pliku lcd_alfanum.h
int main(void)
{
init_lcd(); // inicjuje wyświetlacz
napis_lcd("napis"); // wyświetla napis pomiędzy cudzysłowami
}
4. Następnie utwórzcie nowy plik - menu file. new file
i wklejcie w jego okienko to:
Kod:
/* Jest to plik do dziewiątej lekcji Kursu Programowania mikrokontrolera Atmega w języku C,
jednocześnie pierwsza wersja "biblioteki" obsługi wyświetlacza alfanumerycznego
uroczyście nadaje jej nazwę "lcd_alfanum.h"
Aby użyć jej w swoim projekcie należy w głównym pliku programu dodać linię:
#include "lcd_alfanum.h"
autor: Marcin Prajwocki SP4EJT */
#include <avr/io.h>
#include <util/delay.h>
/* Konfiguracja - na którym porcie i na wyprowadzeniach puszczamy sterowanie LCD */
#define DEF_PORT DDRD /* wpisujemy DDRA, DDRB, DDRC, DDRD - zależy który port będzie obsługiwał wyświetlacz */
#define LCD_PORT PORTD /* wpisujemy, który port ma wysyłać dane do wyświetlacza - 4 starsze bity portu (7,6,5,4) */
/* podłączamy odpowiednio do wyjść D7, D6, D5, D4 wyświetlacza */
#define LCD_RS 3 /* które wyprowadzenie PORTU będzie linią RS */
#define LCD_E 2 /* które wyprowadzenie portu ma być linią E */
/* koniec konfiguracji. Pamiętajcie że numeracja wyprowadzeń PORTU zaczyna sie od "0" */
void bajt_lcd(unsigned char znak)
{
LCD_PORT = (LCD_PORT & 15)|(znak&240);
LCD_PORT |= (1<<LCD_E);
LCD_PORT &= (~1<<LCD_E);
LCD_PORT = (LCD_PORT & 15)|(znak<<4);
LCD_PORT |= (1<<LCD_E);
LCD_PORT &= (~1<<LCD_E);
_delay_ms(10);
}
void napis_lcd(char tab[])
{
LCD_PORT = LCD_PORT|(1<<LCD_RS);
int i=0;
while(tab[i]!=0)
{
bajt_lcd(tab[i]);
i=i+1;
}
}
void init_lcd(void)
{
DEF_PORT = 0xf0|(1<<LCD_RS)|(1<<LCD_E);
unsigned char i;
for(i=0;i<3;i++)
{
LCD_PORT = (LCD_PORT&0x0f)|(0x30&0xf0);
LCD_PORT |= (1<<LCD_E);
LCD_PORT &= (~1<<LCD_E);
_delay_ms(50);
}
LCD_PORT = (LCD_PORT&0x0f)|(0x20&0xf0);
LCD_PORT |= (1<<LCD_E);
LCD_PORT &= (~1<<LCD_E);
_delay_ms(50);
bajt_lcd(0x28); // Interfejs 4-bit, Wyświetlacz dwuwierszowy, Matryca znaków 5x7
bajt_lcd(0x01); // czyszczenie i przesuniecie na poczatek LCD
bajt_lcd(0x0e); // włączenie wyświetlacza kursor widoczny niemrygający
}
/* autor nie zastrzega sobie praw autorskich, pod warunkiem że nie czerpiesz z tego korzysci materialnych, możecie kopiować i zmieniać ten plik */
5. Zapiszcie ten plik pod nazwą "lcd_alfanum.h"
Powinniście uzyskać efekt podobny do tego
6. Skonfigurujcie sobie na którym porcie macie wyświetlacz, Skompilujcie i uruchomcie. Napiszcie jeśli coś jest nie tak.
Plik lcd_alfanum.h jest prostą biblioteką obsługi wyświetlacza, w oddzielnym pliku - układ taki powoduje przejrzystość projektu. Pisząc programy dobrze jest właśnie tak rozbijać (na pliki) poszczególne "biblioteki" obsługi urządzeń - np. do pbsługi syntezy DDS, do klawiatury komputerowej, do zegarka/kaledarza, do wyświetlacza TFT, do dekodera dźwięku, do termometru cyfrowego, itp. itd. Do każdego urządzenia jeden plik. dołaczamy je w prosty sposób do naszych projektów urzywając [code]#include "nazwa_pliku" - plik ten musi być umieszczony w tym samym katalogu co plik główny programu (tak na prawdę nie musi ale na razie przyjmijcie że tak jest - będzie Wam łatwiej)
Na dole gotowiec.
W kolejnych lekcjach będę powolutku dążył do programu obsługującego syntezę DDS AD9951 ... ale przed nami jeszcze kawałek drogi ...