PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Warum wird die main-routine dauernt neu gelstartet ?



düse
15.10.2004, 12:08
Hi,

beim einfügen der "Selbst-Vorstellung" über die serielle Schnittstelle, mußte ich festsetllen, daß die Zeile
( USART_transmit_string ("Programm zur Spannungsueberwachung 10/2004 "); )
immer wieder aufgerufen wird.

Könnte das am Interrupt liegen ? Habt Ihr irgendwelche Ideen ?


#include <avr/io.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <simple_delayroutinen.c>
#include <io_modul.h>

volatile unsigned int grenzwert;
int hilfs;

SIGNAL (SIG_UART_RECV) {

hilfs=empfange();

}


int main (void) {

grenzwert=800;
//Intialisierung
USART_Init ();
ad_init();
set_id();
v_ref(5);

// Text ausgabe. Wiederholt sich unendlich. Warum ???

USART_transmit_string ("Programm zur Spannungsueberwachung 10/2004 ");
USART_transmit('\n');
USART_transmit('\r');



DDRB = 0xff;

// Variablen
int x=0;
char buffer [10];
unsigned erg=0;



sei (); // Interrupt erlauben



delay_ms(8000); //Einschaltzeitverzögerung

for(;;){

PORTB = 0xff;

for (int i=0;i<=3;i++) // Überwachen der Ports 0 bis i
{
erg=ad_port(i); // Port auslesen
if(erg < grenzwert)
{

PORTB = 0xff-0x02;
delay_ms(1000); // Wenn Wert zu niedrig Pin2 von Port B einschalten

}

}
}

return 0;
}

muraad
15.10.2004, 12:53
Ich seh jetzt eigentlich keinen Fehler im Quelltext. Aber wozu hast du diese Zeile bzw. den Uart Recevier(Empfangen) Interrupt,
SIGNAL (SIG_UART_RECV) {

hilfs=empfange();

}

dein programm empfängt doch nie etwas. Du wertest die Variable hilfs auch nie aus, oder wird sie von einer Funktion aus <io_modul.h> gebraucht, da sie ja global ist. Deswegen kannst du UART_REC sicher weglassen.
Gruß Muraad

düse
15.10.2004, 20:22
Doch mein Program empfängt was.

Ich kann mir per Terminal diverse Spannungswert usw. ausgeben lassen, Wertverändern, Resten(extern) usw. und sofort.

Hab halt auf der Uni nur JAVA gelernt :-&
Deshalb schreib ich ins Hauptprg nur das Nötigste. Es gib aber noch ausreichend verkettete Unterprogramme...

düse
15.10.2004, 20:23
Ach so.

Die übergabe der Empfangendaten ans Hauptprg. hab ich zum Test rausgenommen.
Wird trotzdem nicht schöner...

muraad
18.10.2004, 11:54
Dann kann ich dir leider nicht weiter helfen. Der Quelltext des Hauptprogramms hat auf jeden Fall keine Fehler. Vielleicht hast du einen Fehler in USART_transmit_string().
Was vielleicht noch der Fehler ist ist das du ein Leerzeichen zwischen USART_transmit_string und("Programm zur Spannungsueberwachung 10/2004 ") hast, es darf aber soweit ich weiß keins kommen.
Is mir grad aufgefallen als ichs hier rein kopiert hab, und ich glaub irgendwie das ist der Fehler.
Gruß Muraad

düse
18.10.2004, 15:51
Hm,

in meinen Debug-USART-Ausgaben hab ich auch Leerzeichen.
Ist ja ein Zeichen wie jedes andere auch...

Naja.
Kann man nichts machen.
Vielen Dank erstmal für Deine Mühe

muraad
18.10.2004, 21:36
aber hast dus mal ohne Leerzeichnen zwischen Funktionsname und Parameterklammern versucht? würd mich nur interessieren.
Gruß Muraad

19.10.2004, 07:45
Dann gehe ich mal davon aus, dass du RXCIE und TXCIE aktiviert hast in deiner USART-Init. Dass das nicht so geht wenn du für TX keine ISR schreibst, sollte dir klar sein.
Gewöhn dir bitte an, immer den kompletten Code zu posten.

düse
21.11.2004, 00:25
Also nochmal zu dem Programm.
Diesmal mit vollständigen Quellcodes:


usart_emp.h



#include <usart_bibliothek.h>
int hilf=0;
int id=1;

/*void set_id(int x) // veraltet
{
id=x;
}
*/
void set_id (void) {
DDRC=0x00; //Port C = Input
id =PINC-240; // Einlesen der PINs an Port C. Wert korrektur verbesserungswürdig
id=~id-65520;


}

int empfange (void) {
char buffer [10];
unsigned erg=0;
unsigned char data = 0;
data = USART_receive ();
if (data == '?'){
data = USART_receive ();
if (data == 'V'){
data = USART_receive ();
hilf=data;
hilf=hilf-48;
if (hilf==id ){
data = USART_receive ();
hilf=data;
hilf=hilf-48;
if (hilf<8)
{
erg=ad_port(hilf);
utoa(erg, buffer, 10); // Wandelt in String
USART_transmit('\t');
USART_transmit_string (buffer);
USART_transmit('\r');
USART_transmit('\n');
//return 0;
}
}
}
else{
if(data == 'A'){
data = USART_receive ();
hilf=data;
hilf=hilf-48;
//char buffer [10];
unsigned erg=0;
if(hilf==id){
USART_transmit('\t');
for (int i=0;i<=7;i++)
{
int erg=ad_port(i);
utoa(erg, buffer, 10); // Wandelt in String
USART_transmit_string (buffer);
USART_transmit('\t');
}
USART_transmit('\r');
USART_transmit('\n');

} } }


}
else{
if(data == '!'){
//USART_transmit_string (" 1.schleife ");
data = USART_receive ();
if(data == 'I'){
//USART_transmit_string (" 2.schleife ");
data = USART_receive ();
hilf=data;
hilf=hilf-48;
if(hilf == id){
//USART_transmit_string (" 3.schleife ");
//USART_transmit_string (" Reset ");
DDRB = 0xff;
PORTB = 0xff-0x01;

delay_ms(3000);
}
}

else{
if(data == 'T'){
int t=0;
int h=0;
int z=0;
int e=0;
int zwischen_erg=0;
data = USART_receive ();
hilf=data;
hilf=hilf-48;
if(hilf == id){
data = USART_receive ();
hilf=data;
t=hilf-48;
zwischen_erg=zwischen_erg+t*1000;

data = USART_receive ();
hilf=data;
h=hilf-48;
zwischen_erg=zwischen_erg+h*100;

data = USART_receive ();
hilf=data;
z=hilf-48;
zwischen_erg=zwischen_erg+z*10;

data = USART_receive ();
hilf=data;
e=hilf-48;
zwischen_erg=zwischen_erg+e*1;

// debug code
/*utoa(zwischen_erg, buffer, 10); // Wandelt in String
USART_transmit_string (buffer);
USART_transmit('\t');
*/
return zwischen_erg;

} }
else
{}

}

}
else
{}

}



return 9;
}


usart_bibilothek.h



/************************************************** *********
Funktionsbibliothek für den USART des Atmega8
************************************************** *********/

#include <avr/io.h>

#define F_CPU 4000000
#define USART_BAUD_RATE 9600
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

void USART_Init(void) {
UCSRB = _BV(RXCIE) | _BV(TXCIE) | _BV(RXEN) | _BV(TXEN); // wenn einer der zustände 1 dann schreiben
UBRRL = (unsigned char) USART_BAUD_SELECT;
}

void USART_transmit (unsigned char c) {
while (!(UCSRA & (1<<UDRE))) {} //wenn speicherfrei und keine Fehler
UDR = c;
}

void USART_trans (unsigned int a)
{
while (!(UCSRA & (1<<UDRE))) {}
UDR = a;
}
unsigned char USART_receive (void) {
while(!(UCSRA & (1<<RXC))) {}
return UDR;
}

void USART_transmit_string (unsigned char *string) {
while (!(UCSRA & (1<<UDRE))) {}
while ( *string)
USART_transmit (*string++);
}



main_prg



#include <avr/io.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <simple_delayroutinen.c>
#include <io_modul.h>

volatile unsigned int grenzwert;
int hilfs;

SIGNAL (SIG_UART_RECV) {
int x=0;
char buffer [10];
unsigned erg=0;

hilfs=empfange();

if(hilfs>10){
grenzwert=hilfs;

//debug code

/*USART_transmit('\t');
USART_transmit_string (" Im interrupt ");
utoa(grenzwert, buffer, 10);
USART_transmit_string (buffer);
USART_transmit('\t');*/

}
}


int main (void) {

grenzwert=800;
//Intialisierung
USART_Init ();
ad_init();
set_id();
v_ref(5);
USART_transmit_string ("!!! Spannungsüberwachung !!!");
USART_transmit('\n');
USART_transmit('\r');

DDRB = 0xff;

// Variablen
int x=0;
char buffer [10];
unsigned erg=0;



sei (); // Interrupt erlauben



delay_ms(8000); //Einschaltzeitverzögerung

for(;;){

PORTB = 0xff;

for (int i=0;i<=3;i++) // Überwachen der Ports 0 bis i
{

erg=ad_port(i); // Port auslesen
if(erg < grenzwert)
{

/*utoa(grenzwert, buffer, 10);
USART_transmit('\t');
USART_transmit_string (" In Hauptprg ");
USART_transmit_string (buffer);
*/

PORTB = 0xff-0x02;
delay_ms(1000); // Wenn Wert zu niedrig Pin2 von Port B einschalten

//debug text
/*utoa(i, buffer, 10);
USART_transmit_string (" Fehler bei ");
USART_transmit_string (buffer);
utoa(grenzwert, buffer, 10);
USART_transmit('\t');
USART_transmit_string (buffer);
USART_transmit('\t');
USART_transmit('\n');
USART_transmit('\r');
*/
}


}
}
return 0;
}


io_modul.h


#include <avr/io.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
//#include <usart_bibliothek.h>
#include <ad_read.h>
#include <usart_emp.h>

int daten (void) {
USART_Init ();
// Variablen
int x=0;
char buffer [10];
unsigned erg=0;
ad_init();
v_ref(5);


x=empfange();
if (x<8)
{
erg=ad_port(x);
utoa(erg, buffer, 10); // Wandelt in String
USART_transmit('\t');
USART_transmit_string (buffer);



USART_transmit('\r');
USART_transmit('\n');
return 0;
}
else
{
return x;
}



}


ad_read.h


#include <avr/io.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
//#include <usart_bibliothek.h>

unsigned int vref=3;

void v_ref(int x)
{
vref=x;
}

void ad_init(void)
{
ADCSRA = _BV(ADEN) | _BV(ADPS2); //Prescaler
}

unsigned ad_port (int x)
{
unsigned int high_bit=0;
unsigned int unten_bit=0;
unsigned erg=0;

switch(x) // Portwahl
{
case 0: break;
case 1: ADMUX |= _BV(MUX0);
break;
case 2: ADMUX |= _BV(MUX1);
break;
case 3: ADMUX = _BV(MUX0) | _BV(MUX1);
break;
case 4: ADMUX = _BV(MUX2);
break;
case 5: ADMUX = _BV(MUX2) | _BV(MUX0);
break;
case 6: ADMUX = _BV(MUX2) | _BV(MUX1);
break;
case 7: ADMUX = _BV(MUX2) | (_BV(MUX1)|_BV(MUX0));
break;

}


ADCSRA |= _BV(ADSC); // Konvertierung Starten
while (ADCSRA & _BV(ADSC)) {}
//warte, bis ADSC gelöscht wird --> Ende der Konvertierung

unten_bit = ADCL;
high_bit = ADCH;
//erg=(high_bit);
erg=((unten_bit+high_bit*256L)*vref)*1000L/1024L;
return erg;
}



id_portc.h


#include <avr/io.h>
#include <stdlib.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
//#include <usart_bibliothek.h>
#include <ad_read.h>
#include <usart_emp.h>

int get_id (void) {

// Variablen
int id;
//char buffer [10];
//unsigned erg=0;



DDRC=0x00; //Port C = Input


id =PINC-240; // Einlesen der PINs an Port C. Wert korrektur verbesserungswürdig
id=~id-65520;


}

21.11.2004, 08:50
UCSRB = _BV(RXCIE) | _BV(TXCIE) | _BV(RXEN) | _BV(TXEN);
-->
UCSRB = _BV(RXCIE) | _BV(RXEN) | _BV(TXEN);

Ich habe die aktivierten Interrupts mittlerweile auch im Programm auf meiner Homepage auskommentiert, da scheinbar viele die Programmschnipsel einfach benutzen, ohne sich die Rubrik dazu richtig durchzulesen.

Pascal
21.11.2004, 10:06
vielleicht liegt es auch am Watchdog, bei machen AVRs ist der nämlich standartmäßig aktiviert und führt regelmäßig ein Reset des AVR durch
man kann ihn entweder per Fusebits oder softwaremäßig(siehe Datenblatt) ausschalten
bei manchen ATMEGAs ist das auf jeden Fall so, leider weiß ich nicht bei welchen

düse
21.11.2004, 10:12
@pascal, das mit dem Watchdog werd ich mal prüfen.

@gast

Sorry, daß ich bei der USART ein bißchenn viel mit copy&paste gearbeitet hab, aber ich leide unter akutem Zeitmangel...
Ich habe schon versucht, zu verstehen, was da wirklich passiert.
Manchmal ist das mir aber einfach noch zu hoch bzw. müßte ich zu lange im User-Manuel rumlesen und mir Beispiele basteln

21.11.2004, 11:06
So war das doch nicht gemeint, hätte ich das nicht gewollte, hätte ich den Code nicht veröffentlicht. Er ist gerade für Fälle wie dich gedacht.
Nur existiert bei mir zu fast jedem Programm noch ein wenig Text in Form einer HTML-Seite, den man sich durchlesen sollte, bevor man anfängt zu programmieren. Ich habe mich mit Absicht meistens kürzer als das Datenblatt gefasst.
Die Zeit, die du beim Aneignen der Grundlagen verlierst, ersparst du dir beim Debuggen. Ich spreche aus Erfahrung :-)

Alex

21.11.2004, 11:17
Versuch mal: sieht doch aus, als tät sich das Gerät dauernd resetten.
Um das einzugrenzen: inkrementiere in deiner for-schleife irgendeine variable, und sende sie in jeder Schleife.
gibts ein unerwünschtes reset, wird diese Variable nie wirklich in die Höhe kommen (auf null setzen nach init)
Auf jeden fall kriegst du ein ergebnis, wo du siehst, was da abläuft. mfg

BomberD
22.11.2004, 06:21
Hallo,

ich habe ein ähnliches Problem.
Ich konnte allerdings schon etwas eingrenzen.
Bei mir wird der Controller rückgesetzt wenn ich Daten per uart empfange. Dann läuft mein Programm ab und begibt sich wieder in eine Wartestellung. Aus dieser Wartestellung kann ich zur zeit Quellcodemäßig nur über ein Reset entkommen. Meim eintreffen eines X-beliebigen Datenpaketes über UART fängt das programm an zu laufen.
Ich werd's auch mal mit dem herausnehmen des Interrupts probieren.

Edit:
TXCIE wars bei mir. :)