AVR GCC problem z obsługą TWI w Atmega16

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!
ODPOWIEDZ
mouse
-
Posty: 19
Rejestracja: 29 lis 2006, 22:05
Lokalizacja: Opole
Kontakt:

AVR GCC problem z obsługą TWI w Atmega16

Post autor: mouse » 02 lip 2007, 23:31

witam staram się dogadać z pcf 8583 po twi. niestety pojawił sie drobny problem. niedziała, znaczy pewnie działa tylko ja sie nie umiem z tym dogadać. napisałem programik który ma odczytywać minuty niestety czas sie zatrzymał i minuty ani drgną. mam prośbe sprawdźcie mój kod może szybko złapiecie byka. podczas pisania kożystałem zopisu I2C zawartego na tej stronie http://www.autokacik.pl/i2c/

Kod: Zaznacz cały

#include <avr/io.h>
#include <lcd4bit.h>
#include <util/delay.h>
#include <avr/avrlibdefs.h>
#define twi PORTC
#define scl     1
#define sda     0
int minuty;



int main(void)
{

MCUCSR = 1<<7;
MCUCSR = 1<<7; 
	DDRC=0xff;
	PORTC=0xff;
MCUCSR = 1<<7;
MCUCSR = 1<<7; 
	DDRD = 0xff;
	PORTD = 0x00;
DDRB = 0xff;
PORTB = 0xff;
	DDRA = 0xff;
	PORTA = 0xff;	
LcdInit();


	{
	for(;;)
	{
	WriteTextXY(1,2,"lecimy z tym koksem");

cbi (twi,scl);//
sbi (twi,sda);// } ustawienie danych i zegara na 1
sbi (twi,scl);//
/////////////////start///////////////
cbi (twi,sda);/////zmina stanu lini danych z 1na 0 przy zegarze na 1 - czyli start
/////////////////////////////////////		
/////////adres urzadzenia//////w tym przypadku 7 zer///////
// wczesniej ustawilismy 0 na sda przy starcie wiec zostaje			
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 0 bitu		
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 1 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 2 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 3 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 4 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 5 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 6 bitu	/// czyli 7 zer przeszlo
cbi (twi,scl);
sbi (twi,sda);
sbi (twi,scl);////////////7 bit 1 czyli odczyt/////
/////////////////////////////////
DDRC=0b11111110;/// przygotowanie do odbioru ack
cbi (twi,scl);
sbi (twi,scl);
if ((twi,sda)==0)
{
WriteTextXY(1,2,"adres     1 ok");
}
else
{
WriteTextXY(1,2,"fatal errrrrrrror");
}
DDRC=0xff;
cbi (twi,scl);
cbi (twi,sda);
///////////////////adres wewnetrzny//////
// wczesniej ustawilismy 0 na sda przy starcie wiec zostaje			
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 0 bitu		
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 1 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 2 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 3 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 4 bitu	
cbi (twi,scl);			
sbi (twi,scl);////////////odczyt 5 bitu	
cbi (twi,scl);			
sbi (twi,sda);////////////6 bit (1)
sbi (twi,scl);
cbi (twi,scl);
sbi (twi,scl);////////////7 bit (1) 6,7 bit 11 czyli 3/////
/////////////////////////////////
DDRC=0b11111110;/// przygotowanie do odbioru ack
cbi (twi,scl);
sbi (twi,scl);
if ((twi,sda)==0)
{
WriteTextXY(1,2,"adres 2 22222222 2 ok");
}
else
{
WriteTextXY(1,2,"fatal errrrrrrror   2");
}
DDRC=0xff;
cbi (twi,scl);
cbi (twi,sda);
///////////////////////////////////////////////////////////////////////
////////////////ODCZYT minut//////////////////
minuty=0x00;
DDRC=0b11111110;
//////////////////////////////////////////////
sbi (twi,scl);			
if ((twi,sda)==1)
{
minuty=0x01;
}
else
{
DDRB=0xff;
}
cbi (twi,scl);////////////////koniec odczytu 0 bitu

	sbi (twi,scl);			
	if ((twi,sda)==1)
	{
	minuty=minuty+2;
	}
	else
	{
	DDRB=0xff;
	}
	cbi (twi,scl);////////////////koniec odczytu 1 bitu

			sbi (twi,scl);			
			if ((twi,sda)==1)
			{
			minuty=minuty+4;
			}
			else
			{
			DDRB=0xff;
			}
			cbi (twi,scl);////////////////koniec odczytu 2 bitu

					sbi (twi,scl);			
					if ((twi,sda)==1)
					{
					minuty=minuty+8;
					}
					else
					{
					DDRB=0xff;
					}
					cbi (twi,scl);////////////////koniec odczytu 3 bitu


						sbi (twi,scl);			
						if ((twi,sda)==1)
						{
						minuty=minuty+16;
						}
						else
						{
						DDRB=0xff;
						}
						cbi (twi,scl);////////////////koniec odczytu 4 bitu

							sbi (twi,scl);			
							if ((twi,sda)==1)
							{
							minuty=minuty+32;
							}
							else
							{
							DDRB=0xff;
							}
							cbi (twi,scl);////////////////koniec odczytu 5 bitu
		
								sbi (twi,scl);			
								if ((twi,sda)==1)
								{
								minuty=minuty+64;
								}
								else
								{
								DDRB=0xff;
								}
								cbi (twi,scl);////////////////koniec odczytu 6 bitu
									
									sbi (twi,scl);			
									if ((twi,sda)==1)
									{
									minuty=minuty+128;
									}
									else
									{
									DDRB=0xff;
									}
									cbi (twi,scl);////////////////koniec odczytu 7 bitu
//////////////////////////////////////////////
DDRC=0xff;
cbi (twi,sda);
sbi (twi,scl);//////wgenerowany ack od odbiornika czyli procka
//////////////STOP////////////////
////////zegar jest na 1 a dene na 0////////
sbi (twi,sda); //skok z 0 na 1 danych przy zegarze na 1 STOP
//////////////////////////////////////////////////////////////////////

GotoXY(1,1);
WriteChar(minuty);


			
			}
	return 0;
}
}
starałem sie robić dużo komentarzy ale jak by ktoś miał jakieś pytania to chętnie odpowiem co i dlaczego zrobiłem.

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 03 lip 2007, 9:54

Program napisany bardzo nieczytelnie. Nie wiem czy ktoś będzie miał ochotę się przez to przebijać. Ze swojej strony mogę polecić podejście na podstawie warstw. Pisanie obsługi I2C w funkcji main z dbaniem o każdy pojedynczy bit ma sens tylko wtedy jeśli rzeczywiście musimy osiągnąć bardzo dużą prędkość transmisji - rzędu porównywalnego z 1/4 prędkości zegara procesora. Tutaj nie widzę takiej potrzeby. Proponuję napisanie oddzielnie warstwy obsługi I2C na poziomie bitowym (przesłanie jednego bitu, bit start, bit stop). Na tym powinna znaleźć się warstwa obsługi bajtowej (wysłanie adresu, wysłanie danej, odebranie danej). Wtedy program będzie czytelniejszy a jego pisanie stanie się wygodniejsze. Obsługą I2C zajmowaliśmy się w ramach kursu. Odpowiednie listingi dostępne są na mojej stronie autorskiej: https://elportal.pl/n0017

mouse
-
Posty: 19
Rejestracja: 29 lis 2006, 22:05
Lokalizacja: Opole
Kontakt:

Post autor: mouse » 03 lip 2007, 20:10

:) byłem pewny że jest czytelnie . ale zapewne jest czytelny tylko dla tego kto go pisał.
Pisałem bit po bicie bo chce zrozumieć dokładnie sposób transmisji TWI . pobrałem listingi i będę ćwiczył, niestety nie mogę otworzyć całego projektu w związku z tym czy możesz zamieścić program do obsługi urządzenia na I2C tak żebym mógł zobaczyć jak to działa krok po kroku? Nie ukrywam że najlepiej dla zegarka PCF8583 bo z takim zegarkiem próbuję się dogadać, ale będę wdzięczny za cokolwiek na przykładach uczy się najlepiej (przynajmniej mi )
pozdrawiam

Jurek Szczesiul
-
Posty: 13
Rejestracja: 08 paź 2005, 18:20

Post autor: Jurek Szczesiul » 03 lip 2007, 22:04

mouse pisze: Pisałem bit po bicie bo chce zrozumieć dokładnie sposób transmisji TWI .
Cześć mouse.
Akurat przy atmegach nie jest to zbyt praktyczne - prawie wszystkie mają
porządny sprzętowy interfejs i2c z bajtową obsługą i przerwaniami.
Jeśli raz przez to przebrniesz to później masz samograj dla rozmaitych
peryferiów. Jeśli chcesz przykład :
tu

Pozdrowienia Jurek S.

Npn
-
Posty: 35
Rejestracja: 19 maja 2007, 3:09
Lokalizacja: Kraków

Post autor: Npn » 04 lip 2007, 4:55

Przy okazji polecam taką "drobnostkę" jak Bascom. Instrukcje typu 'I2Cwrite'/'I2Cread' itp, wybitnie ułatwiają życie, nie mówiąc już o reszcie ułatwień tego języka.

ZbeeGin

Post autor: ZbeeGin » 04 lip 2007, 16:57

Npn pisze:Instrukcje typu 'I2Cwrite'/'I2Cread' itp, wybitnie ułatwiają życie, nie mówiąc już o reszcie ułatwień tego języka.
Jest niestety druga strona medalu. Wibitnie zżerają zaoby pamięciowe... Ale nie tak jak operacje zmiennoprzecinkowe.

mouse
-
Posty: 19
Rejestracja: 29 lis 2006, 22:05
Lokalizacja: Opole
Kontakt:

Post autor: mouse » 05 lip 2007, 8:10

Bascom.... słyszałem ale nigdy nie miałem z nim do czynienia na uczelni tylko asm i sam dla siebie C z racji tego że materiałów dużo... jak się z czasem okazało nie do avr ale skąd początkujący elektronik miał o tym wiedzieć :) . Waszym zdaniem jaki język jest lepszy. Może inaczej nie lepszy tylko łatwiejszy bo wiadomo czasem wstawkę w asm trzeba zrobić i każdy ma swoje + i - :). Jeśli faktycznie bascom jest "prostszy" to może w nim pisać z drugiej strony nie chce skakać z języka na język tylko dlatego bo w C się na czymś zaciąłem. Co Wy byście mi doradzili ?

Awatar użytkownika
Koppel
Użytkownik
Posty: 500
Rejestracja: 24 lip 2005, 18:05
Lokalizacja: Gliwice

Post autor: Koppel » 05 lip 2007, 8:55

mouse pisze:niestety nie mogę otworzyć całego projektu
Projekt otwiera się z poziomu "Programmers Notepad". Nie jest to jednak konieczne do zrozumienia jego działania - można otwierać pliki oddzielnie.
mouse pisze:Pisałem bit po bicie bo chce zrozumieć dokładnie sposób transmisji TWI
Wydaje mi się, że nie tędy droga. Łatwiej jednak wszystko zrozumieć pisząc najpierw wysyłanie bitu, warunku start i stop, później na tej podstawie wysyłanie bajtu, później adresu i danych...
mouse pisze:Co Wy byście mi doradzili ?
Materiał do części 6 kursu. Tam plik i2c.c do przejrzenia a następnie zobaczenie jak w pliku main.c wykorzystywane są polecenia i2c. Nie jest to obsługa zegarka który chcesz obsługiwać, ale samo i2c jest przerobione.

Jeśli:
mouse pisze:chce zrozumieć dokładnie sposób transmisji TWI
Zapomnij o BASCOMIE. To jest oprogramowanie w którym wszystko działa ale tylko jego producent wie dokładnie jak.
Jeśli jednak chcesz napisać program szybko i mieć od razu efekty, to BASCOMA mogę polecić.

ODPOWIEDZ