TobeFFM
16.11.2008, 19:53
Hi Leute!
Ich hab mir mit nem Atmega8 ne kleine Erweiterung gebaut. Da hängt ein LCD dran, und ich will von der Base Nachrichten hinschicken, die dann auf dem LCD ausgegeben werden.
Ich hab den TWI-Master-Code und header im Base-Projekt eingebunden, und den TWI-Slave-Code und header in meinen Code und Makefile für den Atmega8.
Ich habe mal testweise im Atmega8 readRegisters mit Werten befüllt, und kann diese auch erfolgreich von der Base auslesen. Nur, wenn ich versuche von der Base was in die writeRegisters zu schreiben, kommt dort anscheinend nichts an (Funktion aus Anleitung: transmit3Bytes(SlaveAddr, Reg#, data1, data2).
Hier ist der Code, der auf der Base läuft (abgespeckt, da läuft noch Example07, die State-Machine drauf):
#include "RP6RobotBaseLib.h"
#include "RP6I2CmasterTWI.h"
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("\nI2C ERROR - TWI STATE: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
int main(void)
{
initRobotBase();
// I2C Master initialisieren
I2CTWI_initMaster(100);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
powerON();
while(true)
{
// versuche, was zu schreiben
I2CTWI_transmit3Bytes(15, 0, 1, 3);
//versuchen was zu lesen, Register 0-3:
//I2CTWI_transmitByte(15, 0);
uint8_t results[ 4];
I2CTWI_readBytes(15, results, 3);
writeString_P("\n Empfangen (0-3): ");
for(int i=0; i<3; i++){
writeInteger(results[i], DEC);
writeString_P(" - ");
}
writeString_P("\n");
}
return 0;
}
Und hier der Code der Atmega8-LCD-Erweiterungsplatine:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include "General.h"
#include "Delay.h"
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd-routines.h"
#include "RP6I2CslaveTWI.h"
#define CMD_ZEILE_1 1
#define CMD_ZEILE_2 2
int main(void)
{
// LCD-INIT -----------------------------------
lcd_init();
lcd_string("RP6 Robo-LCD");
Delay_ms(2500);
// I2C-INIT -----------------------------------
I2CTWI_initSlave(15); // Wir haben Adresse 15!
set_cursor(0,1);
lcd_clear();
lcd_string("Waiting.....");
// MAIN-LOOP ----------------------------------
while(1)
{
// schreib mal irgendwas ins register, was ausgelesen wird
I2CTWI_readRegisters[0] = 5;
I2CTWI_readRegisters[1] = 8;
I2CTWI_readRegisters[2] = 7;
// empfangen und kein Schreibzugriff aktiv
if(I2CTWI_writeRegisters[0]!='_' && !I2CTWI_writeBusy){
// TEST
lcd_clear();
set_cursor(0,2);
lcd_string("Innere Schleife");
// speichern
char buffer[20];
uint8_t cmd = I2CTWI_writeRegisters[0];
I2CTWI_writeRegisters[0] = 0; //zurücksetzen
uint8_t param = I2CTWI_writeRegisters[1]; //Parameter
if(cmd == CMD_ZEILE_1){
lcd_clear();
set_cursor(0,1);
lcd_string("CMD Zeile 1");
Delay_ms(2500);
lcd_clear();
set_cursor(0,1);
itoa(param, buffer, 10);
lcd_string(buffer);
}else if(cmd == CMD_ZEILE_2){
set_cursor(0,2);
itoa(param, buffer, 10);
lcd_string(buffer);
}
}
}//while(1)
return 0;
}
Wie gesagt, Register werden erfolgreich ausgelesen, also ist die Verkabelung korrekt. Ich häng da jetzt seit fast zwei Tagen dran und bin kurz vorm durchdrehn, weil ichs einfach nich versteh :-)
Ich hab mir mit nem Atmega8 ne kleine Erweiterung gebaut. Da hängt ein LCD dran, und ich will von der Base Nachrichten hinschicken, die dann auf dem LCD ausgegeben werden.
Ich hab den TWI-Master-Code und header im Base-Projekt eingebunden, und den TWI-Slave-Code und header in meinen Code und Makefile für den Atmega8.
Ich habe mal testweise im Atmega8 readRegisters mit Werten befüllt, und kann diese auch erfolgreich von der Base auslesen. Nur, wenn ich versuche von der Base was in die writeRegisters zu schreiben, kommt dort anscheinend nichts an (Funktion aus Anleitung: transmit3Bytes(SlaveAddr, Reg#, data1, data2).
Hier ist der Code, der auf der Base läuft (abgespeckt, da läuft noch Example07, die State-Machine drauf):
#include "RP6RobotBaseLib.h"
#include "RP6I2CmasterTWI.h"
void I2C_transmissionError(uint8_t errorState)
{
writeString_P("\nI2C ERROR - TWI STATE: 0x");
writeInteger(errorState, HEX);
writeChar('\n');
}
int main(void)
{
initRobotBase();
// I2C Master initialisieren
I2CTWI_initMaster(100);
I2CTWI_setTransmissionErrorHandler(I2C_transmissio nError);
powerON();
while(true)
{
// versuche, was zu schreiben
I2CTWI_transmit3Bytes(15, 0, 1, 3);
//versuchen was zu lesen, Register 0-3:
//I2CTWI_transmitByte(15, 0);
uint8_t results[ 4];
I2CTWI_readBytes(15, results, 3);
writeString_P("\n Empfangen (0-3): ");
for(int i=0; i<3; i++){
writeInteger(results[i], DEC);
writeString_P(" - ");
}
writeString_P("\n");
}
return 0;
}
Und hier der Code der Atmega8-LCD-Erweiterungsplatine:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdint.h>
#include "General.h"
#include "Delay.h"
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd-routines.h"
#include "RP6I2CslaveTWI.h"
#define CMD_ZEILE_1 1
#define CMD_ZEILE_2 2
int main(void)
{
// LCD-INIT -----------------------------------
lcd_init();
lcd_string("RP6 Robo-LCD");
Delay_ms(2500);
// I2C-INIT -----------------------------------
I2CTWI_initSlave(15); // Wir haben Adresse 15!
set_cursor(0,1);
lcd_clear();
lcd_string("Waiting.....");
// MAIN-LOOP ----------------------------------
while(1)
{
// schreib mal irgendwas ins register, was ausgelesen wird
I2CTWI_readRegisters[0] = 5;
I2CTWI_readRegisters[1] = 8;
I2CTWI_readRegisters[2] = 7;
// empfangen und kein Schreibzugriff aktiv
if(I2CTWI_writeRegisters[0]!='_' && !I2CTWI_writeBusy){
// TEST
lcd_clear();
set_cursor(0,2);
lcd_string("Innere Schleife");
// speichern
char buffer[20];
uint8_t cmd = I2CTWI_writeRegisters[0];
I2CTWI_writeRegisters[0] = 0; //zurücksetzen
uint8_t param = I2CTWI_writeRegisters[1]; //Parameter
if(cmd == CMD_ZEILE_1){
lcd_clear();
set_cursor(0,1);
lcd_string("CMD Zeile 1");
Delay_ms(2500);
lcd_clear();
set_cursor(0,1);
itoa(param, buffer, 10);
lcd_string(buffer);
}else if(cmd == CMD_ZEILE_2){
set_cursor(0,2);
itoa(param, buffer, 10);
lcd_string(buffer);
}
}
}//while(1)
return 0;
}
Wie gesagt, Register werden erfolgreich ausgelesen, also ist die Verkabelung korrekt. Ich häng da jetzt seit fast zwei Tagen dran und bin kurz vorm durchdrehn, weil ichs einfach nich versteh :-)