PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Probleme mit Atmega über FT232 an USB



xrzr
28.02.2015, 09:26
Guten Tag,

ich bin dabei eine Verbindung von einem ATMEGA 1284 über UART / FT232 an den USB zu meinem Pc herzustellen.

Mein Ziel ist es:
Die Übertragung von zwei Arrays (ASCII) an meinen PC. Ich habe erst ein int_16t Array geffüllt mit random Zahlen und diese dann in ASCII gewandelt und mit einem Trennzeichen 'x' versehen.

Mein PC erkennt das eigene Board. Wenn ich HTERM öffne bekome ich mich auch Verbunden nur erhalteich keine Daten. Ich bekomme garnichts angezeigt.

Ich habe im Programm nach dem senden ma meine LED´s die auf den Board sind angesteuert. Die Leuchten dann auch alle ca. 25sekunden auf.

Muss ich vlt in der Fuses was einsellen?
An den RX von dem FT232 geht der TX von Atmega. Spricht gekreuzt habe ich.

29899
29900


Quelltext:




#define F_CPU 14745600UL // CPU Taktfrequenz
#include <util/delay.h> //
#include <avr/io.h> //
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>




///////////// ---- Baudrate ---- /////////////

#define BAUD 9600UL // Baudrate

// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif



///////////// ---- Initalisiere UART ---- /////////////

void uart_init(void) {
UBRR0H = UBRR_VAL >> 8;
UBRR0L = UBRR_VAL & 0xFF;

UCSR0B |= (1<<TXEN0) |(1<<RXEN0); // UART TX / RX einschalten
UCSR0C = (1<<UMSEL01)|(1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
}



///////////// ---- UART Senden ---- /////////////


int uart_putc(unsigned char sende) {
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{
}

UDR0 = sende; /* sende Zeichen */
return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s){
while (*s)
{ /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
uart_putc (*s);
s++;
}
}




///////////// ---- MAIN ---- /////////////


int main(void)
{
DDRC = 0xFF;
int16_t zw = 0; //interner Schleifenzähler

int16_t sendeDaten1 [5]; //WErte Array1
int16_t sendeDaten2 [5]; //WErte Array2
char daten1 [31]; //Sende Array1 --> [x32000x12345x67890x......]
char daten2 [31]; //Sende Array2

uart_init();

while (1) {

for (int16_t i=0; i<6; ++i){

sendeDaten1 [i] = rand() % 100; //Zufallswerte in das 1. werte Array
sendeDaten2 [i] = rand() % 100; //Zufallswerte in das 2. werte Array

daten1[zw] = 'x'; //Trennzeichen x vor jeden WErt
daten2[zw] = 'x'; //Trennzeichen x vor jeden WErt

itoa (sendeDaten1 [i], daten1[zw+1], 10);
itoa (sendeDaten1 [i], daten2[zw+1], 10);

zw = zw+6; //
}


uart_puts( daten1 ); //erste daten Array als ASCII senden
uart_puts( daten2 ); //zweites daten Array als ASCII seden




///// Test Routine ´LED Test ///////

PORTC |= (1<<PC0); // Ausgang auf 1
_delay_ms(15);
PORTC |= (1<<PC1);
_delay_ms(15);
PORTC |= (1<<PC2);
_delay_ms(15);

PORTC &= ~(1<<PC0); // Ausgang auf 0
_delay_ms(15);
PORTC &= ~(1<<PC1);
_delay_ms(15);
PORTC &= ~(1<<PC2);
_delay_ms(20);



}

while (1) {
;
}

return 0; // never reached
}

BMS
28.02.2015, 11:05
Hallo,
du hast noch die CKDIV8-Fuse aktiv, d.h. der ATmega teilt die Taktfrequenz nochmal durch 8.
Damit wird die Hardware auch nur 1/8 der im Programm eingestellten Baudrate erzeugen und im Terminal kommt Unsinn an.
Deaktiviere diese Fuse und teste nochmal ;)
Grüße, Bernhard

xrzr
28.02.2015, 13:35
Habe jetzt in der Fuses den Haken bei CKDIV8 entfernt.

Habe dann auch mal die Zeit bei den Test LED auf 500ms erhöht.
Jetzt blinkt mal und zu mal eine LED extrem kurz, scheinbar undkontrolliert.
Die Verbindung zu HTERm läss sich weiterhin aufbauen, erhalte jedoch keine Daten, bzw bekomme nichts angezeigt.
Wenn ich den ISP Adpater entferne, und den Controller neu starte, leuctet dann per zufall eine LED dauerhaft.

Wsk8
28.02.2015, 18:40
Wie wärs, wenn du erst einmal die LEDs im 1s Takt zum blinken bringst? Dann können wir auch über die komplizierteren Themen reden. ;)



#define F_CPU 14745600UL
#include <util/delay.h>
#include <avr/io.h>




int main(void) {
DDRC = 0xFF;


while(1) {
PortC |= (1<<PC0) | (1<<PC1) | (1<<PC2);
_delay_ms(1000);

PortC &= ~((1<<PC0) | (1<<PC1) | (1<<PC2));
_delay_ms(1000);
}

return 0;
}


mfg

xrzr
28.02.2015, 19:24
In einem anderen Programm habe ich bereits diese Funktion getestet. (LED)
Habe jetzt ebefalls in diesem Programm mal die Test Routine für die LED´s in einer seperaten while (1) Schleife direkt nach der initalisierung geschaltet. Funktoniert.

Habe aber jetzt die LED Test routine wieder direkt nach dem UART sende Befehl.

Ist in der Fuses der Hacken bei CKDIV8 NICHT gesetzt blinkt auch nichts. Ist der Hacken gesetzt, so funktioniert die LED test Routine aber wesentlich langsamer als die eingestellte zeit.
Die LED Test routine habe ich nur als HILFE ob das Programm die Zeile abarbeitet.

!! Aber um die LED´s geht es mir nicht. Mir geht es um die UART Verbindung. !!

- - - Aktualisiert - - -

Nah wie vor, bekomme ich in HTERM nichts angezeigt. Verbindung geht wohl, aber nichts angezeigt, kann es sein das ich bei HTERM auch noch was einstellen muss?

Aber wenn die LED Testroutine nicht funktioniert, dann ist ja generell schonmal etwas nicht i.O.

Wsk8
28.02.2015, 19:56
!! Aber um die LED´s geht es mir nicht. Mir geht es um die UART Verbindung. !!
!! Aber es hat keinen Sinn, beim Uart weiter zu machen wenn nicht mal sowas simples funktioniert !!

mfg

xrzr
28.02.2015, 19:58
Wie gesagt, die LED´s funktionieren, nur wenn ich sie hinter den UART befehl setzte funktionieren sie nicht.

Habe noch zwei Warnings, wovon könnten diese kommen:
../UART.c:92: warning: passing argument 2 of 'itoa' makes pointer from integer without a cast
../UART.c:93: warning: passing argument 2 of 'itoa' makes pointer from integer without a cast

Wsk8
28.02.2015, 20:04
Wie gesagt, die LED´s funktionieren, nur wenn ich sie hinter den UART befehl setzte funktionieren sie nicht.


Ist der Hacken gesetzt, so funktioniert die LED test Routine aber wesentlich langsamer als die eingestellte zeit.
Hört sich aber gar nicht so an...

Also, blinken die LEDs genau im 1s Takt bei _delay_ms(1000)??

mfg

xrzr
28.02.2015, 20:09
Nein wesentlich langsamer, tippe auf so ca. knapp 2sek.
Wenn ich CKDIV8 den hacken setzte entsprechend noch langsamer.

Wsk8
28.02.2015, 20:13
CKDIV8 nicht setzen und im sourcecode 8MHz bei f_cpu angeben. Dann nochmal testen.

mfg

xrzr
28.02.2015, 20:16
habe bei define F_CPU jetzt 8000000UL angegeben. imemr noch das selbe.

- - - Aktualisiert - - -

CKDIV ist entfernt.

Wsk8
28.02.2015, 20:26
Dann flasht du die falsche Datei! Bei so einer großen Änderung der Frequenz kann es nicht gleich bleiben.

mfg

xrzr
28.02.2015, 20:34
Mittels Stoppuhr ist die Zeit bei 8MHz etwa 1,5sek und bei 14745600Hz etwa 2sek

- - - Aktualisiert - - -

Muss ich die Datei auch im Eeprom laden?

Wsk8
28.02.2015, 20:45
Ist die An- UND Auszeit ca. 2sec oder An 2s und Aus 2s?

mfg

xrzr
28.02.2015, 21:07
Die an und die aus zeit 2sek. also spricht doppelt so lang wie laut Programm sein soll

Wsk8
28.02.2015, 21:19
ne, 2sec für beide passt. Dann stimmen die 14MHz.

mfg

xrzr
01.03.2015, 10:08
ne nicht ganz, ein wechsel eienr LED wo ein delay von 1 sek laut programm sein soll dauert in echtzeit ca 2sek.

Da scheint ja schonmal das generelle Prolem zu sein. Woran könnt das liegen? Mal ganz bei 0 angefangen..

- - - Aktualisiert - - -

Ich habe noch ein zweites Baord, welches ähnlich aufgebaut ist, jedoch keinen FT232 hat. Bei diesem Board (auch Atmega 1284P) stimmt das mit der Zeit, da Blinkt die LED genau so wie die Zeit eingestellt ist.

Wsk8
01.03.2015, 14:23
Laut deinen Fuses hast du einen externen Quarz am µC? Und der läuft mit 14,x MHz? Dann sollte das Programm mit der Einstellung eigentlich auch richtig laufen.

mfg

xrzr
01.03.2015, 14:43
ja das ist korrekt.
Tut es aber Merkwürdigerweise nicht.
Liegt es vlt daran das ich als Spannungsversorgung Baterrien habe (Spannungsregler auf 5V)?

- - - Aktualisiert - - -

Habe jetzt nochmal ein neues Programm angelegt wo ich nur einen LED Test mache. Dort blinkt die LED jetzt mit total unterschiedlichen Zeiten. Mal länger mal kürzer.

Wsk8
01.03.2015, 14:53
Nein, 5V passen. Poste mal deinen aktuellen Code.

mfg

xrzr
01.03.2015, 15:00
Habe jetzt mit einer etwas größeren Lupe alle Lötstellen überprüft und zwei nachgelötet, obwohl die gut aussahen. Jetzt geht es. Zeiten passen.
Danke schonmal.

Jedoch klappt das mit HTERM noch nicht. Bekomme dort nichts angezeigt.


Hier nochmal mein Code. Passt das unten vor der LED Routine mit dem "uart_puts ( ARRAY ); mit dem Array senden?





#define F_CPU 14745600UL // CPU Taktfrequenz
#include <util/delay.h> //
#include <avr/io.h> //
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>




///////////// ---- Baudrate ---- /////////////

#define BAUD 9600UL // Baudrate

// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.

/*
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
#endif
*/


///////////// ---- Initalisiere UART ---- /////////////

void uart_init(void) {
UBRR0H = UBRR_VAL >> 8;
UBRR0L = UBRR_VAL & 0xFF;

UCSR0B |= (1<<TXEN0) |(1<<RXEN0); // UART TX / RX einschalten
UCSR0C = (1<<UMSEL01)|(1<<UCSZ01)|(1<<UCSZ00); // Asynchron 8N1
}



///////////// ---- UART Senden ---- /////////////


int uart_putc(unsigned char sende) {
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{
}

UDR0 = sende; /* sende Zeichen */
return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s){
while (*s)
{ /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
uart_putc (*s);
s++;
}
}




///////////// ---- MAIN ---- /////////////


int main(void) {

DDRC = 0xFF;
int16_t zw = 0; //interner Schleifenzähler

int16_t sendeDaten1 [5]; //WErte Array1
int16_t sendeDaten2 [5]; //WErte Array2
char daten1 [31]; //Sende Array1 --> [x32000x12345x67890x......]
char daten2 [31]; //Sende Array2

uart_init();



while (1) {

for (int16_t i=0; i<6; ++i){

sendeDaten1 [i] = rand() % 100; //Zufallswerte in das 1. werte Array
sendeDaten2 [i] = rand() % 100; //Zufallswerte in das 2. werte Array

daten1[zw] = 'x'; //Trennzeichen x vor jeden WErt
daten2[zw] = 'x'; //Trennzeichen x vor jeden WErt

itoa (sendeDaten1 [i], daten1[zw+1], 10);
itoa (sendeDaten1 [i], daten2[zw+1], 10);

zw = zw+6; //
}


uart_puts( daten1 ); //erste daten Array als ASCII senden
uart_puts( daten2 ); //zweites daten Array als ASCII seden

while (1){

///// Test Routine ´LED Test ///////

PORTC |= (1<<PC0); // Ausgang auf 1
_delay_ms(100);
PORTC |= (1<<PC1);
_delay_ms(100);
PORTC |= (1<<PC2);
_delay_ms(100);

PORTC &= ~(1<<PC0); // Ausgang auf 0
_delay_ms(100);
PORTC &= ~(1<<PC1);
_delay_ms(100);
PORTC &= ~(1<<PC2);
_delay_ms(100);
}

}
}

Wsk8
01.03.2015, 15:14
Versuchs erstmal mit was ganz einfachem.



int main(void) {
uart_init();


while(1) {
uart_putc('A');
_delay_ms(200);
}

return 0;
}


mfg

- - - Aktualisiert - - -

Und du darfst

(1<<UMSEL01)
nicht setzen!

mfg

xrzr
01.03.2015, 16:43
'A' bekomme ich Übertragen. Das ASCII Array uart_puts( daten1 ); und uart_puts( daten2 ); nicht.

Wsk8
01.03.2015, 17:10
Wieder viel zu kompliziert.



int main(void) {
int8_t i; //interner Schleifenzähler


int16_t sendeDaten1[5]; //WErte Array1
char daten1[20]; //Sende Array1 --> [x32000x12345x67890x......]


uart_init();


while (1) {
for (i=0; i<5; i++){


sendeDaten1[i] = rand() % 100; //Zufallswerte in das 1. werte Array


sprintf(&daten1[i*3], "x%d", sendeDaten1[i]);
}


//printf("%s\n", daten1);
uart_puts(daten1); //erste daten Array als ASCII senden
}


return 0;
}


mfg

xrzr
01.03.2015, 19:25
Die Übertragung zu HTERM funktioniert.
Buchstaben kommen enstrpechend an. Das Array wird auch gesendet, Habe jetzt das Array an jeder Stelle mit der gleichen Zahl gefüllt.
Jedoch jetzt zwei Bugs:
1. ist jede Übertragene Array Zahl in HTERM anders
2. Die Zahl die in HTERM angezeigt wird (z.B. "-24401" enstspricht nicht der gesendeten INT 111.

Habe beim Wandeln ITOA darauf geachtet das die Puffer Variable [6] groß ist, da INT 5 stellen hat plus "/0".

Wsk8
01.03.2015, 20:15
Sry, aber das WLAN-Modul von meiner Glaskugel ist kaputt. Musst den Sourcecode leider selbst posten.:MistPC

mfg