logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

TWI,komunikacja,atmega8, C

szefopiotr 12 Gru 2008 14:16 1730 1
  • #1 5849721
    szefopiotr
    Poziom 9  
    Witam próbuje skomunikować ze sobą dwie atmegi za pomocą twi. Napisałem skrypt oparty o datasheet jednak mam pare watpliwosci.poszukalem po elektrodzie i nie znalazlem tematu ktory by odp na moje ptyania.

    Komunikacja wyglada nastepujaco. Jeden z kontrolerow bedzie Master Reciver a drugi slave transmitter. po inicjalizacji polaczenia slave ma przeslac pewna wartosc.
    Oto program dla master:
    #include "moje.h"
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/pgmspace.h>
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <avr/delay.h>
    
    
    
    #define adres_sl 0x51
    
    unsigned char bufor[1]; 
    volatile uint8_t bd; //bajt danych
    
    void error1(void)
    {
    	 LCD_xy(10,0);
         write_text("blad1");
    	 _delay_ms(5000);
    }
    
    void error2(void)
    {
    	LCD_xy(10,0);
         write_text("blad2");
    	 _delay_ms(5000);
    }
    
    void error3(void)
    {
    	 LCD_xy(10,0);
         write_text("blad3");
    	 _delay_ms(5000);
    }
    
    TWBR=0x01;
    TWSR=(~_BV(TWPS1)|~_BV(TWPS0));  //ustawienie bitow prescalera
    
    SIGNAL(TWI)
    {
    }
    
    sei();
    
    void main(void)
    {
    while(1)
    {
    	
    	TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWCR=_BV(TWINT)|_BV(TWSTA)|_BV(TWEN);start
     
    	while(!(TWCR&(1<<TWINT))) //potw startu
    	{
    	}
    
    	if ((TWSR&0xF8 != 0x08))
    	{
    		error1();
    	}									//spr_kodu_start
    	
    	TWDR=adres_sl;
    	TWCR=(1<<TWINT)|(1<<TWEN);    //adresowanie(); //adres slave 0101 000 1=0x51
    	
    	
    	while(!(TWCR&(1<<TWINT))) 
    	{
    	}								//potw_adr();
    	
    	if ((TWSR&0xF8)!=0x40)
    	{
    		error2();
    	}							//spr_kodu_adr();
    	
    	
    	bd=TWDR;                      
    
    	TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);
    	
    											//odb_danych();
    	
    		
    	if ((TWSR&0xF8)!=0x50)
    	{
    		error3();
    	}                                      //						spr_kodu_odb();
    	
    	
    	void stop(void)
    	{
    		TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
    	}													//stop();
    	
    	
    	 LCD_xy(10,0);
         write_text("ok");
    	 _delay_ms(5000);
    }
    
    
    }

    a to kod dla slave:
    #include "moje.h"
    #include <avr/io.h>
    #include <avr/interrupt.h> 
    #include <avr/pgmspace.h>
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <avr/delay.h>
    
    
    #define adres_sl 0x51
    
    //unsigned char bufor[1]; 
    //volatile uint8_t bd; 
    
    void error1(void)
    {
    	 LCD_xy(10,0);
         write_text("blad1");
    	 _delay_ms(5000);
    }
    
    void error2(void)
    {
    	LCD_xy(10,0);
         write_text("blad2");
    	 _delay_ms(5000);
    }
    
    void error3(void)
    {
    	 LCD_xy(10,0);
         write_text("blad3");
    	 _delay_ms(5000);
    }
    
    TWBR=0x01;
    TWSR=(~_BV(TWPS1)|~_BV(TWPS0));  //ustawienie bitow prescalera
    
    TWAR=0x51;    //UST ADRESU
    
    SIGNAL(TWI)
    {
    }
    
    sei();
    
    void main(void)
    {
    while(1)
    {
    	TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN)|~(1<<TWSTA)|~(1<<TWSTO); //uruchom OCZEKIWANIE();
    	
    	while(!(TWCR&(1<<TWINT))) 
    	{
    	}								//potw wywolania
    
    	if ((TWSR&0xF8 != 0xA8))
    	{
    		error1();
    	}
    	             //wysl danych
    	
    	
    	
    	TWDR=0x34; 
    	TWCR=(1<<TWINT)|(1<<TWEN);
    	
    	while(!(TWCR&(1<<TWINT)))      //potw wysl
    	{
    	}
    	
    			
    	if ((TWSR&0xF8)!=0xB8)    //spr kodu wysl
    	{
    		error2();
    	}
    	TWCR=(1<<TWINT)|(1<<TWEN);
    	
    	while(!(TWCR&(1<<TWINT))) // potw konca bajtu
    
    	{
    	}					
    	
    	if ((TWSR&0xF8)!=0xC8)    //spr kodu wysl
    	{
    		error3();
    	}
    	
    	TWCR=(1<<TWINT)|~(1<<TWEA)|~(1<<TWSTA)|~(1<<TWSTO);
    	
    	 LCD_xy(10,0);
         write_text("ok");
    	 _delay_ms(5000);
    }
    }


    Moje pytania sa nastepujace:
    1.Czy te programy maja w ogole szanse zadzialac??
    2.Jezeli jestem MR to czy moge tak po prostu po zczytaniu kodu poprawnego przyjecia adresu zczytać wartość TWDR??czy musze jeszcze zastosowac jakis warunek??
    if ((TWSR&0xF8)!=0x40)
    	{
    		error2();
    	}							//spr_kodu_adr();
    	
    	
    	bd=TWDR;                      
    
    	TWCR=(1<<TWINT)|(1<<TWEA)|(1<<TWEN);
    	
    											//odb_danych();
    	

    3.jeżeli jestem MR to czy po prawidłowym odczytaniu kodu odebrania bajtu musze wystawic ACK czy master zrobi to automatycznie??
    4.Jezeli jestem ST to czy poprawne jest sprawdzanie flagi jako warunku końca wysyłanych bajtów?? chodzi mi o warunek potw konca bajtu??


    poniewaz jestem poczatkujacy w tym temacie kazda pomoc bedzie na wage zlota.

    Mam jeszcze jedna prosbe poniewaz przy kompilacji wyskakuje mi nastepujacy blad:
    :/winavr-20080610/lib/gcc/../../avr/include/avr/delay.h:36:2: warning: #warning "This file has been moved to <util/delay.h>."
    mainST.c:36: error: expected identifier or '(' before 'volatile'
    mainST.c:36: error: expected ')' before '(' token
    mainST.c:37: error: expected identifier or '(' before 'volatile'
    mainST.c:37: error: expected ')' before '(' token
    mainST.c:39: error: expected identifier or '(' before 'volatile'
    mainST.c:39: error: expected ')' before '(' token
    mainST.c:41: warning: 'TWI' appears to be a misspelled signal handler
    mainST.c:45: error: expected '(' before 'volatile'
    mainST.c:47: warning: return type of 'main' is not 'int'
    mainST.c: In function 'main':
    mainST.c:57: warning: suggest parentheses around comparison in operand of &
    make.exe: *** [mainST.o] Error 1
    

    wiem,ze napisane jest o problemie z nawiasami,ale wszystkie wydaja sie ok... moze jestem jz zbyt zmeczony czytaniem o TWI zeby to zauwazyc :) wprawne oko na pewno szybko to wychwyci.

    Bede bardzo wdzięczny za pomoc. Pozdrawiam
  • Pomocny post
    #2 5850896
    Dr.Vee
    VIP Zasłużony dla elektroda
    Wszystko Ci przecież kompilator napisał.
    Błędy:
    1) masz sei(); i kilka innych instrukcji poza jakąkolwiek funkcją...
    2) procedurę obsługi TWI deklaruj jako ISR(TWI_vect) { }
    3) funkcja main powinna mieć prototyp
    int main(void);

    Pozdrawiam,
    Dr.Vee
REKLAMA