Hallo Frank und ihr lieben Zuschauer,
ich fasse mal alles zusammen.
Ich möchte mit einem Atmega32 das RN-MotorCtrl (MC) steuern(RS232). Der Atmega selber bekommt seine Vorgaben vom I2C Master (Brain).
Für die RS232 Datenübertragung vom Atmega32(Slave) zum MC verwende ich die Bibliothek von Peter Fleury, die funktioniert auch ohne Probleme. Ich habe die Funktionen von Peter Fleury um ein Funktion uart_getcWait(int Timeout) erweitert. Das funktioniert auch, da bin ich mir zu 99.9% sicher.
UART Wait:
Der UART0 Interrupt wird erzeugt wenn ein Zeichen empfangen wurde. In diesem Interrupt hab ich einen globalen Counter, den ich bei jedem Interrupt hochzähle. Wenn ich nun uart_getcWait aufrufe wartet die Funktion solange bis der Counter größer als 0 wird. Nachdem die Funktion ein Char aus dem Buffer geholt hat, wird der Counter wieder um eins verringert. Meines erachtens funktioniert das auch.
Code:
unsigned int uart_getcWait(int timeout)
{
unsigned char tmptail;
unsigned char data;
int i=0;
while(rcvUart0Counter==0)
{
if(i>=timeout)
{
return 0;
}
i++;
_delay_ms(1);
}
if(rcvUart0Counter>0)
rcvUart0Counter--;
if ( UART_RxHead == UART_RxTail ) {
return 0; /* no data available */
}
/* calculate /store buffer index */
tmptail = (UART_RxTail + 1) & UART_RX_BUFFER_MASK;
UART_RxTail = tmptail;
/* get data from receive buffer */
data = UART_RxBuf[tmptail];
return (UART_LastRxError << 8) + data;
}/* uart_getcWait */
Physikalische Verbindung zwischen Mc und Atemga32:
Anfangs habe ich einen Max232 verwendet für die Datenübertragung. Ausserdem kann man ja auch schell das PC-Steuerungsprogramm anschließen. Um aber den Max aus Fehlerquelle auszuschließen habe ich den Max vom MC entfernt und direkt an den Atmega angeschlossen(Uart<->Uart). Leider hat sich nix geändert.
Nun meine Code zum senden an die MC:
Code:
#include "lib/I2CSlave.h"
#define Timeout 500
int uart_checkResults(){
int result[10];
int i;
//Wenn alles klappt kommt 99 zurück
// 2 Bytes müssen zurück kommen
result[0]=uart_getcWait(Timeout);
result[1]=uart_getcWait(Timeout);
//Lampen für Fehleranzeige
if(result[0]==99 || result[1]==254){
PORTA = resetBit(PORTA,0);
return true;
}else{
PORTA = setBit(PORTA,0);
}
//Lampen für Fehleranzeige
if(result[1] == 254){
PORTA = setBit(PORTA,1);
}else{
PORTA = resetBit(PORTA,1);
}
if(result[0]==5 || result[0]==1 || result[0]==2 || result[0]==3 || result[0]==4|| result[0]==6 || result[0]==20){
PORTA = setBit(PORTA,7);
txbuffer[0]='R';
}else{
PORTA = resetBit(PORTA,7);
}
if(result[0]==0){
PORTA = setBit(PORTA,3);
txbuffer[0]='R';
}else{
PORTA = resetBit(PORTA,3);
}
LEDS = resetBit(LEDS,LED1);
return false;
}
void uart_setMotorSpeed(int a,int b){
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 3);
uart_putc((char) 2);
uart_putc((char) a);
uart_putc((char) b);
}while(!uart_checkResults());
};
void uart_setDirection(int a,int b){
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 3);
uart_putc((char) 5);
uart_putc((char) a);
uart_putc((char) b);
}while(!uart_checkResults());
};
uint8_t uart_getReasonMotorStop(){
char res[1];
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 1);
uart_putc((char) 43);
res[0]=uart_getcWait(Timeout); //Solange warten bis Datenempfangen wurden
}while(!uart_checkResults());
return res[0];
};
//a->Motorwahl b-> LowByte c-> HighByte
void uart_setMotorControlSpeed(int a,int b,int c){
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 4);
uart_putc((char) 3);
uart_putc((char) a);
uart_putc((char) b);
uart_putc((char) c);
}while(!uart_checkResults());
};
//a -> Motorwahl
void uart_resetPath(int a){
int i;
do{
for(i=0;i<=9;i++) uart_getc();
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 2);
uart_putc((char) 4);
uart_putc((char) a);
}while(!uart_checkResults());
};
//a -> Motorwahl --Rückgabe 2 Bytes -> 1. LowByte 2. HighByte
long uart_getMotorCurrent(int a){
char res[10];
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 2);
uart_putc((char) 40);
uart_putc((char) a);
res[0]=uart_getcWait(Timeout); //Solange warten bis Datenempfangen wurden
res[1]=uart_getcWait(Timeout);
}while(!uart_checkResults());
return TOWORD(res[0],res[1]);
};
//a -> Motorwahl --Rückgabe 2 Bytes -> 1. LowByte 2. HighByte
long uart_getRevolutionPerMin(int a){
char res[2];
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 2);
uart_putc((char) 41);
uart_putc((char) a);
res[0]=uart_getcWait(Timeout); //Solange warten bis Datenempfangen wurden
res[1]=uart_getcWait(Timeout);
}while(!uart_checkResults());
return TOWORD(res[0],res[1]);
};
//a -> Motorwahl --Rückgabe 4 Bytes -> 1. LowWord Low 2. LowWord High 3. HighWord Low 4. HighWord High
uint32_t uart_getPath(int a){
char res[4];
do{
uart_putc((char) 35);
uart_putc((char) 35);
uart_putc((char) 2);
uart_putc((char) 42);
uart_putc((char) a);
res[0]=uart_getcWait(Timeout); //Solange warten bis Datenempfangen wurden
res[1]=uart_getcWait(Timeout);
res[2]=uart_getcWait(Timeout);
res[3]=uart_getcWait(Timeout);
res[4]=uart_getcWait(Timeout);
}while(!uart_checkResults());
return TODWORD(res[0],res[1],res[3],res[4]);
};
Diese Funktionen sollen die Kommunikation übernehmen. Der einzelne Befehl soll dabei solange an die MC gesendet werden bis die richtigen Zeichen zurückkommen. Datenblatt: 1. Byte-> Fehlercode, 2. Byte 254
Vielleicht seht ihr einen Fehler.
@Frank: Was ist mit dem W4. Du liest bestimmt beim "Einstellung lesen" (PC-Steuerprog) den EEPROM aus. Steht W4 wirklich für die Einstellung der Encoder.
Lesezeichen