浏览代码

i2c_timer_pwm.c initial PWM initialization.

master
kevin.larke 4 年前
父节点
当前提交
04dc59ee48
共有 2 个文件被更改,包括 55 次插入22 次删除
  1. 1
    1
      control/tiny/Makefile
  2. 54
    21
      control/tiny/i2c_timer_pwm.c

+ 1
- 1
control/tiny/Makefile 查看文件

@@ -3,7 +3,7 @@ TTY=/dev/ttyACM0
3 3
 endif
4 4
 
5 5
 ifndef TARGET
6
-TARGET=blink
6
+TARGET=i2c_timer_pwm
7 7
 endif
8 8
 
9 9
 MCU=attiny85

+ 54
- 21
control/tiny/i2c_timer_pwm.c 查看文件

@@ -9,17 +9,23 @@
9 9
 
10 10
 #define I2C_SLAVE_ADDRESS 0x8 // the 7-bit address (remember to change this when adapting this example)
11 11
 
12
+
12 13
 enum
13 14
 {
14
- kCS13_10_idx = 0,  // Timer 1 Prescalar (CS13,CS12,CS11,CS10) from Table 12-5 pg 89
15
- kOCR1C_idx   = 1,  // OCR1C timer match value
16
- 
15
+ kCS13_10_idx     = 0,  // Timer 1 Prescalar (CS13,CS12,CS11,CS10) from Table 12-5 pg 89
16
+ kTmr0_Coarse_idx = 1,  // count of times timer0 count to 255 before OCR1C is set to Tmr0_Minor
17
+ kTmr0_Fine_idx   = 2,  // OCR1C timer match value
18
+ kPWM_Duty_idx    = 3,  //
19
+ kPWM_Freq_idx    = 4,  // 1-4 = clock divider=1=1,2=8,3=64,4=256,5=1024
17 20
 };
18 21
 
19 22
 volatile uint8_t ctl_regs[] =
20 23
 {
21
- 0x0f,   // clk/16384
22
- 244,    // OCR1C
24
+ 0x0f,   // 0 (0-15)  timer prescalar 0=stop, prescaler = pow(2,val-1), 0=stop,1=1,2=2,3=4,4=8,....14=8192,15=16384  pre_scaled_hz = clock_hz/value
25
+ 0,      // 1 (0-255) Tmr0_Coarse count of times timer count to 255 before loading Tmr0_Minor for final count.
26
+ 244,    // 2 (0-254) Tmr0_Fine OCR1C value on final phase before triggering timer
27
+ 127,    // 3 (0-255) Duty cycle
28
+ 4,      // 4 (1-4)   PWM Frequency (clock pre-scaler) 
23 29
 };
24 30
 
25 31
 // Tracks the current register pointer position
@@ -28,20 +34,42 @@ const uint8_t reg_size = sizeof(ctl_regs);
28 34
 
29 35
 ISR(TIMER1_OVF_vect)
30 36
 {
31
-  PINB = _BV(PINB4);  // writes to PINB toggle the pins
37
+  PINB = _BV(PINB4) + _BV(PINB1);  // writes to PINB toggle the pins
38
+  
32 39
 }
33 40
 
34
-void timer_init()
41
+
42
+void timer1_init()
35 43
 {
36 44
   TIMSK  &= ~_BV(TOIE1);    // Disable interrupt TIMER1_OVF
37 45
   OCR1A   = 255;            // Set to anything greater than OCR1C (the counter never gets here.)
38 46
   TCCR1  |= _BV(CTC1);      // Reset TCNT1 to 0 when TCNT1==OCR1C 
39 47
   TCCR1  |= _BV(PWM1A);     // Enable PWM A
40
-  TCCR1  |= ctl_regs[kCS13_10_idx] & 0x0f;
41
-  OCR1C   = ctl_regs[kOCR1C_idx];
48
+  TCCR1  |= ctl_regs[kCS13_10_idx] & 0x0f;  // 
49
+  OCR1C   = ctl_regs[kTmr0_Fine_idx];
42 50
   TIMSK  |= _BV(TOIE1);     // Enable interrupt TIMER1_OVF  
43 51
 }
44 52
 
53
+void pwm0_update()
54
+{
55
+  OCR0B   = ctl_regs[kPWM_Duty_idx];  // 50% duty cycle
56
+  TCCR0B |= ctl_regs[kPWM_Freq_idx]; // PWM frequency pre-scaler
57
+}
58
+
59
+void pwm0_init()
60
+{
61
+  //WGM[1:0] = 3 (TOP=255)
62
+  // OCR0B = duty cycle (0-100%)
63
+  // COM0A[1:0] = 2 non-inverted
64
+  //
65
+
66
+  TCCR0A |=  0x20   + 3;    // 0x20=non-inverting 3=WGM bits Fast-PWM mode (0=Bot 255=Top)
67
+  TCCR0B |=  0x00   + 4;    //                    3=256 pre-scaler  122Hz=1Mghz/(v*256) where v=64
68
+
69
+  pwm0_update();
70
+    
71
+  DDRB |= _BV(DDB1);    
72
+}
45 73
 
46 74
 
47 75
 /**
@@ -74,14 +102,14 @@ void on_request()
74 102
  * them directly,
75 103
  */
76 104
 
77
-void on_receive( uint8_t howMany )
105
+void on_receive( uint8_t byteN )
78 106
 {
79
-    if (howMany < 1)
107
+    if (byteN < 1)
80 108
     {
81 109
         // Sanity-check
82 110
         return;
83 111
     }
84
-    if (howMany > TWI_RX_BUFFER_SIZE)
112
+    if (byteN > TWI_RX_BUFFER_SIZE)
85 113
     {
86 114
         // Also insane number
87 115
         return;
@@ -90,24 +118,28 @@ void on_receive( uint8_t howMany )
90 118
     // get the register index to read/write
91 119
     reg_position = usiTwiReceiveByte();
92 120
     
93
-    howMany--;
121
+    byteN--;
94 122
 
95 123
     // If only one byte was received then this was a read request
96 124
     // and the buffer pointer (reg_position) is now set to return the byte
97 125
     // at this location on the subsequent call to on_request() ...
98
-    if (!howMany)
126
+    if (!byteN)
99 127
     {
100 128
       return;
101 129
     }
102 130
 
103 131
     // ... otherwise this was a write request and the buffer
104 132
     // pointer is now pointing to the first byte to write to
105
-    while(howMany--)
133
+    while(byteN--)
106 134
     {
107 135
         ctl_regs[reg_position] = usiTwiReceiveByte();
108 136
 
109
-        if(reg_position == kCS13_10_idx || reg_position == kOCR1C_idx )
110
-          timer_init();
137
+        if( kCS13_10_idx <= reg_position && reg_position <= kTmr0_Fine_idx )
138
+          timer1_init();
139
+
140
+        if( kPWM_Duty_idx <= reg_position && reg_position <= kPWM_Freq_idx )
141
+          pwm0_update();
142
+
111 143
         
112 144
         reg_position++;
113 145
         if (reg_position >= reg_size)
@@ -124,11 +156,12 @@ int main(void)
124 156
 {
125 157
   cli();        // mask all interupts
126 158
     
127
-  DDRB  |= _BV(DDB4);  // setup PB4 as output
128
-  PORTB &= ~_BV(PINB4);
129
-
130
-  timer_init();
159
+  DDRB  |= _BV(DDB4) + _BV(DDB1);  // setup PB4 as output
160
+  PORTB &= ~(_BV(PINB4) + _BV(PINB1));
131 161
 
162
+  timer1_init();
163
+  pwm0_init();
164
+  
132 165
   // setup i2c library
133 166
   usi_onReceiverPtr = on_receive; //on_receive;
134 167
   usi_onRequestPtr = on_request;

正在加载...
取消
保存