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 PWM wave generation in codevision

Status
Not open for further replies.

Bluestar88

Member level 3
Joined
Oct 17, 2014
Messages
59
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
447
Hi guys,
I woud like to produce a pulse with 200 HZ frequency and 0.07 duty cycle, so I used timer2 of atmega32 in FAST PWM mode.
For this purpose, I used external crystal 4MHZ, and Prescale 128 (FOR 200Hz). basis on fpwm=crystal/(prescale*(256-tcnt)) formula, I computed 100 (0x64) for TCNT2, For duty cycle 0.07, according to dutycycle=ocr2/(256-tcnt2) formula, OCR2 is 0x68.
So I did it in Codevision:

TCCR2=0x6D;
TCNT2=0x64;
OCR2=0x68;

But I coudnot get to 200 Hz, it is about 125 Hz...please help me...
 

Thanks for your consideration,
I am generating different pulses (200, 250,300, 350,400 Hz) by controlling from Visual basic 6 software. I Used atmega32, for this order. My full program is here, I cant take accurate frequency. only 250 Hz frequency is correct.
My goal is generating pulses by 200 to 400 Hz by step 50 Hz.
it,s hardware is very simple (Atmega32 and 4Mhz crystal and two 22Pf capacitors)

I really need to your help.
Please help me.


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
/*****************************************************
 
 
Chip type               : ATmega32
Program type            : Application
AVR Core Clock frequency: 4000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 512
*****************************************************/
 
#include <mega32.h>
 
// Standard Input/Output functions
#include <stdio.h>
 
 
void main(void)
{
char a=0;
 
//unsigned char x_msec;
 
//unsigned char rst[8]={tt};
//integer tt;
// Declare your local variables here
 
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTA=0x00;
DDRA=0x00;
 
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0xff;
 
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0xff;
 
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0xf0;
 
//-----------------------------------------------------------------------
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
 
 TCCR0=0x00;  
 TCNT0=0x00;      //0Hz
 OCR0=0x00;         
 
//-----------------------------------------------------------------------------
 
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: DisconGenerationnected    200-400Hz
//ASSR=0x00;
 
TCCR2=0x0;  
 
//--------------------------------------------------------------------------------
 
//-------------------------------------------------------------------------------
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
//--------------------------------------------------------------------------------
 
#asm("sei")
 
while (1)
      {   
      
    
   a=getchar();
 
 
//2.frequency 200-400Hz                                       
     if (a=='f')    
          {    
          
            TCCR2=0x00;
           
           //OCR2=0x64;   
           OCR2=0x1A;
           TCCR2=0x6C;     
           TCNT2=0xD9;             //400Hz
           // TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable 
            
         }
                         
      if (a=='b' )
         {  
         
           TCCR2=0x00;  
           OCR2=0x2C; 
           TCCR2=0x6C;
            
           TCNT2=0x4D;             //350Hz 
          // TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable 
           putchar (TCNT2);
          
         
          }    
          
       if (a=='c')
         {       
         
          TCCR2=0x00;
           OCR2=0x1A;     
          TCCR2=0x6C; 
             
          TCNT2=0x30;             //300Hz
         // TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable 
          
          
           
          }     
                           
        if (a=='d')
         {    
          
           TCCR2=0x00;  
           OCR2=0x1A;
          TCCR2=0x6C;
               
          TCNT2=0x06;             //250Hz
         // TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable  
          
          
          
        
          }    
                
        if (a=='e')
         {        
         
        
             TCCR2=0x00;    
             OCR2=0x1A;
           //TCCR2=0x1D; 
                  
           //TCNT2=0x64;          //200Hz:    setting of 400Hz, only prescaled changed )
           //OCR2=0x60; 
 
            TCCR2=0x6D; 
                  
           // TCNT2=0x64;          //200Hz:    setting of 400Hz, only prescaled  changed )
           
           TCNT2=0x64;             //200Hz 
           // TIMSK |= (1<<TOIE2) | (0<<OCIE2);        //Timer2 Overflow Interrupt Enable 
            
 
          }   
          
          
         } 
 
                  
 
    
 }
// }
 // }

 
Last edited by a moderator:

usually, the reloading of counting register (TCNT2) do in interruption code, otherwise it value will be changed at random time and consequently no accuracy available
 
It means I take TCNT2 in interrupt of timer2?
according this:
(Sould I Add this part to my program?)




Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  Tcnt2=x
}
 
 
       if (a=='c')
 
 
         {       
         
          TCCR2=0x00;
           OCR2=0x1A;     
          TCCR2=0x6C; 
             
          TCNT2=x; 
          x=0x30;            //300Hz
          TIMSK=0x40;
          
           
          }



Where TCNT2 changes according to the frequency???( Same x variable?)
 
Last edited by a moderator:

i think code may look like this -
Code:
static unsigned char x;	  

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  TCNT2=x; //reload this value at each overflow
}
 

void main ()
{
 TIMSK=1<<TOIE2;//overflow interrupt		
 TCCR2=0x6C; //1<<WGM21|1<<WGM20|1<<COM21|1<<CS02|1<<CS00 \
		fast pwm, top 0xff, clock sel /128 
     
	while(1)
	{
	 	if (a=='c') 
	         {

	          OCR2=0x1A;     
		  x=0x30;   //4000000/(128*(0xff-0x30)=151Hz
	          
	          }
	}
}
 
Hi, shall I tell You the exact output frequency ?

Fout = 122.0703125 Hz, you will be getting. Correct ?

Reason

Untitled.png

To avoid it you have to enable TOVn interrupt and reload TCNT2 every interrupt.
 
Thanks Venkadesh_M, Do you suggest the code above? (Code of Dear DeepOne) I think I should use from it...So I am going change my code to it....The accuracy of frequency is very important for me in this program......
 

I have a problem yet...
I used timer2 of atmega32 in fast PWM mode. For generating 2 pulses with 250 and 400 Hz and duty cycle 0.07, I modified TCNT2 only (TCCR2 is fixed) and I took it in interruption. But it doesnot work.....Please help me....frequency is fixed in 250 Hz and doesnot change....My code is here...Help...please...please....



Code dot - [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
#include <mega32.h>
 
// Standard Input/Output functions
#include <stdio.h>
 
static unsigned char x;   
 
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  TCNT2=x; //reload this value at each overflow
}
 
void main( )
{
char a=0;
 
PORTC=0x00;
DDRC=0xff;
 
PORTD=0x00;
DDRD=0xf0;
 
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
 
TIMSK=1<<TOIE2;//overflow interrupt     
 TCCR2=0x6C; //1<<WGM21|1<<WGM20|1<<COM21|1<<CS02|1<<CS00 \    fast pwm, top 0xff, clock sel /128 
//#asm("sei")
 
while (1)
      {   
      
      
   a=getchar();
//2.frequency 200-400Hz                                       
     if (a=='f')    
          {    
             
           OCR2=0x1A;     
           x=0xD9;             //400Hz
 
         }
                         
      if (a=='b' )
         {  
             
           OCR2=0x2C;     
             x=0x4D;             //350Hz 
 
          }    
          
       if (a=='c')
         {       
         
           OCR2=0x1A;         
            x=0x30;             //300Hz
     
          }     
                           
        if (a=='d')
         {    
           
           OCR2=0x1A;  
            x=0x06;             //250Hz
     
        
          }    
                
        if (a=='e')
         {        
         
           
             OCR2=0x1A;
   
                  
     
 
             x=0x64;             //200Hz 
 
          }   
          
          
         } 
 }

 
Last edited by a moderator:

OCR2 should be higher than TCNT2 initial value

Code C - [expand]
1
2
3
x = value for TCNT2
and
OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );


in each case.
 
OCR2 should be higher than TCNT2 initial value

Code C - [expand]
1
2
3
x = value for TCNT2
and
OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );


in each case.

I did it, in each case duty cycle changes but frequency is fixed. it is about 4.2 ms which equals 438 Hz. I do not know why it happens? my code is below...I am confused...please ...please...help...

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
#include <mega32.h>
 
// Standard Input/Output functions
#include <stdio.h>
#include <delay.h>
 
static unsigned char x;   
 
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  TCNT2=x; //reload this value at each overflow
}
 
////////////////////////////////////////////////////////////////////////////////////////////////////
void main( )
{
char a=0;
PORTC=0x00;
DDRC=0xff;
 
PORTD=0x00;
DDRD=0xf0;
//-------------------------------------------------------------------------------
 
UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
//--------------------------------------------------------------------------------
 
TIMSK=1<<TOIE2;//overflow interrupt     
 TCCR2=0x6C; //1<<WGM21|1<<WGM20|1<<COM21|1<<CS02|1<<CS00 \    fast pwm, top 0xff, clock sel /128 
//#asm("sei")
 
while (1)
      {   
      
    
   a=getchar();   if (a=='f')    
          {    
             
           //OCR2=0x1A;     
           x=0xD9;             //400Hz
           OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
         }
                         
      if (a=='b' )
         {  
             
           //OCR2=0x2C;     
            x=0x4D;             //350Hz      
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
 
          }    
          
       if (a=='c')
         {       
         
           //OCR2=0x1A;         
            x=0x30;             //300Hz   
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
     
          }     
                           
        if (a=='d')
         {    
           
           //OCR2=0x1A;  
            x=0x06;             //250Hz     
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
     
        
          }    
}

 

and uncomment //#asm("sei") ))
and TCCR2=0x6C; - must be TCCR2=0x6D; (0b01101101) - that is my mistake
 
Thanks Dear Deepone and Dear Venkadesh_M ..... It answered...I really appreciate you....Thanksss

- - - Updated - - -

The circuit works well. But there is a small problem. In normal mode (means without any pressing key to produce pulse with any frequency) , output is high. I do not why!!! ??? (But by pressing a key the pulse with accurate frequency generates) Can you help me to remove the high output? (My code is here) please do me a favor to remove this problem...help....please...thanks alot....
Code:
#include <mega32.h>

// Standard Input/Output functions
#include <stdio.h>
#include <delay.h>
 
static unsigned char x;	  

interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
  TCNT2=x; //reload this value at each overflow
}
 
////////////////////////////////////////////////////////////////////////////////////////////////////
void main( )
{
char a=0;


 
PORTC=0x00;
DDRC=0xff;

PORTD=0x00;
DDRD=0xf0;
        
//------------------------------------------------------------------------

UCSRA=0x00;
UCSRB=0x18;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x19;
//--------------------------------------------------------------------------------
  #asm("sei")
TIMSK=1<<TOIE2;//overflow interrupt		
 TCCR2=0x6C; //1<<WGM21|1<<WGM20|1<<COM21|1<<CS02|1<<CS00 \    fast pwm, top 0xff, clock sel /128 


while (1)
      {   
         
   a=getchar();

  
//frequency 200-400Hz                                       
     if (a=='f')    
          {    
             
           //OCR2=0x1A;     
           x=0x64;             //400Hz
           OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
         }
                         
      if (a=='b' )
         {  
             
           //OCR2=0x2C;     
            x=0x4D;             //350Hz      
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );

          }    
          
       if (a=='c')
         {       
         
           //OCR2=0x1A;         
            x=0x30;             //300Hz   
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
     
          }     
                           
        if (a=='d')
         {    
           
           //OCR2=0x1A;  
            x=0x06;             //250Hz     
            OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 );
        
          }    
                
        if (a=='e')
         {        
         
             
             //OCR2=0x1A;
 
             x=0x64;             //200Hz 
             OCR2 =(unsigned char) x + ( ( 256 - x ) * 0.07 ); 
                  
           //TCNT2=0x64;          //200Hz:    setting of 400Hz, only prescaled changed )
           //OCR2=0x60; 

                  
           // TCNT2=0x64;          //200Hz:    setting of 400Hz, only prescaled  changed )
            
 
          }   
          
          
         }
 

before while(1)
put

Code C - [expand]
1
2
x = 0;
OCR2 = 0;



Or you have to access the pin using GPIO mode.

- - - Updated - - -

before while(1)
put

Code C - [expand]
1
2
x = 0;
OCR2 = 0;



Or you have to access the pin using GPIO mode.
 
Thanks Dear Venkadesh_M,
By using { x=0; OCR2=0 } It is high yet...
Would you please describe about GPIO mode. I did not use this property until now and I do not know what I sall do. Thanks for your help...tahnks alot....
 

in Proteus model in this case the short pulses are present at output.
possible try to do so - "static unsigned char x=0xff;"
instead of "static unsigned char x;"
 
Hi

Its true, In this mode it cant be purely zero.

I never used Atmega before, I think it will have DDR register and PORT access register you have to configure in the beginning. DeepOne will help you on that.

When a key is pressed you have to initialize the timer.
 

Thanks alot Dear DeepOne and Dear Venkadesh_M ..... You really helped me...My circuit works well...Thanks alot...
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top