The HD44780 requires a large voltage difference between Vcc and Vo to get a good contrast on the screen. When running at 5v, this difference can be pretty pretty easily achieved by merely putting a resistor between Vo and ground, dropping a certain voltage across it. However, when running at 3v, this voltage difference isn’t enough, even if Vo is connected directly to ground. To get around this, one can build a really easy circuit (by really easy, I mean really easy, it only requires 5 components and a spare GPIO pin!).
This special magical kind of circuit is called a charge pump (http://goo.gl/I3S1yJ). A charge pump realistically works quite simply: Charge is placed on one plate of a capacitor, causing a difference in charge between the two capacitor plates. The charged side is then placed from a positive voltage to ground, shifting this charge from the once positively charged plate to the opposing plate. This movement of charge can be directed using diodes to produce voltages higher than the initially charges plate or inverted voltages, with the same magnitude (in an ideal diode world with no VFwd) as the positive voltage, just negative!
I’m not the best at wordy explanations so lets have a look at a simulation! Instead of using any specifically required pins on my STM32F0, I’ve used a standard GPIO pin and have used the Systick interrupt to toggle the pin at a rate of 500Hz (the interrupt is fired every 1000Hz and a toggle takes two “cycles” through the interrupt, halving the pin toggle rate). By using a standard GPIO pin for this, I’m not tied to using any specific pins and can use whatever is free to produce my negative voltage.
Using a 3v clock source at 500Hz with a series resistor (used to set the contrast, in practice, I’m using two 820ohm resistors in parallel as I don’t have a 410ohm resistor!) of 410 ohms, two 1N4148 diodes and two diodes, one can generate a voltage at VCC-(2*VFwd of diodes), giving me a voltage of around -2.6v! This gives a total voltage differential of up to 3–2.6 = 5.6v, much more than is required! In practice, the output is loaded by the LCD and this negative voltage drops to -0.908v. The voltage drop is dependent on the series resistor. By increasing this, you can decrease the contrast and vice versa. I merely picked 410ohms because it made my display look good, you may require a different value!
As you can see above, no magic is really happening. The clocked voltage range has merely been shifted from 0v – 3v down to -2.6v – 0.4v or so. This negative voltage is then half rectified thanks to D2 and regulated by capacitor C2. The series resistor also limits the current to some normal value (8mA peak in the simulation) as the initial current flows into the capacitor can be quite large (realistically dependent on the rise and fall times of the signal, I = c * dV/dt!). Once rectified, the voltage sits at a relatively smooth -2.7v!
In reality, the clock source in the simulation image is replaced with the GPIO pin from the microcontroller. I’m using GPIOA Pin 7 for my clocked output.
I’ve only slightly modified my code and if you want to go back to the chargepump-less version, just go to the second revision – b2fe4fa1b742f77ba139043f5f21ac2fcf3b5eac.
My github repo of this can be found at: https://github.com/pyrohaz/STM32F0-HD44780LCD
I’m always revising code so I’ll make sure to keep this updated! My next step will be to include PWM control for the LED backlight.
If you have any questions, ask away!