Hallo,
Kann mir wer helfen stehe vor einem völlig komischenProblem:
Wenn ich dieses Programm ausführe und ich per UART ein M sende Startet
sich das Programm Neu: von Vorne...
Woran kann das liegen?
/*
* C2T3_v1.c
*
* Created: 28.05.2017 16:13:26
* Author : Gert
*/
#include <avr/io.h>
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
#include <util/delay.h>
#define FOSC 16000000
#define MYUBRR 51
// Globale Variablen
int Messung =0;
int Zeitintervall = 1000;
void uart_init(void)
{
cli();
//1 = output, 0 = input
// DDRB = 0b11101111; //PB4 = MISO
// DDRC = 0b11111110; //
DDRD = 0b11111110; //PORTD (RX on PD0)
//USART Baud rate: 56700
UBRR0H = (MYUBRR >> 8);
UBRR0L = MYUBRR;
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (0<<USBS0)|(3<<UCSZ00);
UCSR0A = (1<<U2X0);
// stdout = &mystdout; //Required for printf init
// UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0); // UART RX, TX und
RX Interrupt einschalten
sei();
}
// Serielle Ausgabe:
/* ATmega16 */
int uart_putc(unsigned char c)
{
while (!(UCSR0A & (1<<UDRE0))) /* warten bis Senden moeglich */
{
}
UDR0 = c; /* 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++;
}
}
volatile char uart_ausgabe[50] = "";
#define UART_MAXSTRLEN 5
volatile uint8_t uart_str_complete = 0; // 1 .. String komplett
empfangen
volatile uint8_t uart_str_count = 0;
volatile char uart_string[UART_MAXSTRLEN + 1] = "";
void USART_Flush( void )
{
unsigned char dummy;
while ( UCSR0A & (1<<RXC0) ) dummy = UDR0;
}
ISR(USART0_RX_vect)
{ //PB0 im PORTB setzen
unsigned char nextChar;
// Daten aus dem Puffer lesen
nextChar = UDR0;
if( uart_str_complete == 0 ) { // wenn uart_string gerade in
Verwendung, neues Zeichen verwerfen
PORTD |= (1 << PORTD3);
// Daten werden erst in uart_string geschrieben, wenn nicht
String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
if( nextChar != '\n' &&
nextChar != '\r' &&
uart_str_count < UART_MAXSTRLEN ) {
uart_string[uart_str_count] = nextChar;
uart_str_count++;
}
else {
PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
uart_string[uart_str_count] = '\0';
uart_str_count = 0;
uart_str_complete = 1;
}
}
}
// ADC
void ADC_Init(void)
{
// die Versorgungsspannung AVcc als Referenz wählen:
ADMUX = (1<<REFS0);
// oder interne Referenzspannung als Referenz für den ADC wählen:
// ADMUX = (1<<REFS1) | (1<<REFS0);
// Bit ADFR ("free running") in ADCSRA steht beim Einschalten
// schon auf 0, also single conversion
ADCSRA = (1<<ADPS1) | (1<<ADPS0); // Frequenzvorteiler
ADCSRA |= (1<<ADEN); // ADC aktivieren
/* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man
liest
also einen Wert und verwirft diesen, um den ADC "warmlaufen zu
lassen" */
ADCSRA |= (1<<ADSC); // eine ADC-Wandlung
while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der
Konvertierung warten
}
/* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
Wandlung nicht übernommen. */
(void) ADCW;
}
uint16_t ADC_Read( uint8_t channel )
{
// Kanal waehlen, ohne andere Bits zu beeinflußen
ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
ADCSRA |= (1<<ADSC); // eine Wandlung "single
conversion"
while (ADCSRA & (1<<ADSC) ) { // auf Abschluss der Konvertierung
warten
}
return ADCW; // ADC auslesen und zurückgeben
}
/* ADC Mehrfachmessung mit Mittelwertbbildung */
/* beachte: Wertebereich der Summenvariablen */
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
{
uint32_t sum = 0;
for (uint8_t i = 0; i < nsamples; ++i ) {
sum += ADC_Read( channel );
}
return (uint16_t)( sum / nsamples );
}
/* Beispielaufrufe: */
int main(void)
{ cli();
char Programm_gestartet[] = { "Programm gestartet" };
char Messungstartstring[] = { "Messung gestartet" };
char Messungstoppstring[] = { "Messung gestoppt" };
char Messungszeit000string[] = "Messung so schnell als möglich";
char Messungszeit100string[] = "Messung alle 100ms";
char Messungszeit500string[] = "Messung alle 500ms";
char Messungszeit1000string[] = "Messung alle 1000ms";
char Messungszeit2000string[] = "Messung alle 2000ms";
char Messungszeit5000string[] = "Messung alle 5000ms";
// Vergleichsstrings
char Messungstart[] = "M";
char Messungstopp[] = "S";
char Messungszeit000[] = "Z000";
char Messungszeit100[] = "Z100";
char Messungszeit500[] = "Z500";
char Messungszeit1000[] = "Z1000";
char Messungszeit2000[] = "Z2000";
char Messungszeit5000[] = "Z5000";
uint16_t adcval;
ADC_Init();
uart_init();
PORTD |= (1 << PORTD3);
_delay_ms(10000);
uart_puts(Programm_gestartet);
PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
sei();
/* Replace with your application code */
while (1)
{
if(uart_str_complete)
{
//uart_puts(uart_string);
USART_Flush();
if(strcmp(uart_string, Messungstart) == 0)
{
uart_puts(Messungstartstring);
Messung = 1;
}
if(strcmp(uart_string, Messungstopp) == 0)
{
uart_puts(Messungstoppstring);
Messung = 0;
}
if(strcmp(uart_string, Messungszeit000) == 0)
{
uart_puts(Messungszeit000string);
Zeitintervall = 0;
}
if(strcmp(uart_string, Messungszeit100) == 0)
{
uart_puts(Messungszeit100string);
Zeitintervall = 100;
}
if(strcmp(uart_string, Messungszeit500) == 0)
{
uart_puts(Messungszeit500string);
Zeitintervall = 500;
}
if(strcmp(uart_string, Messungszeit1000) == 0)
{
uart_puts(Messungszeit1000string);
Zeitintervall = 1000;
}
if(strcmp(uart_string, Messungszeit2000) == 0)
{
uart_puts(Messungszeit2000string);
Zeitintervall = 2000;
}
if(strcmp(uart_string, Messungszeit5000) == 0)
{
uart_puts(Messungszeit5000string);
Zeitintervall = 5000;
}
uart_str_complete = 0;
}
if (Messung == 1)
{ USART_Flush();
adcval = ADC_Read(PORTA0);
strcat(uart_ausgabe, itoa(adcval,uart_ausgabe,10));
uart_puts(Messungstartstring);
}
}
return 0;
}
Es muss etwas mit ADC zu tun haben.