2

I want to control the contrast and backlight of an HD44780 LCD display with two PWM signals. I would like to use PB1 and PB2 (Pin 9 and Pin 10) for this. As far as my research goes, timer1 is responsible for the two pins. OCR1A and OCR1B are responsible for the pulse length.

With the code below I get a frequency of 7.823 kHz and a duty cycle of 88%. But it works only on PB1. PB2 is still constant 0V. I am using the AtmelStudio, therefore I don't have access to functions like pinMode(10, Output)

How can I have different duty cycles on pin 9 and 10?

#define F_CPU 16000000UL
#include <avr/io.h>

int main(void)
{
    DDRB |= (1 << DDB1) | (1 << DDB2);
    OCR1A = 900;
    OCR1B = 400;
    TCCR1A |= (1 << COM1A1);
    TCCR1A |= (1 << WGM11) | (1 << WGM10);
    TCCR1B = (TCCR1B & 0b11111000) | (1 << CS10);

}
  • You can't control the contrast with PWM unless you filter it properly to provide the correct voltage. Personally I use a digipot for contrast. – Majenko Aug 9 '17 at 15:05
  • I want to use PB1 for backlight and PB2 for contrast. analogWrite() is not inside AtmelStudio. – Albritter Aug 9 '17 at 15:09
  • Maybe you should use the Arduino IDE with your Arduino. Or copy and paste the Arduino source code into your project. – Majenko Aug 9 '17 at 15:11
  • As far as I have been able to test it. It will work. I might add a circuit to filter it but that's down the line. – Albritter Aug 9 '17 at 15:12
  • Without a filter you will get flicker as it switches rapidly between full contrast and zero contrast. – Majenko Aug 9 '17 at 15:13
2

After trying a lot of things i got it working. And even the contrast is working directly on the pwm signal.

#define F_CPU 16000000UL
#include <avr/io.h>
void main(void){
    DDRB = 0x06;
    OCR1A = 200; //Duty cycle for PB1 ~80%
    OCR1B = 100; //Duty cycle for PB2 ~40%
    TCCR1A = 0; //Set TCCR1A to zero. We will configure it manually
    TCCR1A |= (1 << COM1A1) | (0 << COM1A0) | ( 0 << COM1B0) | (1 << COM1B1);
    TCCR1A |= (0 << WGM12) | (0 << WGM11) | (1 << WGM10); 
    TCCR1B = 0; //Set TCCR1B to zero. We will configure it manually
    TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
    while(1){

    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.