Thanks Spehro Pefhany for your answer and the nice discussion! I just want to summerice the discussion and my additional research combined with some images and a C++ code file.
The lcd mentioned in the Question is an static drive display. It is not valid to apply a static dc field between the segment electrode and the common electrode! It will destroy the display. The best way to avoid that is to alternate the voltage on the common pin between ground and vcc. Every segment that is on, must have the oposite potential than the common pin (ex.: Common: Hight --> Segment: Low). Every segment that is off, must have the same potential then the common pin (ex.: Common: Hight --> Segment: Hight). Normally an lcd is driven with a frequency around 30-60Hz (higher is not a fault, it just consumes more power)
For evaluation purpose I connected the common of the display to PA.0 of an ATTiny. In addition i connected two segments, one to PA.1 the other to PA.2:
I used a timer and the compare interrupt to trigger the io change operation. The following cpp File was used to alternate between two segments:
/*
* TryLCD.cpp
*
* Created: 11.01.2020 12:49:58
* Author : Ludwig Füchsl
* Description: Evaluation code for driving an static lcd glass directly with an ATTiny
*/
// 8MHz internal oscillator
#define F_CPU 8000000UL
// Include atmel libs
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
// Bit for common high low
bool bit = false;
// Segment a desired value
bool a = false;
// Segment b desired value
bool b = false;
// Output compare match interrupt
ISR(TIM0_COMPA_vect){
// Invert common every clock cycle to generate alternating field in lcd
bit = !bit;
// Set the current common state
if(bit) PORTA |= (1UL << 0);
else PORTA &= ~(1UL << 0);
// Determinate segment a state via xor with common
if(bit ^ a) PORTA |= (1UL << 1);
else PORTA &= ~(1UL << 1);
// Determinate segment b state via xor with common
if(bit ^ b) PORTA |= (1UL << 2);
else PORTA &= ~(1UL << 2);
}
// Main program
int main(void){
cli();
// == Setup IO ==
// Port A output
DDRA = 0xFF;
// Port A all off
PORTA = 0x00;
// == Setup Timer Meta ==
// Clear on compare
TCCR0A |= (1UL << WGM01);
// Timer prescaler clk/256
TCCR0B |= (1UL << CS02);
// Setup Time Interrupt
// Compare match A on 255
OCR0A = 0xFF;
// Compare match a A interrupt enable
TIMSK0 |= (1UL << OCIE0A);
// Interrupts on
sei();
// Setup default segment values
a = true;
b = false;
// Main loop
while (1) {
// Wait for 1s
_delay_ms(1000);
// Invert a and b
a = !a;
b = !b;
}
}
Using my test setup and this code, i took some measurement with my scope.
On Chanel 1 (yellow) is the common. On Chanel 2 (green) is segment A (In this case the segment is NOT lit). On Chanel 3 (orange) is segment B (In this case the segment is lit)
Please note that if you are not using an static lcd (Multiple commons) the lcd needs to be multiplexed! This results in the need of more that two voltage levels! For more information please also read this document by microchip: Application Notice 658