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