0

The program is written in C and compiled for AVR microcontroller ATmega328P. The program is being debugged in Proteus 8. After all interrupts are executed, the program restarts from the initialization section instead of entering the main loop. The program is expected to enter an infinite loop in the main function after initialization.

Could someone point out what the problem might be and what to look for?

P.S. It happens not all the time, but often.

main.c

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>
#include <string.h>
#include "lic328p_gpio.h"
#include "lic_menuio.h"
#include "battery.h"
#include "lic_18650h.h"
#include "lic_uart.h"
#include "lic_adc.h"
static volatile tx_data tx_package;
static volatile adc_channel channel;
static volatile batlist batstat;
ISR(ADC_vect)
{
 uint16_t data = adc();
 batt_data_handling(data, &batstat);
 fill_tx_package(&batstat, &tx_package);
 UCSR0B |= (1 << UDRIE0); 
}
ISR(USART_RX_vect)
{
 // Selecting the Menu Mode
 setMode(&menu, UDR0);
}
ISR(USART_UDRE_vect)
{
 if(tx_package.index < tx_package.length) {
 UDR0 = tx_package.data[tx_package.index];
 tx_package.index++;
 } else {
 tx_package.inprocess = false;
 UCSR0B &= ~(1 << UDRIE0);
 };
}
ISR(USART_TX_vect) {
}
int main(void)
{
 port_init();
 uart_init(MYUBRR);
 timer_init();
 adc_init();
 init_adcChan(&channel);
 init_battData(&batstat);
 init_tx_data(&tx_package);
 sei();
 while(1) {
 };
 return 0;
}

enter image description here

asked Jun 26, 2024 at 17:58
9
  • The program is incomplete. We don't see what all used types and invoked functions are. Also fuse bytes. Do you have watchdog enabled? Commented Jun 26, 2024 at 22:25
  • I have added a picture of the fuses settings in Proteus to the question description. The WatchDog is unprogrammed. As for the rest of the library files that describe all the data types and functions, I would be happy to show them, but there are many of them and I thought it would be inappropriate to post them here. Commented Jun 27, 2024 at 11:49
  • 2
    In timer_init() you enable timer overflow interrupt but no handler defined. I don't know what toolchain you use, but avr-gcc in this case jumps to _bad_interruptwhich jumps to reset vector. Commented Jun 27, 2024 at 18:55
  • I have added a link to my project's GitHub repository in the description. Commented Jun 27, 2024 at 20:41
  • 1
    Yes, i looked into that code and pointed in previous comment to at least one issue with timer overflow interrupt, which may cause jump to reset vector. Side note: don't change bit fields in registers one-by-one, set them at once. For example, instead of ADCSRA |= (1<<ADPS0); ADCSRA |= (1<<ADPS1); ADCSRA &= (1<<ADPS2) write ADCSRA = (ADCSRA | (1<<ADPS0) | (1<<ADPS1)) & ~(1<<ADPS2); Or uint8_t tmp = ADCSRA; tmp |= ...; tmp &= ...; ADCSRA = tmp; Commented Jun 27, 2024 at 22:59

0

Know someone who can answer? Share a link to this question via email, Twitter, or Facebook.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.