PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Atmega32 hängt sich mit pcf8574AP auf



servusssss
05.05.2007, 21:38
hallo zusammen,

ich komme wider einmal nicht vom fleck #-o #-o , ich versuche den pcf8574 als porterweiterung an den atmega 32 zu hängen doch das klappt nicht ganz.

deshalb hab ich mir ein kleines programm zum teste geschrieben um andere fehler auszuschießen.

der pcf ist mit A0 A1 A2 auf gnd und hängt an der rn control 1.4
die pullups sind auf der rn control
das init geht beim start ist dann schluss ](*,)

i2c.c



#include <avr/io.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#include <string.h>
#include "uart.h"
#include "pcf8574.h"

#ifndef F_CPU
#define F_CPU 16000000UL // 16MHz Taktfrequenz
#endif

/* 9600 baud */
#define UART_BAUD_RATE 9600
#define CR \r\n

void wait(unsigned int ms);



void init(void)
{

// Portsdef

DDRC &=!((1<<DD0)|(1<<DD1));
PORTC =(1<<DD0)|(1<<DD1);

}

int main (void){
// Initialisierung der Register


init();

// Uart Initalisierung
uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
//Interrupt enable
sei();


uart_puts("\n\r UART OK\n\r");
for(;;){

wait(255); //debug ausgaben
uart_puts("\n\r mainloop \n\r");
wait(255);
uart_puts("i2c init \n\r");
pcf8574_init ();
uart_puts("i2c start \n\r");
pcf8574_send_start ();
uart_puts("i2c set adress \n\r");
pcf8574_send_add_rw (0X70, 0);
uart_puts("i2c send byte \n\r");
pcf8574_send_byte (0b1111111);
uart_puts("i2c stop \n\r");
pcf8574_send_stop ();





}
}

void wait(unsigned int ms)
{
unsigned int zaehler;

while (ms)
{
zaehler = F_CPU / 5000;
while (zaehler)
{
asm volatile ("nop");
zaehler--;
}
ms--;
}
}

pcf8579.c


void pcf8574_init (void)
{
TWSR =0;
/*set bus speed*/

//TWBR = 0x20;
TWBR = 0x48;
}


unsigned char pcf8574_send_start (void)
{
/*writing a one to TWINT clears it, TWSTA=Start, TWEN=TWI-enable*/
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
/*wait, until start condition has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}


void pcf8574_send_stop (void)
{
/*writing a one to TWINT clears it, TWSTO=Stop, TWEN=TWI-enable*/
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
}


unsigned char pcf8574_send_add_rw (unsigned char address, unsigned char rw)
{
/*address can be 0 .. 8; rw=0 --> write, rw=1 --> read*/
unsigned char addr_byte = 0;
/*shift address one bit left*/
addr_byte = address << 1;
/*set RW-Bit, if necessary*/
addr_byte |= rw;
/*0b0111xxx0 --> address of Expander pcf8574AP */
addr_byte |= 0b01110000;
/*TWDR contains byte to send*/
TWDR = addr_byte;
/*send content of TWDR*/
TWCR = (1<<TWINT) | (1<<TWEN);
/*wait, until address has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}


unsigned char pcf8574_send_byte (unsigned char byte)
{
/*TWDR contains byte to send*/
TWDR = byte;
/*send content of TWDR*/
TWCR = (1<<TWINT) | (1<<TWEN);
/*wait, until byte has been sent --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWSR;
}


unsigned char pcf8574_read_byte (void)
{
/*send content of TWDR; TWEA = enable ACK*/
TWCR = (1<<TWINT) | (1<<TWEA) | (1<<TWEN);
/*wait, until byte has been received --> ACK*/
while (!(TWCR & (1<<TWINT)));
return TWDR;
}


unsigned char pcf8574_get_inputs (unsigned char address)
{
pcf8574_init ();
pcf8574_send_start ();
pcf8574_send_add_rw (address, 1);
unsigned char input = pcf8574_read_byte ();
pcf8574_send_stop ();
return input;
}


void pcf8574_set_outputs (unsigned char address, unsigned char byte)
{
pcf8574_init ();
pcf8574_send_start ();
pcf8574_send_add_rw (address, 0);
pcf8574_send_byte (byte);
pcf8574_send_stop ();
}



hab ich das TWBR richtig eingestellt?

danke für euere mühe

servusssss

linux_80
05.05.2007, 23:54
Hallo,

wenn die Sache sowieso beim Start hängenbleibt, könntest Du mal mit einem Multimeter die Pegel der beiden Leitungen messen.
Also, wenn nix los ist, sind beide bei ca. 5V, nach dem Start sollte SCL weiterhin High sein, SDA aber Low !

Das mit TWBR sollte schon passen. SCL 100kHz bei 16MHz

Du solltest nach jeder Aktion noch den Status von TWSR ausgeben, bzw. vor jeder Aktion überprüfen ob man auch weitermachen kann, nicht einfach der Reihe nach alles raussenden, so geht das nicht !

Einfach er wird es eine fertige Lib einzubauen:
http://homepage.hispeed.ch/peterfleury/avr-software.html#libs

servusssss
06.05.2007, 12:47
hallo linux_80,

danke für deinen tipp mit dem multimeter dadurch hab ich den Fehler gefunden

die SCL hatte einen verbindung zu GND ](*,) ](*,)

sg servusssss