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] what is the bug,where is my mistake in this code?

Status
Not open for further replies.

shirko20

Member level 2
Joined
Sep 29, 2013
Messages
44
Helped
1
Reputation
2
Reaction score
0
Trophy points
6
Activity points
381
hi i wrote the code below for atmega8 to run timer2 and whenever timer2 overflows ,the ISR of timer2 overflow execute and change the global variable tot_overflow ,but this will never do and the corresponding ISR will never accur?where is my error?
here is code:

..................................................................................

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/*
 * ADC_with_LCD.c
 *
 * Created: 24/11/2015 18:48:04
 *  Author: Sherko
 */ 
 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"
 
//
volatile uint16_t tot_overflow ;
//
volatile uint16_t tot_speed ;
 
void lcd_write(uint16_t x,uint16_t y,int z)
{
    char int_buffer[10];
    
    if(z==0)
    {
        lcd_clrscr();
        lcd_puts("ADC : ");
        lcd_gotoxy(0,1);
        lcd_puts("OCR1A :  ");
        itoa(x,int_buffer,10);
        lcd_gotoxy(6,0);
        lcd_puts(int_buffer);
        itoa(y,int_buffer,10);
        lcd_gotoxy(8,1);
        lcd_puts(int_buffer);
        _delay_ms(50);
    }
    else 
    {       
 
        lcd_clrscr();
        lcd_puts("tot_ovf: ");
        lcd_gotoxy(0,1);
        lcd_puts("speed : ");
        itoa(x,int_buffer,10);
        lcd_gotoxy(6,0);
        lcd_puts(int_buffer);
        itoa(y,int_buffer,10);
        lcd_gotoxy(8,1);
        lcd_puts(int_buffer);
        _delay_ms(50);
    
    }       
        
}
 
 
//initialize timer2  and  External interrupt 0 INT0 AND SEI()
void timer2_init()
{
        // ENABLE EXTERNAL INT0 INTERRUPT AND INITIALIZE IT
    GICR |= (1<<INT0);
    MCUCR |= (1<< ISC00) | (1<<ISC01);
    GIFR |= (1<<INTF0);
    
    //timer2 clock prescaler=8 TimePeriod=.001, delay required=1m=60s=60000ms  so timer must overflow 234375 times.
    //timer mode = normal 
    TCCR2 |= (1<<CS21);
    //enable timer2 overflow ISR
    TIMSK |= (1<<TOIE2);
    TCNT2=0x00;
    // enable global interrupts
    sei();
 
    // initialize overflow counter variable
    tot_overflow = 0;
    tot_speed =0;
}
 
//INT0 ISR
ISR(INT0_vect)
{
    tot_speed++;
    
}
 
//Timer2 overflow ISR
ISR(TIMER2_OVF_vect)
{
    tot_overflow++;
    if (tot_overflow == 234375)
    {
        GICR |= (1<<INT0);
        lcd_write(tot_overflow,tot_speed,1);
        _delay_ms(5000);
    }
    
}
// initialize timer1
void timer1_init()
{
    // timer1 clock=8000khz/64/256 = 488 hz  clock prescaler=64
    // timer Mode =fast PWM
    // MODE OF PWM = non_Inverted Mode  1<<COM21
    //SET PB1(OC1A) & PB2(OC1B) AS OUTPUT  PIN
    DDRB|=(1<<PB1) | (1<<PB2);
    TCCR1B |= (1<<CS10) | (1<<CS11) | (1<<WGM12) ;
    TCCR1A |= (1<< WGM10) | (1<<COM1A1) | (1<<COM1B1);
    TIMSK |= (1<<OCIE1A);
    TCNT1=0X00;
    OCR1A=0X00;
    
    
}
ISR(TIMER1_COMPA_VECT)
{
    
}
 
// initialize adc
void adc_init()
{
    // AREF = AVcc
    ADMUX = (1<<REFS0);
 
    // ADC Enable and prescaler of 64
    // 8000000/64 = 125000
    ADCSRA = (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(0<<ADPS0);
}
 
// read adc value
uint16_t adc_read(uint8_t ch)
{
    // select the corresponding channel 0~7
    // ANDing with '7' will always keep the value
    // of 'ch' between 0 and 7
    ch &= 0b00000111;  // AND operation with 7
    ADMUX = (ADMUX & 0xF8)|ch;     // clears the bottom 3 bits before ORing
 
    // start single conversion
    // write '1' to ADSC
    ADCSRA |= (1<<ADSC);
 
    // wait for conversion to complete
    // ADSC becomes '0' again
    // till then, run loop continuously
    while(ADCSRA & (1<<ADSC));
 
    return (ADC);
}
 
int main()
{
    uint16_t adc_result0;
    uint16_t X=0;
    
    //INITIALIZE TIMER1
    timer1_init();
    // initialize adc and lcd
    adc_init();
    lcd_init(LCD_DISP_ON_CURSOR);
 
 
    // display the labels on LCD
    _delay_ms(50);
    // SET PB5 as INPUT PIN
    DDRB |= (0<<PB5);
    PORTB |= (0<<PB5);
    PINB |= (0<<PB5);
    
    while(1)
    {
        adc_result0=adc_read(0);
        X= (adc_result0/102)*25.4;
        OCR1A=X;
        //WRITE ADC READED DATA ON LCD
        lcd_write(adc_result0,X,0);
        //if button on PB5 pressed then start TIMER2 and INT0
        if(PINB & (1<<PB5) )
        {   _delay_ms(100);
            lcd_clrscr();
            lcd_puts("Processing... please wait!");
            timer2_init();
            // loop until int0 is disabled and one minute is passed
            while(GICR & (1<<INT0));    
        
        }       
        
 
 
        
    }
}

 

Your code has some not recommended practices, such as placing long delay inside the ISR vector, as well accessing the LCD inside and outside it, most likely some instance competing with each other.

You should just set few flags there, and deal with the module interfaces at the main() program.
 

YES YOU WERE right but even now while i changed timer2 Overflow ISR to below code the value of tot_overflow variable not changed and corresponding ISR not execute at all?!


Code C - [expand]
1
2
3
4
5
6
7
//Timer2 overflow ISR
ISR(TIMER2_OVF_vect)
{
    tot_overflow++;
    if (tot_overflow == 234375)
        GICR |= (1<<INT0);
}

 

You are comparing a variable which has 16 bit's magnitude with a numeric value which will never reach.
Try declare tot_overflow as Long.

Code:
if (tot_overflow == 234375)
 

i deleted the code you mentioned and no change in tot_overflow happened, i think the problem is regarding to interrupt where the ISR don't execute at all and even when i set int0 pin condition to execute responding ISR even this ISR dont accur and the value of tot_speed is same also the value of tot_overflow is the same zero,but why ISR 's cant be called?
 

You are asynchronously changing the Timer2 configuration parameters by calling the timer2_init() function at runtime inside the while(1) loop, which is not appropriated; You should run it only once. I´m unnable to check on this code if timmings are properly sized, but sounds as another possible source of the problem.
 

is ther any irreconcilably between timer1 and timer 2 and adc and INT0 to active them at same time?
i remove code relative to timer1 initialization and adc and problem solved is there any disagree between them?
 

is ther any irreconcilably between timer1 and timer 2 and adc and INT0 to active them at same time?
i remove code relative to timer1 initialization and adc and problem solved is there any disagree between them?

Some timers, particularly the TIMER0, are widely used in various hardware modules of the microcontroller to generate the time base for some internal operations, such as the A/D converter, for example. To find out exactly which one caused this problem, you should to investigate the settings of each of these peripherals to know where there was a conflict regarding to multiple handling of them.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top