I think your commands are a little wrong. Let's look at them:
LcdWriteCmd(0xAE); // LCD set display enabled
0xAE is 0b10101110. In the datasheet the matching command is
# is display on (1) or off (0), so 0xAE is actually display disabled. Changing it to 0xAF instead, so bit 0 is 1, should enable the display.
LcdWriteCmd(0x21); // LCD set power COntrol
0x21 is 0b00100001. That command is
### is the VLCD resistor ratio. That is being set to 2/8. ((
# + 1) / 8).
LcdWriteCmd(0x14); // LCD bias mode 1:40
0x14 is 0b00010100, which is command
0001#### which sets the column address MSB. Quite why you're doing that I don't know, but that command has nothing to do with bias mode...
LcdWriteCmd(0xA2); // LCD basic commands
No, 0xA2 / 0xA3 sets the bias ratio set, which selects the bias from one of two groups of biases depending on the current duty. This is the default value.
So not only are you not configuring the screen correctly, but you aren't even then trying to put anything on the screen to see if it's working or not.
I suggest you work from the provided example code:
The "Initial" function sets the sequence of operations:
The main commands are defined at the top of the file:
#define DISPLAY_ON() Write_Instruction(0xaf) // Display on
#define DISPLAY_OFF() Write_Instruction(0xae) // Display off
#define SET_ADC() Write_Instruction(0xa1) // Reverse disrect (SEG131-SEG0)
#define CLEAR_ADC() Write_Instruction(0xa0) // Normal disrect (SEG0-SEG131)
#define REVERSE_DISPLAY_ON() Write_Instruction(0xa7) // Reverse display : 0 illuminated
#define REVERSE_DISPLAY_OFF() Write_Instruction(0xa6) // Normal display : 1 illuminated
#define ENTIRE_DISPLAY_ON() Write_Instruction(0xa5) // Entire dislay Force whole LCD point
#define ENTIRE_DISPLAY_OFF() Write_Instruction(0xa4) // Normal display
#define SET_BIAS() Write_Instruction(0xa3) // bias 1 1/7 bais
#define CLEAR_BIAS() Write_Instruction(0xa2) // bias 0 1/9 bais
#define RESET() Write_Instruction(0xe2) // system reset
#define SET_SHL() Write_Instruction(0xc8) // SHL 1,COM63-COM0
#define CLEAR_SHL() Write_Instruction(0xc0) // SHL 0,COM0-COM63
The more complex ones are simple enough - just ORing the provided parameter with the base command. For example
Power_Control() just does:
I am sure you can find (and decipher) the rest of the commands to initialize the screen properly.