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.

Controlling the frequency of PWM in AVR

Status
Not open for further replies.

Magdy_said

Newbie level 6
Newbie level 6
Joined
Sep 28, 2018
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
151
My goal is it to control one mosfet with pwm from ATMEGA32A.

after watching some tutorial and codes on internet i got this 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
#ifndef F_CPU                   // if F_CPU was not defined in Project -> Properties
#define F_CPU 1000000UL         // define it now as 1 MHz unsigned long
#endif
 
#include <avr/io.h>             // this is always included in AVR programs
#include <avr/interrupt.h>
 
///////////////////////////////////////////////////////////////////////////////////////////////////
int main(void) {
    
    DDRC |= (1 << PC5) | (1 << PC4);            // set PC5 (pin 28) and PC4 (pin 27) for output
    
    /*
    TCCR1A - Timer/Counter 0 Control Register A
    
    bit           7         6         5         4        3       2        1        0
    name        COM1A1    COM1A0    COM1B1   COM1B0    FOC1A   FOC1B    WGM11    WGM10
    set to        0         0         0         0        0       0        0        1
    
    COM1A1 = 0    normal port operation, OC1A disconnected
    COM1A0 = 0
    
    com1B1 = 0    normal port operation, OC1B disconnected
    com1B0 = 0
    
    bit 3 = 0
    bit 2 = 0
    
    WGM11 = 1     CTC (Clear Timer on Compare match) mode, see TCCR0B also
    WGM10 = 0     TCNT0 will count up to value in OCR1A, then signal timer 0 compare interrupt
    */
 
    TCCR1A = 0b00000001;
    
    /*
    TCCR1B - Timer/Counter 0 Control Register B
    
    bit           7          6        5       4         3         2         1        0
    name        ICNC1      ICES1      -      WGM13      WGM12      CS12      CS11     CS10
    set to        0          0        0       0          1          1         0        1
    
    ICNC1 = 0     
    FOC0B = 0
    
    bit 5 = 0
    WGM13 = 0
    
    WGM02 = 0     CTC (Clear Timer on Compare match) mode, see TCCR0A also
    
    CS02 = 0
    CS01 = 1      clock / 64, should not use less than this to allow ISR enough clock cycles
    CS00 = 1
    */
 
    TCCR1B = 0b00001010;
    
    /*
    TIMSK - Timer/Counter 0 Interrupt Mask Register
    
    bit           7        6        5       4       3       2         1         0
    name          -        -     TICIE1  OCIE1A  OCIE1B   TOIE1       -       -
    set to        0        0        0       1       0       0         0         0
    
    bit 7 = 0     don't use Force Output Compare A
    bit 6 = 0
    bit 5 = 0
    bit 4 = 0
    bit 3 = 0
    OCIE1B = 0    don't enable Timer/Counter 0 Output Compare Match B Interrupt
    OCIE1A = 1    enable Timer/Counter 0 Output Compare Match A Interrupt Enable
    TOIE1 = 0     don't enable Timer/Counter 0 Overflow Interrupt
    */
    TIMSK = 0b00010000;
    
    PORTC |= (1 << PC4);        // turn on PC4 (pin 27) full bright
    
    OCR1A = 0b00000001;     // set compare register to low value to produce fast PWM
    
    sei();              // enable interrupts
    
    while (1) { }
    
    return(0);                  // should never get here, this is to prevent a compiler warning
}
 
///////////////////////////////////////////////////////////////////////////////////////////////////
ISR(TIMER1_COMPA_vect) {
    PORTC ^= (1 << PC5);
}




but i don't know how to control frequency or duty cycle, i know that OCR1A should control duty cycle but however, i change it between 0 and 255 nothing happens it only gives 50% duty cycle

the frequency changes already wwhen i change the prescaller, but i can't just take any arbitrary frequancy i need to define an exact frequency or at least an in-range frequency(i know that depends on the type of the chip), the datasheet give an equation for the frequancy of the fast pwm mode (which i am using ) but i don't know what's TOP value !! but data sheet says :

The counter reaches the TOP when it becomes equal to the highest value in the count
sequence. The TOP value can be assigned to be one of the fixed values: 0x00FF, 0x01FF, or
0x03FF, or to the value stored in the OCRnA or ICRn Register. The assignment is dependent
of the mode of operation.

which i don't understand !

u8.PNG

anothe thing is that i am usning "protus 8" software to test my codes before downloading it onto the avr, i just use very primite way of calaculating the output frequency by counting the squares on the osilloscope screen, protus keeps shifting the signal downwards so the pwm looks lika an ac signal, i don't know if there is something wrong with the code or protus just not very accurate!

u7.PNG
 
Last edited by a moderator:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top