sammler
23.04.2011, 16:15
Hallo Leute,
nach etlichen Versuchen und mittlerweile leicht verzweifelt, muss ich mich wohl geschlagen geben und einfach mal um Hilfe bitten ;-)
Ich versuche derzeit mich nach und nach (wieder) in die Programmierung einzuarbeiten (echt erschreckend, wie viel man in 4 Jahren vergessen kann...).
Soweit komme ich ja ganz gut zurecht, und dank Datenblatt, rn-Wissen und mikrocontroller.net komme ich eigentlich auch mit den Timern und den ganzen anderen Registern klar.
Nur will mir jetzt offenbar eine popelige IF-Abfrage den Spaß verderben.
Folgendes Phänomen kann ich beobachten:
Ich habe einen einfachen CTC-Interrupt auf Timer0 meines AT-Mega32 programmiert, der mir alle Millisekunde eine 16-bit-Variable g_msec inkrementiert.
Wird g_msec > 1000 soll g_sec inkrementiert werden:
void make_time(void){
if (g_msec > 999) {
cli();
if (g_msec < 1000){
g_msec++;
}
g_msec -= 1000;
sei();
g_sec++;
g_send=1;
PORTA ^= (1 << PINA0);
if (g_sec > 59){
g_sec = 0;
g_min++;
PORTA ^= (1 << PINA1);
if (g_min > 59){
g_min = 0;
g_h++;
PORTA ^= (1 << PINA2);
if (g_h > 23){
g_h = 0;
g_d++;
}
}
}
}
}
Blöderweise springt er mir der Befehlspointer aber manchmal auch bei kleineren Werten als 1000 in die Schleife:
18649
Der Aufruf der Funktion erfolgt in der Hauptschleife in main.c:
#include <avr/io.h> // Namen der IO Register
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h> // Funktionen zum Warten
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "raupe.h"
#include "uart.h"
#include "scheduler.h"
int main(void)
{
/**
* Stammfunkion.
* Ruft alle anderen Programmteile auf. */
unsigned int c;
char buffer[20];
char command[20];
command[0] = '\0';
startup_diag();
sei();
init_scheduler();
PORTA = ( 1 << PINA3 ); // Pullups auf Eingangs-Pins
DDRA |= ( 1 << PINA0 ); // PINA0 als output, _BV(0) = (1<<0) = 1
DDRA |= ( 1 << PINA1 ); // PINA1 als Output
DDRA |= ( 1 << PINA2 ); // PINA2 als Output
while (1)
{
make_time();
/*
* Get received character from ringbuffer
* uart_getc() returns in the lower byte the received character and
* in the higher byte (bitmask) the last receive error
* UART_NO_DATA is returned when no data is available.
*
*/
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
//i = 0;
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
uart_puts_P("Buffer overflow error: ");
}
if (!((c=='\0')||(c=='\n'))&&(i<sizeof(command))){
command[i] = (unsigned char)c;
command[(i+1)] = '\0';
i++;
}
else if (c=='\n') {
i=0;
}
}
if (!strcmp(command, "time") || (g_send)) {
sprintf(buffer, "\nT: %02d:%02d:%02d.%04d\n", g_h, g_min, g_sec, g_msec);
uart_puts(buffer);
command[0]=(int)"\0";
g_send=0;
}
}
// Programm-Ende - sollte nicht erreicht werden...
}
Fuses: 0x09(High) 0x7F(Low); komplettes Programm im Anhang.
Wäre super, wenn ihr mir auf die Sprünge helfen könntet!
Gruß,
sammler
PS: der Wert von g_msec, wenn er fälschlich reinspringt, ist offenbar immer 768 (dez.)...
nach etlichen Versuchen und mittlerweile leicht verzweifelt, muss ich mich wohl geschlagen geben und einfach mal um Hilfe bitten ;-)
Ich versuche derzeit mich nach und nach (wieder) in die Programmierung einzuarbeiten (echt erschreckend, wie viel man in 4 Jahren vergessen kann...).
Soweit komme ich ja ganz gut zurecht, und dank Datenblatt, rn-Wissen und mikrocontroller.net komme ich eigentlich auch mit den Timern und den ganzen anderen Registern klar.
Nur will mir jetzt offenbar eine popelige IF-Abfrage den Spaß verderben.
Folgendes Phänomen kann ich beobachten:
Ich habe einen einfachen CTC-Interrupt auf Timer0 meines AT-Mega32 programmiert, der mir alle Millisekunde eine 16-bit-Variable g_msec inkrementiert.
Wird g_msec > 1000 soll g_sec inkrementiert werden:
void make_time(void){
if (g_msec > 999) {
cli();
if (g_msec < 1000){
g_msec++;
}
g_msec -= 1000;
sei();
g_sec++;
g_send=1;
PORTA ^= (1 << PINA0);
if (g_sec > 59){
g_sec = 0;
g_min++;
PORTA ^= (1 << PINA1);
if (g_min > 59){
g_min = 0;
g_h++;
PORTA ^= (1 << PINA2);
if (g_h > 23){
g_h = 0;
g_d++;
}
}
}
}
}
Blöderweise springt er mir der Befehlspointer aber manchmal auch bei kleineren Werten als 1000 in die Schleife:
18649
Der Aufruf der Funktion erfolgt in der Hauptschleife in main.c:
#include <avr/io.h> // Namen der IO Register
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <util/delay.h> // Funktionen zum Warten
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include "raupe.h"
#include "uart.h"
#include "scheduler.h"
int main(void)
{
/**
* Stammfunkion.
* Ruft alle anderen Programmteile auf. */
unsigned int c;
char buffer[20];
char command[20];
command[0] = '\0';
startup_diag();
sei();
init_scheduler();
PORTA = ( 1 << PINA3 ); // Pullups auf Eingangs-Pins
DDRA |= ( 1 << PINA0 ); // PINA0 als output, _BV(0) = (1<<0) = 1
DDRA |= ( 1 << PINA1 ); // PINA1 als Output
DDRA |= ( 1 << PINA2 ); // PINA2 als Output
while (1)
{
make_time();
/*
* Get received character from ringbuffer
* uart_getc() returns in the lower byte the received character and
* in the higher byte (bitmask) the last receive error
* UART_NO_DATA is returned when no data is available.
*
*/
c = uart_getc();
if ( c & UART_NO_DATA )
{
/*
* no data available from UART
*/
//i = 0;
}
else
{
/*
* new data available from UART
* check for Frame or Overrun error
*/
if ( c & UART_FRAME_ERROR )
{
/* Framing Error detected, i.e no stop bit detected */
uart_puts_P("UART Frame Error: ");
}
if ( c & UART_OVERRUN_ERROR )
{
/*
* Overrun, a character already present in the UART UDR register was
* not read by the interrupt handler before the next character arrived,
* one or more received characters have been dropped
*/
uart_puts_P("UART Overrun Error: ");
}
if ( c & UART_BUFFER_OVERFLOW )
{
/*
* We are not reading the receive buffer fast enough,
* one or more received character have been dropped
*/
uart_puts_P("Buffer overflow error: ");
}
if (!((c=='\0')||(c=='\n'))&&(i<sizeof(command))){
command[i] = (unsigned char)c;
command[(i+1)] = '\0';
i++;
}
else if (c=='\n') {
i=0;
}
}
if (!strcmp(command, "time") || (g_send)) {
sprintf(buffer, "\nT: %02d:%02d:%02d.%04d\n", g_h, g_min, g_sec, g_msec);
uart_puts(buffer);
command[0]=(int)"\0";
g_send=0;
}
}
// Programm-Ende - sollte nicht erreicht werden...
}
Fuses: 0x09(High) 0x7F(Low); komplettes Programm im Anhang.
Wäre super, wenn ihr mir auf die Sprünge helfen könntet!
Gruß,
sammler
PS: der Wert von g_msec, wenn er fälschlich reinspringt, ist offenbar immer 768 (dez.)...