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] Help with using ADC multiple channels atmega-328P ... Help me plz

Status
Not open for further replies.

Ghassan Darkool

Newbie level 2
Newbie level 2
Joined
Oct 3, 2014
Messages
2
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
35
Hello ...
I wrote this code for my Atmega 328P to make a PI control (changing the duty cycle of PWM according to the values of load current and voltage)
my code is sensible !! but I don't know why it's not work !!
PLZ help me PLZ
I didn't have any result !
in the main code when you change the OCR2A value for a constant one .. I have a result
for example if I put OCR2B=128*0.5; ... I have a duty cycle of 50% .. but I don't want that!!
PLZ I appreciate any help !
that's my 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
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <Stdlib.h>
#include <String.h>
double p,i,pi,theLow,theTenBitResult ;
int kp=4, ki=0.2;
int vref=1024, iref=1024 ,verror, int_verror=0, vreal, ireal;
////////////////////////////////////////////////////////////////////////////
void adc_read(void)
{
    ADCSRA|=(1<<ADSC); // start conversion
       
    //while (ADCSRA & (1 << ADSC)); // Wait for it to finish
 
    //return ADCH;
}
//////////////////////////////////////////////////////////////////////////
void adc_setup (void)
{
    ADCSRA|=(1<<ADEN);// enable the ADC.
    ADCSRA|=(1<<ADATE);//enable auto triggering.
    ADCSRA|=(1<<ADPS0)|(1<<ADPS1)|(1<<ADPS2); // start the ADC with division factor 128 and activated the interrupt.
    ADCSRA|=(1<<ADIE);//the ADC Conversion Complete Interrupt is activated.
    ADMUX|=(1<<REFS0);//AVCC with external capacitor at AREF pin is activated.
    ADMUX|=(1<<ADLAR);
    sei();
}
/////////////////////////////////////////////////////////////////////////
ISR(ADC_vect) // interrupt service routine function
{
    uint8_t theLow = ADCL;
    uint8_t first_conversion=1;
    uint16_t theTenBitResult = ADCH<<8 | theLow;
    if(ADMUX==101)// ADC5
    {
        if(first_conversion==2)
        {
            vreal=theTenBitResult;
            ADMUX|=(1<<MUX0)|(1<<MUX1); // switch to ADC3
            first_conversion=1;
        }
        else
        first_conversion++;
    }
    else if (ADMUX==99) // ADC3
    {
        if (first_conversion==2)
        {
            ireal=theTenBitResult;
            ADMUX|=(1<<MUX0)|(1<<MUX2); //switch to ADC5
            first_conversion=1;
        }
    else
    first_conversion++;
    }
    adc_read();
}
 
////////////////////////////////////////////////////////////////////////
void pwm_setup (void)
{
     TCCR2A|= (1<<COM2A1)|(1<<COM2A0);//Set OC2A on Compare Match
     TCCR2A|=(1<<WGM20)|(1<<WGM21);//fast PWM OCR2A=BOTTOM AND 0XFF=TOP 
     TCCR2A|=(1<<COM2B1);//Clear OC2B on Compare Match when up-counting. Set OC2B on Compare Match when down-counting.
     TCCR2B |= (1<<CS20)|(1<<WGM22); // Used no Prescaler
     TCNT2 = 0; // Reset TCNT2
     OCR2A = 128; // Initial the Output Compare register A & B
     
}
//////////////////////////////////////////////////////////////////////// 
int main (void)
{
   DDRD = 0b11111111;
   DDRB |= (1<<PB5)|(1<<PB0);
   PORTD = 0x00;
   OCR2B = 0;
   adc_setup();
   pwm_setup();
    while (1)
    {
         adc_read();
         verror=vreal-vref;
         p=kp*verror;
         int_verror+=verror;
         i=ki*int_verror;
         pi=p+i;
         if(ireal>iref)
         OCR2B=0;
         else 
         {
         if(vreal < vref)
         pi++;
         else if(vreal > vref)
          pi--;
         }
          OCR2B=pi;
         }  
 
}

 
Last edited by a moderator:

In the main function,before calling the while(1) loop you have initialized OCR2B as zero and inside the while(1) function also,you have initialized OCR2B zero.What is the reason behind initializing OCR2B twice?
 

the first one in the main it's like a beginning value for OCR2B
inside while loop the OCR2B change its value according to the if-else loop
isn't it ??
 

inside while loop the OCR2B change its value according to the if-else loop isn't it ??
But if you have initialized it already once,why you need to initialize it again?Use it as is from the previous initialization.Keep it initialized once,remove the declaration in the while loop and report on what happens.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top