Problem with ATMega32 timers
Quote from Ricardo Kersckbaumer on May 7, 2024, 5:25 pmI set up a very simple circuit, just an LED on pin A0. For this circuit I made a software that uses timer 0 to change the state of the A0 output at 1 ms intervals. The output remains at 0. I changed the code to use timer 1, and the output alternated, but very slowly, at 0.5s intervals. I changed the program again, this time to timer 2, and the output now remains at 0.
To check my programs I used a real microcontroller, and all three programs worked properly.
So, as in a real circuit my programs work and in the ATMega32 simulated with the simulide they don't work, I believe there is some problem with the ATMega32 timers in the simulator.
The circuit is only an ATMega32 running at 8 MHz with a resistor and an LED connected to pin 40 (A0).
These are the programs used:
For Timer 0:
#include <avr/io.h> #include <avr/interrupt.h> // Define the LED pin #define LED_PIN PA0 // Initialize Timer 0 to generate an interrupt every 1 ms void timer0_init() { // Timer 0 Configuration TCCR0 |= (1 << WGM01) | (1 << CS01) | (1 << CS00); // CTC Mode, Prescaler of 64 OCR0 = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock TIMSK |= (1 << OCIE0); // Enable Timer 0 compare match interrupt } // Interrupt service routine for Timer 0 ISR(TIMER0_COMP_vect) { // Toggle the state of the LED connected to pin PORTA0 PORTA ^= (1 << LED_PIN); } int main(void) { // Configure the LED pin as output DDRA |= (1 << LED_PIN); // Initialize Timer 0 timer0_init(); // Enable global interrupts sei(); // Infinite loop while (1) { // Additional code in the main loop can be added here } return 0; }
For Timer 1:
#include <avr/io.h> #include <avr/interrupt.h> // Define the LED pin #define LED_PIN PA0 // Initialize Timer 1 to generate an interrupt every 1 ms void timer1_init() { // Timer 1 Configuration TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC Mode, Prescaler of 64 OCR1A = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock TIMSK |= (1 << OCIE1A); // Enable Timer 1 compare match A interrupt } // Interrupt service routine for Timer 1 ISR(TIMER1_COMPA_vect) { // Toggle the state of the LED connected to pin PORTA0 PORTA ^= (1 << LED_PIN); } int main(void) { // Configure the LED pin as output DDRA |= (1 << LED_PIN); // Initialize Timer 1 timer1_init(); // Enable global interrupts sei(); // Infinite loop while (1) { // Additional code in the main loop can be added here } return 0; }
And for Timer 2:
#include <avr/io.h> #include <avr/interrupt.h> // Define the LED pin #define LED_PIN PA0 // Initialize Timer 2 to generate an interrupt every 1 ms void timer2_init() { // Timer 2 Configuration TCCR2 |= (1 << WGM21) | (1 << CS22); // CTC Mode, Prescaler of 64 OCR2 = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock TIMSK |= (1 << OCIE2); // Enable Timer 2 compare match interrupt } // Interrupt service routine for Timer 2 ISR(TIMER2_COMP_vect) { // Toggle the state of the LED connected to pin PORTA0 PORTA ^= (1 << LED_PIN); } int main(void) { // Configure the LED pin as output DDRA |= (1 << LED_PIN); // Initialize Timer 2 timer2_init(); // Enable global interrupts sei(); // Infinite loop while (1) { // Additional code in the main loop can be added here } return 0; }
I am at your disposal for further clarification. Thank you
I set up a very simple circuit, just an LED on pin A0. For this circuit I made a software that uses timer 0 to change the state of the A0 output at 1 ms intervals. The output remains at 0. I changed the code to use timer 1, and the output alternated, but very slowly, at 0.5s intervals. I changed the program again, this time to timer 2, and the output now remains at 0.
To check my programs I used a real microcontroller, and all three programs worked properly.
So, as in a real circuit my programs work and in the ATMega32 simulated with the simulide they don't work, I believe there is some problem with the ATMega32 timers in the simulator.
The circuit is only an ATMega32 running at 8 MHz with a resistor and an LED connected to pin 40 (A0).
These are the programs used:
For Timer 0:
#include <avr/io.h>
#include <avr/interrupt.h>
// Define the LED pin
#define LED_PIN PA0
// Initialize Timer 0 to generate an interrupt every 1 ms
void timer0_init() {
// Timer 0 Configuration
TCCR0 |= (1 << WGM01) | (1 << CS01) | (1 << CS00); // CTC Mode, Prescaler of 64
OCR0 = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock
TIMSK |= (1 << OCIE0); // Enable Timer 0 compare match interrupt
}
// Interrupt service routine for Timer 0
ISR(TIMER0_COMP_vect) {
// Toggle the state of the LED connected to pin PORTA0
PORTA ^= (1 << LED_PIN);
}
int main(void) {
// Configure the LED pin as output
DDRA |= (1 << LED_PIN);
// Initialize Timer 0
timer0_init();
// Enable global interrupts
sei();
// Infinite loop
while (1) {
// Additional code in the main loop can be added here
}
return 0;
}
For Timer 1:
#include <avr/io.h>
#include <avr/interrupt.h>
// Define the LED pin
#define LED_PIN PA0
// Initialize Timer 1 to generate an interrupt every 1 ms
void timer1_init() {
// Timer 1 Configuration
TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC Mode, Prescaler of 64
OCR1A = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock
TIMSK |= (1 << OCIE1A); // Enable Timer 1 compare match A interrupt
}
// Interrupt service routine for Timer 1
ISR(TIMER1_COMPA_vect) {
// Toggle the state of the LED connected to pin PORTA0
PORTA ^= (1 << LED_PIN);
}
int main(void) {
// Configure the LED pin as output
DDRA |= (1 << LED_PIN);
// Initialize Timer 1
timer1_init();
// Enable global interrupts
sei();
// Infinite loop
while (1) {
// Additional code in the main loop can be added here
}
return 0;
}
And for Timer 2:
#include <avr/io.h>
#include <avr/interrupt.h>
// Define the LED pin
#define LED_PIN PA0
// Initialize Timer 2 to generate an interrupt every 1 ms
void timer2_init() {
// Timer 2 Configuration
TCCR2 |= (1 << WGM21) | (1 << CS22); // CTC Mode, Prescaler of 64
OCR2 = 124; // Value for 1 ms with prescaler of 64 and 8 MHz clock
TIMSK |= (1 << OCIE2); // Enable Timer 2 compare match interrupt
}
// Interrupt service routine for Timer 2
ISR(TIMER2_COMP_vect) {
// Toggle the state of the LED connected to pin PORTA0
PORTA ^= (1 << LED_PIN);
}
int main(void) {
// Configure the LED pin as output
DDRA |= (1 << LED_PIN);
// Initialize Timer 2
timer2_init();
// Enable global interrupts
sei();
// Infinite loop
while (1) {
// Additional code in the main loop can be added here
}
return 0;
}
I am at your disposal for further clarification. Thank you
Quote from arcachofo on May 7, 2024, 5:48 pmHi.
I tried your code for Timer0 and it works for me.
And it is not normal that any of the Timers works for you.Maybe there is some issue in your circuit, can you share it?
Hi.
I tried your code for Timer0 and it works for me.
And it is not normal that any of the Timers works for you.
Maybe there is some issue in your circuit, can you share it?
Quote from Ricardo Kersckbaumer on May 7, 2024, 5:53 pmThe previously reported issues are for Simulide version 1.0.0-SR2 R1449. I tested with version 1.1.0-SR0. Timer 0 and timer 2 worked correctly, but timer 1 continues to have problems, changing the output with much longer time intervals than expected.
The previously reported issues are for Simulide version 1.0.0-SR2 R1449. I tested with version 1.1.0-SR0. Timer 0 and timer 2 worked correctly, but timer 1 continues to have problems, changing the output with much longer time intervals than expected.
Quote from arcachofo on May 8, 2024, 1:58 pmFound the problem with Timer1.
It is an error in some bit names.
You can replace SimulIDE/data/AVR/mega32/mega32_regs.xml with this file:
mega32_regs.xml
Found the problem with Timer1.
It is an error in some bit names.
You can replace SimulIDE/data/AVR/mega32/mega32_regs.xml with this file:
mega32_regs.xml