- fchao-Sinus-Wechselrichter AliExpress         
Seite 3 von 3 ErsteErste 123
Ergebnis 21 bis 25 von 25

Thema: I²C Bus und LM75

  1. #21
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.01.2006
    Ort
    Gratkorn
    Alter
    35
    Beiträge
    207
    Anzeige

    Powerstation Test
    Hallo an alle

    Ich hab nun die I2C Routine fertig geschrieben Jedoch funktioniert sie noc nicht. Ich finde jedoch keinen Fehler

    Hier der Code

    Code:
    #include <avr/io.h>
    #include <stdlib.h>
    #include "lcd.h"
    
    #define TRUE 1
    #define FALSE 0
    #define ACK TRUE
    #define NACK FALSE
    
    #define START 0x08
    #define TW_MT_SLA_ACK 0x18
    #define TW_MT_DATA_ACK	0x28
    
    void lm75_read(void);
    void i2c_init(void);
    int i2c_send_start(uint8_t adress);
    int i2c_send_byte(uint8_t data);
    void i2c_send_stop(void);
    int i2c_read(uint8_t adress, uint8_t ackflag);
    
    
      struct TEMPERATUR {
      uint8_t high;
      uint8_t low;
      } temp;
      
    void i2c_init(void)
    {
    	TWBR |= (1 << 5); //TWBR = 32 = 10 0000
    	// Prescaler = 1
    }
    
    int i2c_send_start(uint8_t adress)
    {
    	TWCR |= ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); //Sende start Condition
    	while(!(TWCR & (1 << TWINT))); //Warte bis ende
    	
    	if((TWSR & 0xF8) != START)
    		return -1;
    	
    	TWDR = adress;
    	TWCR = (1 << TWINT) | (1 << TWEN);
    	while(!(TWCR & (1 << TWINT)));
    	
    	if((TWCR & 0xF8) != TW_MT_SLA_ACK)
    		return -1;
    	
    	return 0;
    }
    
    int i2c_send_byte(uint8_t data)
    {
    	TWDR = data;
    	TWCR = (1 << TWINT) | (1 << TWEN);
    	
    	while(!(TWCR & (1 << TWINT)));
    	
    	if((TWSR & 0xF8) != TW_MT_DATA_ACK)
    		return -1;
    		
    	return 0;
    }
    
    void i2c_send_stop(void)
    {
    	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
    	while(!(TWCR & (1 << TWSTO)));
    }
    
    int i2c_read(uint8_t adress, uint8_t ackflag)
    {
    	if(ackflag == ACK)
    		TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA);
    	else
    		TWCR = (1 << TWINT) | (1 << TWEN);
    	
    	while(!(TWCR & (1 << TWINT)));
    	
    	return TWDR;
    }
    
    void lm75_read(void)
    {
      i2c_send_stop();
      i2c_send_start(0x9E);
      temp.high = i2c_read(0x9F,ACK);
      temp.low = i2c_read(0x9F, NACK);
      i2c_send_stop();
    }
    
    int main(void)
    {
    	uint8_t nachkomma, ganzzahl;
    	
    	i2c_init();
    	lcd_init(LCD_DISP_ON);
    	lcd_home();
    	lcd_clrscr();
    	
    
    	lcd_clrscr();
    	lm75_read();
    	
    	if(bit_is_set(temp.low, 0))
    		nachkomma = 5;
    	else
    		nachkomma = 0;
    		
    	temp.low >>= 1;
    	temp.high <<= 7;
    	ganzzahl= temp.low | temp.high;
    	
    	lcd_put_d(ganzzahl);
    	lcd_putc('A');
    	lcd_put_d(nachkomma);
    
    	
    	return 0;
    }
    Ich hoffe es kann mir wer helfen.

    Danke im Voraus

    Gruß Robert

  2. #22
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Warum sendest Du zu beginn ein STOP, das erzeugt nur Verwirrung,
    sollte der Bus nicht frei sein beim START, bekommt man das schon mit, und kann darauf reagieren.
    Man sollte aber den Bus wieder freigeben, falls der START nicht geklappt hat,
    siehe TWI und TWI_Praxis
    ist zwar mit Bascom gemacht, aber die Reihenfolge passt ja trotzdem.

  3. #23
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.01.2006
    Ort
    Gratkorn
    Alter
    35
    Beiträge
    207
    Hallo an alle

    i2c_start() funktioniert. Nur bei der Receive Routine hakt es. Ich hab Acked und Nacked getrennt.

    Ich hab nach jedem Befehl eine Lcd Ausgabe eingeführt, um zu sehen wo es hakt.

    Hier der Code:

    Code:
    int i2c_read_ack(void)
    {
    lcd_putc('1');
    TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
    lcd_putc('2');
    while(!(TWCR & (1<<TWINT)));
    lcd_putc('3');
    
    if(!(TWSR & 0x50))
    {
    lcd_putc('4');
    return -1;
    }
    lcd_putc('5');
        return TWDR;
    
    }
    Das ist die Funktion mit Acknoledgement. Am Display wird aber nur 12 angezeigt.

    Es hängt also bei while(!(TWCR & (1<<TWINT)));

    Weiß irgendwer, was da falsch sein könnte. Ich hab je´tzt echt keinen Plan mehr

    Danke im Voraus

    Gruß Robert

  4. #24
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.01.2006
    Ort
    Gratkorn
    Alter
    35
    Beiträge
    207
    So, die Ansteuerung funktioniert jetzt

    Code:
    oid i2c_init(void)
    {
    	TWBR = (1 << 5) | (1 << 1) | (1 << 3); //TWBR = 11
    }
    
    void i2c_send_stop(void)
    {
    	TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
    	while(!(TWCR & (1 << TWSTO)));
    }
    
    int i2c_read_ack(void)
    {
    	TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
    	while(!(TWCR & (1<<TWINT)));
    
    		if(!(TWSR & 0x50))
    			return -1;
    		
        return TWDR;
    
    }
    
    int i2c_read_nack(void)
    {
    	TWCR = (1<<TWINT) | (1<<TWEN);
    	while(!(TWCR & (1<<TWINT)));
    	
    	if(!(TWSR & 0x58))
    		return -1;
    	
        return TWDR;
    
    }
    
    int i2c_send_start(uint8_t adress)
    {    
        TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); //Sende start Condition
        while(!(TWCR & (1 << TWINT))); //Warte bis ende
    
        if(!(TWSR & 0x08))
            return -1;
    		
        TWDR = adress;
    
        TWCR = (1 << TWINT) | (1 << TWEN);
        while(!(TWCR & (1 << TWINT)));
    	
        if(!(TWSR & 0x40))
            return(-2);
    
        return 0;
    }
    
    void readfromLM75(uint8_t *temp, uint8_t *nachkomma)
    {
    	i2c_send_start(LM75_ADRESS | 1); //Sende Adresse + Read
    	*temp = i2c_read_ack();
    	*nachkomma = i2c_read_nack();
    	i2c_send_stop();
    	
    	if(bit_is_set(*nachkomma, 7))
    		*nachkomma = 5;
    	else
    		*nachkomma = 0;
    }

  5. #25
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Eine Anmerkung hätte ich noch,
    normalerweise wird beim lesen eines Bytes zuerst das TWDR ausgelesen, und dann erst TWCR gesetzt, sonst kanns vorkommen das sich das nächste Byte schon wieder über den Bus reinschiebt, und die Daten nicht mehr aktuell sind in TWDR.
    Denn normalerweise kommt das gesendete Stop-Bit auch wieder bei TWDR an und schiebt die Daten ein Bit weiter !

    Und es wird aus jeder funktion bei einem Fehler mit return einfach zurückgesprungen, ohne den Bus wieder freizugeben, das kann auch zu komischen Fehlern führen !
    Wenn die Startsequenz zB. keinen Erfolg hatte, muss man trotzdem den Bus freigeben, denn sonst kann ein anderer Master auch nicht weitermachen.

Seite 3 von 3 ErsteErste 123

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress