I'm learning about the LCD display drive in an ATmega169pa (and AVR, C and assembly). I've seen how it works IRL on a scope, and I know what most of the basic settings would be.
In this example from the datasheet below, they want to set the "LCDCRB – LCD Control and Status Register B" to the desired b11100111, which would be for
MSB b7=1 for external clock
b6=1 for Vcc/3 bias
b5:4=10 for 1/3 duty cycle
b3=0 reserved
b2:0=111 if up to segment 24, is to be used (ignoring they only want SEG21 to SEG24 for now)
So if someone wanted to load this into the chip, wouldn't they just store this one 8-bit number in the memory, and then load it up into the LCDCRB register when the MCU starts running ? Maybe just to not use that 1 byte, it would add up for all the other stuff that needs setting ? But the program code takes space too so ??
Instead they do it with bitwise leftshift, and bitwise OR. I'm probably missing something, otherwise, I don't get why they do all this.
from page 241
Assembly Code Example(1)
LCD_Init:
; Use 32 kHz crystal oscillator
; 1/3 Bias and 1/3 duty, SEG21:SEG24 is used as port pins
ldi r16, (1<<LCDCS) | (1<<LCDMUX1)| (1<<LCDPM2)
sts LCDCRB, r16
; Using 16 as prescaler selection and 7 as LCD Clock Divide
; gives a frame rate of 49 Hz
ldi r16, (1<<LCDCD2) | (1<<LCDCD1)
sts LCDFRR, r16
; Set segment drive time to 125 µs and output voltage to 3.3 V
ldi r16, (1<<LCDDC1) | (1<<LCDCC3) | (1<<LCDCC2) | (1<<LCDCC1)
sts LCDCCR, r16
; Enable LCD, default waveform and no interrupt enabled
ldi r16, (1<<LCDEN)
sts LCDCRA, r16
ret
C Code Example(1)
Void LCD_Init(void);
{
/* Use 32 kHz crystal oscillator */
/* 1/3 Bias and 1/3 duty, SEG21:SEG24 is used as port pins */
LCDCRB = (1<<LCDCS) | (1<<LCDMUX1)| (1<<LCDPM2);
/* Using 16 as prescaler selection and 7 as LCD Clock Divide */
/* gives a frame rate of 49 Hz */
LCDFRR = (1<<LCDCD2) | (1<<LCDCD1);
/* Set segment drive time to 125 µs and output voltage to 3.3 V*/
LCDCCR = (1<<LCDDC1) | (1<<LCDCC3) | (1<<LCDCC2) | (1<<LCDCC1);
/* Enable LCD, default waveform and no interrupt enabled */
LCDCRA = (1<<LCDEN);
Just from the " (1<<LCDCS) | (1<<LCDMUX1)| (1<<LCDPM2) " section, that they want to load into r16
The initial value of the LCDCS, Clock select bit b7 is 0. And so are all the other initial values. So for 1<<LCDCS, isn't that just 1<<0 = 1
And then the same for the other 2, and then bitwise OR would be (1|1|1)=1 ?? , so at best b0000001, and not b11100111 ??
What am I missing here ?
Ok they don;t even use LCD2B is the 1st section, so yeah it would never work.
But for the expression
1<<LCDCS, would they really mean 10000000<<0, since the LCDCS is the 8th bit ? Then I can see the OR getting somewhere.