Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[AVR] Atmega328P Timer Interrupt Problem

Status
Not open for further replies.

erdem.simsek

Newbie level 5
Joined
Aug 6, 2015
Messages
9
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
85
Hi,
I am new to AVR and i am trying to make my libraries.
My problem is that, When TCNT0 register passes the 0xFF or value in OCR0A register, the timer should occur an interrupt. In my code, TC0 timer could not occur any interrupt.

Code:
//This is the timer8.c source file
#include <avr/io.h>
#include "timer8.h"
#include <avr/interrupt.h>

#define TIMER_0_START_ADDRESS (0x0044)
#define TIMER_2_START_ADDRESS (0x00B0)

typedef volatile struct{ // this structure holds registers
    unsigned char tccra;
    unsigned char tccrb;
    unsigned char ocra;
    unsigned char ocrb;
}timer_hw;

struct timer{
    timer_hw volatile *p_hw;
};

static timer g_timer[2];
uint8_t temp_clock_type = 0x00;

void timer_init(void){
    g_timer[0].p_hw = (timer_hw volatile *)TIMER_0_START_ADDRESS;
    g_timer[1].p_hw = (timer_hw volatile *)TIMER_2_START_ADDRESS;
}

timer *timer_open(timer_type type){ // it return the related timer pointer
    timer *p_timer = &(g_timer[type]);
    return p_timer;
}

void timer_set(timer *timer_temp, timer_mode mode, timer_clock clock, uint8_t duration_ms){
// It sets the related timer modes and  thresould duration
    timer_hw volatile *p_hw = timer_temp->p_hw;
    temp_clock_type = clock;
    p_hw->tccra |= mode;
    p_hw->ocra = duration_ms;
    TIMSK0=(0<<OCIE0B) | (1<<OCIE0A) | (0<<TOIE0);
}

void timer_start(timer *timer_temp){
// It starts the timer 
    timer_hw volatile *p_hw = timer_temp->p_hw;
    p_hw->tccrb |= temp_clock_type;
}

void timer_stop(timer *timer_temp){
// it stops the timer
    timer_hw volatile *p_hw = timer_temp->p_hw;
    p_hw->tccrb = 0x00;
}

void timer_restart(timer *timer_temp){
    timer_hw volatile *p_hw = timer_temp->p_hw;
    p_hw->ocra = 0x00;
    p_hw->ocrb = 0x00;
}

void timer_clear(timer *timer_temp){
// it sets all related timer registers to zero 
    timer_hw volatile *p_hw = timer_temp->p_hw;
    p_hw->tccra = 0x00;
    p_hw->tccrb = 0x00;
    p_hw->ocra = 0x00;
    p_hw->ocrb = 0x00;
}


ISR(TIMER0_OVF_vect){ // when interrupt occurs, timer_callback function is called
    timer_callback();
}

Code:
// this is the header file for timer library
#ifndef TIMER_H_INCLUDED
#define TIMER_H_INCLUDED

typedef enum timer_type{
    TIMER_0,
    TIMER_2,
}timer_type;

typedef enum timer_mode{
    NORMAL_MODE,
    CTC_MODE,
    FAST_PWM_MODE,
    PHASE_CORRECT_PWM_MODE
}timer_mode;

//WGM0[2:0] 101 and 111 modules are not supported

typedef enum timer_clock{
    CLOCK_1,
    CLOCK_8,
    CLOCK_64,
    CLOCK_256,
    CLOCK_1024,
    CLOCK_EXT_FALLING_EDGE,
    CLOCK_EXT_RISING_EDGE
}timer_clock;

typedef struct timer timer;

void timer_init(void);
timer *timer_open(timer_type);
void timer_set(timer *, timer_mode, timer_clock, uint8_t);
void timer_start(timer *);
void timer_stop(timer *);
void timer_restart(timer *);
void timer_clear(timer *);
void timer_callback();


#endif // TIMER_H_INCLUDED

Code:
/*
This is the main function 
 */

#include <avr/io.h>
#include <timer8.h>
#include <gpio.h>

void timer_callback();

int main(void)
{

    // Insert code
    gpio_init(); //initialize the gpio library and gpio library is used for manipulating the ports
    gpio *Port_B = gpio_open(PIN_B);
    gpio_port_direction_set(Port_B,0xFF); // Set the All PORTB as an output
    timer_init(); // initialize the timer library
    timer *Timer_0 = timer_open(TIMER_0);
    timer_set(Timer_0,NORMAL_MODE,CLOCK_1,200); // Set the timer registers
    timer_start(Timer_0); // starts the timer
    while(1)
    ;

    return 0;
}

void timer_callback(){
    PORTB ^= 0xFF;
}

This is all my code
Like i said, when the timer reach the maximum value (0XFF or OCR0), the interrupt must occur. I try to figure out my my mistake but i could not.

Thanks for your attention
Have a nice day.View attachment codes.zip
 

Hi,

(I´m not that experienced in C)

Did you enable dedicated interrupts?
Did you enable global interrupt?

Klaus
 

Where is

Code:
sei()
 

I added
Code:
sei()
but there is no changes.
As far as i remember, interrupts are enabled by default in atmega328p. When i found the sources , i will add the source of "interrupts are enabled by default in atmega328p".
 

Two questions. Why did you such a simple task in so complex way. It is almost impossible to analyse in a short time. Start with something simple then write "libraries". If you have searched already, no one uses such a HAL-like (from much complex STM32 32 bit micros with far more complex peripherals) libraries for this very simple micros.

There is no reason to call callback function and waste time for it.
 

First things first - are you sure that the timer is running?
Try executing your start routine code, sit in a simple for() loop for a while, and then stop and read the timer register value.
If it isn't running, you haven't configured it properly - perhaps the clock source for it must be configured? Have you set the clock fuse bits appropriately in the program? What clock fuse/config settings have you set in the project?

Actually, I think that your code is pretty well organized - but getting it to work is also important!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top