This is my program which doesn't working correctly.
MCU, regardless of the position of the lever on the remote control, sends a signal to pin D PB2 4.7V. On other pins A PB3, B PB2, C PD5 is 0V. Engine isn't running.
Link to the datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/doc8246.pdf
- TCCR0A form 82 page
- TCCR1A form 111 page
How should I set the registers to generate PWM signal on pins?
- PB3 + PB2 Engine turn left
- PB4 + PC5 Engine turn right
- RC receiver sends PWM signal to MCU on PD2 pin.
I'm writing program in Microchip Studio to control DC 6V engine (graupner 400 max 4,0A) using RC radio receiver.
I'm using Attiny 2313A with F_CPU 16 MHz.
To control motor I would like to generate a PWM signal with a frequency of 1 kHz.
Thanks a lot.
#define F_CPU 16000000L
#define MCU attiny2313
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#define A PB3
#define D PB2
#define B PB4
#define C PD5
volatile uint16_t R = 0;
volatile uint8_t R0 = 0;
volatile uint16_t R1 = 0;
void measurePWM() {
TCNT1 = 0;
while (!(PIND & (1 << PD2)));
while (PIND & (1 << PD2));
R = TCNT1;
}
int main(void) {
TCCR0A = (1 << COM0A1) | (1 << WGM02) | (1 << WGM01) | (1 << WGM00);
TCCR1A = (1 << COM1A1) | (1 << WGM12) | (1 << WGM10);
TCCR0B = (1 << COM0B1) | (1 << WGM02) | (1 << WGM01) | (1 << WGM00) | (1 << CS01);
TCCR1B = (1 << COM1B1) | (1 << WGM12) | (1 << WGM10);
DDRB |= (1 << DDB2) | (1 << DDB3) | (1 << DDB4);
DDRD |= (1 << DDD5);
PORTB &= ~((1 << A) | (1 << D) | (1 << B));
PORTD &= ~(1 << C);
DDRD &= ~(1 << PD2);
PORTD &= ~(1 << PD2);
while (1) {
measurePWM();
R0 = (R - 958) * 255 / (1815 - 958);
R1 = (R - 958) * 65534 / (1815 - 958);
if (R >= 1500) {
OCR0A = 0;
OCR1A = 0;
OCR0B = R0;
OCR1B = R1;
} else if (R <= 1300) {
OCR0A = 0;
OCR1A = 0;
OCR0B = R0;
OCR1B = R1;
} else {
OCR0A = 0;
OCR0B = 0;
OCR1A = 0;
OCR1B = 0;
}
_delay_ms(100);
}
return 0;
}
If you want to generate a PWM, you can use the timer for it. Check the datasheet of Tiny2313A. The block diagram on page 71 shows that there is already a waveform generation mode integrated in timer0. If you want to use other pins it is necessary to use timer interrupts.
The timer supports two modes for PWM generation
A simple example to generate a waveform at around ~1kHz with integrated PWM modes:
If the OC pins of the microcontroller are used it is not necessary to use the ISRs because the timer itself sets the OC pins. You have already used that in your example.
If you want to measure an external pwm clock cycle it is necessary to extend the program with an external interrupt. A predefined pin triggers the external interrupt. With the status of the pin and with an additional timer it is possible to measure the current duty cycle e.g:
Maybe this helps. Currently i have no platform to test...