Hallo,
ich beschäftige mich seit ein paar Wochen mit Mikrocontroller
Programmierung und verwende dazu einen ATMEGA328PB welcher auf einem
Board über UART mit dem Rechner kommuniziert. (Eigentlich sind es insg.
10 Mikrocontroller aber für das beschriebene Problem sollte nur der
Master Controller relevant sein)
Im eigentlichen Skript geht es darum einen Datensatz mit Positionswerten
zu generieren, aber ich bin auf einen Fehler gestoßen welcher den
Mikrokontroller abstürzen lässt (zumindest springt er in die Main
zurück).
Der Fehler ist auch mit dem unten aufgeführten Minimalbeispiel
vorführbar, daher muss ich scheinbar irgendwas fundamentales
missverstehen das nichts mit der Wertgenerierung an sich zu tun hat.
Im aktuellen Zustand gibt das Skript des mikrokontrollers beim Start die
Standardmeldung "Master ready" über UART aus und ich erhalte die Ausgabe
über hTerm am Rechner.
Dann geht das Skript in eine Warteschleife in der es auf einen
beliebigen Input über UART wartet.
Sobald ich irgendein Zeichen sende müsste die generate_ramp Funktion
durchlaufen und mit der Ausgabe "Exit function" abschließen.
Das tut sie auch, allerdings nur für ramp_freq >= 2.0
Für ramp_freq <= 1.0 stürzt das Skript ab und der Kontroller startet
neu, was sich dadurch äußert, dass wieder die Standardmeldung "Master
ready" ausgegeben wird.
Der "tolerierbare Bereich" rutscht tiefer wenn ich die globale Variable
DATA_FREQ auf 256 setze, dann gehen also auch Werte zwischen 1.0 und 2.0
aber nicht kleiner 1.0.
Ich habe also versucht manuell Werte für seq_Length vorzugeben und dabei
festgestellt:
- Werte <= 452 funktionieren problemlos
- Werte >= 453 führen zu fehlerhafter UART Ausgabe aber es sind
korrekte Zeichen dabei
- Werte zwischen 456 und 506 führen zu einer Endlosschleife der UART
Ausgabe)
- Werte >= 507 führen zum altbekannten Neustart
Gebe ich den Wert von seq_Length direkt ohne Variable vor so
funktioniert
das Skript problemlos auch für Werte weit über 512.
Ich hoffe ich habe alles beschrieben was hilfreich sein kann und dass
irgendwer besser versteht was hier vor sich geht.
Für hilfreiche Kommentare wäre ich sehr dankbar.
1 | #include <stdlib.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <util/delay.h>
|
5 | #include <time.h>
|
6 | #include <stdbool.h>
|
7 | #include <stdint.h>
|
8 | #include "uart.h"
|
9 | #include "linsin16.h"
|
10 |
|
11 | /* define CPU frequency in Hz in Makefile */
|
12 | #ifndef F_CPU
|
13 | #error "F_CPU undefined, please define CPU frequency in Hz in Makefile"
|
14 | #endif
|
15 |
|
16 | /* Define UART buad rate here */
|
17 | #define UART_BAUD_RATE 200000 //115200
|
18 |
|
19 | #define RESET PC4
|
20 | #define RESET_SLAVES {(PORTC |= (1 << RESET)); (DDRC |= (1 << RESET)); _delay_ms(100); (PORTC &= ~(1 << RESET)); _delay_ms(100);}
|
21 |
|
22 | #define T_TRIGGER_512 37499
|
23 | #define T_TRIGGER_256 9374
|
24 | #define DATA_FREQ_512 (19200000/(T_TRIGGER+1))
|
25 | #define DATA_FREQ_256 (2400000/(T_TRIGGER+1))
|
26 |
|
27 | #define T_TRIGGER T_TRIGGER_512
|
28 | #define DATA_FREQ DATA_FREQ_512
|
29 |
|
30 | /***********************************************
|
31 | Functions
|
32 | ***********************************************/
|
33 | struct Pos_Array { uint8_t data[4];};
|
34 |
|
35 | void generate_ramp(float ramp_freq){
|
36 |
|
37 | int seq_Length = (int)((float)DATA_FREQ/ramp_freq);
|
38 | //int seq_Length >= 507; // Klappt nicht
|
39 | //int seq_Length >= 453; // Klappt aber nicht richtig
|
40 | //int seq_Length = 452; // Klappt
|
41 | struct Pos_Array ramp_pos_arr[seq_Length];
|
42 |
|
43 | for(int i=0;i<seq_Length;i++){
|
44 | ramp_pos_arr[i].data[0] = 0x00;
|
45 | }
|
46 |
|
47 | uart_puts("Exit function");
|
48 | uart_puts("\r\n");
|
49 | return;
|
50 | }
|
51 |
|
52 |
|
53 | int main(void)
|
54 | {
|
55 | uint16_t c;
|
56 |
|
57 | RESET_SLAVES; // Sets reset signal for other controllers
|
58 |
|
59 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); // Initialize UART library, pass baudrate and AVR cpu clock with the macro
|
60 |
|
61 | sei(); // Enable interrupt, since UART library is interrupt controlled
|
62 |
|
63 | uart_puts("Master ready");
|
64 | uart_puts("\r\n");
|
65 |
|
66 | for(;;){
|
67 | do{
|
68 | c = uart_getc();
|
69 | if ( c & UART_NO_DATA ){/* no data available from UART*/}
|
70 | else{
|
71 | generate_test( 1.0);
|
72 | }
|
73 | }while (!( c & UART_NO_DATA ));
|
74 | }
|
75 | uart_puts("Exit Main");
|
76 | uart_puts("\r\n");
|
77 | }
|