Hallo
Zur Übertragung mit USI zwischen einem Master (Atmega1284p) und einem Slave (Attiny2313) verwende ich USI. Vom Master zum Slave geht es ohne Probleme. Vom Slave zum Master geht es nicht. Verwende zusätzlich noch ein LCD zur Anzeige von Text und Daten. Vielleicht jemand von euch Idee woran es liegt.
Code für den Master:
CodeBox C
Code für den Slave:
CodeBox C
Vielleicht hat jemand eine Idee dazu.
achim
Zur Übertragung mit USI zwischen einem Master (Atmega1284p) und einem Slave (Attiny2313) verwende ich USI. Vom Master zum Slave geht es ohne Probleme. Vom Slave zum Master geht es nicht. Verwende zusätzlich noch ein LCD zur Anzeige von Text und Daten. Vielleicht jemand von euch Idee woran es liegt.
Code für den Master:
CodeBox C
#include <stdbool.h>
#include <avr/pgmspace.h>
#include "main.h"
#include <util/delay.h>
#include "i2clcd.h"
#include "i2cmaster.h"
#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"
#define slave_adresse 0x52 // Slave Adresse schreiben
#define slave_adresse_r 0x53 // Slave Adresse lesen
uint8_t ret; // Kontrollvariable ob Slave vorhanden
uint8_t byte1, byte2; // Daten zum Senden vom Master zu Slave
uint8_t byte3, byte4;
uint8_t byte10; // Daten zum holen vom Slave zu Master
uint8_t wert;
///////////////////////////////////////////////////////////////////////////////////////////////////
void startanzeige() // Titelbild
{
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // Warte 2ms
lcd_printlc(1,2,"USI Bus M-Prg1"); // Zeile 1
lcd_printlc(2,2,"Verbindung von"); // Zeile 2
lcd_printlc(3,2,"Prz ueber I2C "); // Zeile 3
lcd_printlc(4,2,"(by P.)"); // Zeile 4
_delay_ms(3000); // Warte 5000ms
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void slavetest() // Abfrage Slave, Fehlermeldung und Anzeige
{ // Abfarge ob Slave vorhanden ist
ret = i2c_start(slave_adresse); // Start i2C mit Adresse Slave
i2c_write(0x00); // Sende Daten
i2c_stop(); // I2C Stop
if (ret == 0) // Bus ok - 0, kein Bus 1
{ // Anzeige Slave ok
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // Warte 2ms
lcd_printlc(2,4,"Slave ist "); // Ausgabe Text
lcd_printlc(3,5,"OK !!!!!"); // Slave OK
_delay_ms(2000); // Warte 2s
}
else // Fehlermeldung
{ // Anzeige Slave nicht ok
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // Warte 2ms
lcd_printlc(2,5,"Slave ist"); // Ausgabe Schrift
lcd_printlc(3,5,"Nicht OK"); // Slave Nicht O
_delay_ms(2000); // Warte 2s
}
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // Warte 2ms
lcd_printlc(1,1,"Taste aus "); // Ausgabe Text
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
void s_write (uint8_t wert) // schreibe Daten 2 von Master zu Slave
{
i2c_start(slave_adresse); // Slave ist bereit zum Schreiben
i2c_write(0x00); // Buffer Startadresse setzen
i2c_write(wert); // Drei Bytes schreiben... 43
i2c_stop(); // Zugriff beenden
}
/////////////////////////////////////////////////////////////////////////////////////////////////
void s_read1() // lese Slave1
{
i2c_start(slave_adresse); // Start Bus schreiben
i2c_write(0x00);
i2c_rep_start(slave_adresse); // starte Slave lesen
byte3=i2c_readAck(); // 2. Byte lesen und in "gelesen" ablegen
byte4=i2c_readNak(); // letztes Byte lesen, darum kein ACK
i2c_stop(); // Zugriff beenden
}
////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
cli(); // Interrupts deaktiviert
i2c_init(); // Starte I2C Bus
lcd_init(); // Starte I2CLCD
// Display Befehle
lcd_command(LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKINGOFF);
lcd_light(0); // Licht an
startanzeige();
lcd_command(LCD_CLEAR); // Leere Display
_delay_ms(2); // Warte 2ms
slavetest();
_delay_ms(2);
DDRC=0b01100000; //Taster // setzt Port C auf Ausgang, PC5 und PC6
DDRA=0b11111111; //LED // setzt Port A auf Ausgang, PC5 und PC6
PORTC|=0b01001111; //Taster // Deaktiviere Ports C5-6 (LEDs aus)
PORTA|=0b11111111; //LED // Deaktiviere Pins A0-7 (LEDs aus)
while(1)
{
// ========>> AUF GELESENE DATEN REAGIEREN
s_read1();
if (byte4 == 30)
{ // Wenn Wert 30 gelesen wurde...
PORTC &= ~((1<<PINC5)); // schalte Port A6
PORTC |=(1<<PINC6); // wenn nicht lösche Port A6
}
else
{
PORTC |=(1<<PINC5); // wenn nicht lösche Port A6
PORTC &= ~((1<<PINC6)); // schalte Port A6
}
/*if (byte4 == 40)
{ // Wenn Wert 40 gelesen wurde...
//PORTC &=~(1<<PINC6); // schalte Port A7 ein
}
else
{
//PORTC |=(1<<PINC6); // wenn nicht lösche
} */
///////////////////////////////////////////////////////////////////////////////////////////////
// ========>> TASTENEINGABEN T1
if (!(PINC & (1<<PINC2)) ) // Taster T1
{ // Wenn T1 gedrückt...
PORTA &=~(1<<PINA2); // LED 2 A1 ein
s_write(42); // Schreib 1 Funktion aufrufen
lcd_printlc(1,1,"Taste 1 "); // Ausgabe Text
}
else
{
PORTA |=(1<<PINA1); // sonst LED 2 A1 aus
}
// ========>> TASTENEINGABEN T3
if (!(PINC & (1<<PINC4)) ) // Taster T 3
{ // Wenn T3 gedrückt...
PORTA &=~(1<<PINA1); // LED 3 A2 ein
s_write(43); // Schreib 2 Funktion aufrufen
lcd_printlc(1,1,"Taste 2 "); // Ausgabe Text
}
else
{
PORTA |=(1<<PINA2); // sonst LED 3 aus
}
/////////////////////////////////////////////////////////////////////////////////////////////////
/* // vom Slave lesen
if (!(PINC & (1<<PINC3)) ) // Taster T2 mitte
{ // Wenn T 2 gedrückt...
PORTC &=~(1<<PINC5); // LED 6 A5 ein
//s_read1(); // ...Lese-Funktion aufrufen
}
else
{
PORTC |=(1<<PINC5); // LED 6 A5 aus
}*/
}
}
Code für den Slave:
CodeBox C
#define F_CPU 16000000UL
#include <stdlib.h> // für den Ati 2313A im usiTwiSlave.c A zufügen
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "usiTwiSlave.h"
#define slave_adresse 0x52 // Adresse Slave
uint8_t byte1, byte2, byte3, byte4;
uint16_t buffer;
int main(void)
{
cli(); // Interrupts aus
usiTwiSlaveInit(slave_adresse); // Init TWI slave
sei(); // Interrupts ein
DDRD=0b00111000; // setze Taster + LED DDR D
//DDRB=0b10100111; // setze LED DDR B
PORTD|=0b00111000; // setze Taster + LED Port D
//PORTB|=0b00000111; // setze LED Port B
while(1)
{
byte1 = rxbuffer[0]; // schreibe Daten in den Eingangspuffer
byte2 = rxbuffer[1];
///////////////////////////////////////////////////////////////////////
if (byte1==43) // Abfrage byte1 auf 43
{ // wenn dann ...
PORTD &=~(1<<PIND5); // LED 2 B1 ein
PORTD |=(1<<PIND4); // LED 3 B2 aus
}
if (byte1==42) // Abfrage byte1 auf 42
{ // wenn dann ...
PORTD &=~(1<<PIND4); // LED 3 B2 ein
PORTD |=(1<<PIND5); // LED 2 B1 aus
}
//////////////////////////////////////////////////////////////////////
if (PIND & (1<<PIND0)) // Taster T2 PD0
{ // Wenn T1 gedrückt...
byte3=40; // setze byte3 auf 40
PORTD |=(1<<PIND3); // LED 4 D5 aus
}
else
{
PORTD &=~(1<<PIND3); // LED 4 D5 ein
byte4=30; // setze byte4 auf 30
}
txbuffer[0]=byte3; // byte10 in den Sendepuffer auf [0]
txbuffer[1]=byte4;
} // end.while
} // end.main
Vielleicht hat jemand eine Idee dazu.
achim