Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - Trubi

Pages: [1]
1
Graphic LCDs / NHD-C12864B2Z-RN-FBW w/PIC16LF1939
« on: September 17, 2014, 07:13:39 AM »
Although there is another thread in this section about this model of COG LCD, I think that starting a new thread is a better option, as the MPU is different.

I've purchased a couple of NHD-C12864B2Z-RN-FBW displays, and connected one of them to a Microchip PIC16LF1936 microcontroller, keeping the second display as a spare unit. Both the display and the PIC microcontroller are powered at 3.3V from a digital, adjustable power supply. Connections have been made following the NHD's datasheet, using 5 x 100nF ceramic capacitors for V0~V4 pins, and 4 x 1uF tantalum capacitors for C1~C3 pins (paying special attention to polarity).

As a starting point, I'm trying to initialize the display (adapting the Example Initialization Program provided by NHD) and then to turn all the display points ON (command 0xA5). But somehow the display seems not to react to any command sent from the PIC, as it is always "clear" (no segments are lighted up). I've double checked all the connections in the proyect board and everything seems to be OK. Also I've checked the signals coming out of the PIC microcontroller using a 4-channel oscilloscope, and both the 8-bit data and the timing between data and /WR signal seem to be OK. The /RD signal is tied to VDD, and the A0 signal is controlled by the PIC, but that line is working OK (always on low-state, as we're writing commands). I've also tried the spare display without success.

FYI, I'm using a NHD-FFC30 board to connect the display to my project board, making sure that the 1# pin on the FFC strip matches the 1# pin on my board.

Here's the code I'm using (compiled with CCS and debugged with MPLAB 8 ). Any advice on how to deal with this situation will be greatly appreciated:

Code: [Select]
//========================================

int8 const LCD_INIT_STRING[10] =
{
0xA2, // 1/9 bias
0XA0, // ADC select, normal
  0xC8,                                      // COM output reverse
  0xA4,                                      // Display all points normal
0x40, // Display start line set
0x25, // Internal resistor ratio
0x81, // Electronic volume set
0x10, // Electronic volume
0x2F, // Power controller set
0xAF        // Display ON
};
                             

//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note:  !! converts an integer expression
// to a boolean (1 or 0).

 output_bit(LCD_DB0, !!(nibble & 1));
 output_bit(LCD_DB1, !!(nibble & 2));
 output_bit(LCD_DB2, !!(nibble & 4));   
 output_bit(LCD_DB3, !!(nibble & 8));
 output_bit(LCD_DB4, !!(nibble & 16));
 output_bit(LCD_DB5, !!(nibble & 32));
 output_bit(LCD_DB6, !!(nibble & 64));   
 output_bit(LCD_DB7, !!(nibble & 128));   

 delay_cycles(2);
 output_low(LCD_W);

 delay_ms(1);
 output_high(LCD_W);
}

//-----------------------------------
// This sub-routine is only called by lcd_read_byte().

int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
#bit retval_4 = retval.4
#bit retval_5 = retval.5
#bit retval_6 = retval.6
#bit retval_7 = retval.7

retval = 0;

output_low(LCD_R);
delay_cycles(300);

retval_0 = input(LCD_DB0);
retval_1 = input(LCD_DB1);
retval_2 = input(LCD_DB2);
retval_3 = input(LCD_DB3);
retval_4 = input(LCD_DB4);
retval_5 = input(LCD_DB5);
retval_6 = input(LCD_DB6);
retval_7 = input(LCD_DB7);
 
output_high(LCD_R);
   
return(retval);   
}   


//---------------------------------------
// Read a byte from the LCD and return it.

int8 lcd_read_byte(void)
{
int8 lectura;

//output_low(LCD_R);
//delay_cycles(1);

lectura = lcd_read_nibble();

return(lectura);
}

//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{

while(bit_test(lcd_read_byte(),7)) ;

if(address)
   output_high(LCD_A0);
else
   output_low(LCD_A0);
     
 delay_cycles(1);

lcd_send_nibble(n);
}

//----------------------------
void lcd_init(void)
{

int8 i;

output_high(LCD_R);
output_high(LCD_W);
output_low(LCD_A0);

delay_ms(100);

for(i=0; i < sizeof(LCD_INIT_STRING); i++)
   {
    lcd_send_byte(0, LCD_INIT_STRING[i]);
   }

}


As for the "main":

Code: [Select]
#include <16LF1939.H>
#fuses HS,INTRC_IO,NOCLKOUT,NOWDT,PUT,NOPROTECT,BROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock = 500000)

#byte   OPTION_REG = 0x095
#byte   OSCCON   = 0x099

#define LCD_DB0   PIN_A0
#define LCD_DB1   PIN_A1
#define LCD_DB2   PIN_A2
#define LCD_DB3   PIN_A3
#define LCD_DB4   PIN_A4
#define LCD_DB5   PIN_A5
#define LCD_DB6   PIN_A6
#define LCD_DB7   PIN_A7

#define LCD_A0    PIN_E2
#define LCD_R     PIN_E0
#define LCD_W     PIN_E1

#include "flexdriver8bit.c"

//==========================
void main()
{

OSCCON = 0b0110100;

lcd_init();  // Always call this first.

int i = 0;

int8 nada;

while(1)
{
lcd_send_byte(0, 0xA5);
delay_ms(50);
}
}


Thanks in advance!

Cheers,

Ruben

Pages: [1]