Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

HT1621 display driver

Status
Not open for further replies.

psubiaco

Member level 2
Joined
Apr 6, 2003
Messages
42
Helped
1
Reputation
2
Reaction score
0
Trophy points
1,286
Location
Italy
Activity points
610
ht1621 source

Hi all.
I'm trying a custom display using HT1621 controller...

I'm not able to see anything on the display (it remains blank), and I'm not sure that the sequence of commands to init HT1621 is correct..... here is the sequence of commands i sent

ht1621_writecmd(0x18); // Internal RC OSC
ht1621_writecmd(0x01); // SYS EN
ht1621_writecmd(0x03); // LCD ON
ht1621_writecmd(0x05); // DISABLE WDT FLAG OUTPUT
ht1621_writecmd(0x04); // DISABLE TIMEBASE OUTPUT
ht1621_writecmd(0x60); // TONE 2KHz
ht1621_writecmd(0x25); // 3 common, 1/3 duty

If you know the initialization procedure or a sample code (C or ASSEMBLY), please let me know.
Thank you in advance. Paolo
 

ht1621 sourcecode

Hi,

I don't know what is inside your ht1621_writecmd() function. You know, a HT1621 command is 9 bits long and the ID to send after toggling the _CS signal is 3 bits long.
I wrote an initialisation subroutine in PIC16 assembly. The sequence I used is (by the way, my LCD is a 1/3 bias and there is no buzzer connected) :
10000000001X001010X1X00000011X00001000X00001000X
|-||-------||-------||-------||-------||-------|
ID SYS EN BIAS 1/3 LCD ON TONE OFF TONE OFF

(please use a fixed-length font to read this... ID is the 3 bits to put the HT1621 in command mode, the others are 9 bits long)
TONE OFF is repeated twice because the PIC SPI module can send only 8 bits at a time, then ID+SYS_EN+BIAS_1/3+LCD_ON+2xTONE_OFF = 6 bytes such as :
100000000010001010010000000110000010000000010000 (X=0)
|------||------||------||------||------||------|
80h 22h 90h 18h 20h 10h

(once in command mode, you can send all commands without specifying the ID... it is also possible in read and write mode, between those sequence, just toggle the _CS pin low/high/low)

Here is the source code for my PIC16F73 :

LCD_TInit ; data table of bytes to be sent
ADDWF PCL, F
RETLW 80h
RETLW 22h
RETLW 90h
RETLW 18h
; RETLW 20h
; RETLW 10h

(the last two bytes can finally be ommitted)

; init procedure
LCD_Init
BSF PORTA, _CS ; clear the HT1621 SPI registers
BCF PORTA, _CS ; enable SPI on HT1621
CLRF REGA ; init byte counter (0 to 4)

BSF STATUS, RP0
BCF SSPSTAT, BF
BCF STATUS, RP0
Init_SendCom
MOVF REGA, W
CALL LCD_TInit
MOVWF SSPBUF ; load the SPI output buffer
INCF REGA, F
BSF STATUS, RP0
Init_BF
BTFSS SSPSTAT, BF
GOTO Init_BF ; wait for data being sent
BCF SSPSTAT, BF ; clear SPI internal buffer flag
BCF STATUS, RP0
BTFSS REGA, 2 ; REGA==4 ?
GOTO Init_SendCom ; no => proceed to next byte

RETURN



Once the HT1621 initialized, don't forget to send it the data to be displayed !...
My procedure is a bit particular since I send the whole buffer of 16 bytes in a row...
Here is how I made it :
Put _CS high
Put _CS low
write '101' on the SPI lines (HT1621 is then in write mode)
write '000000' on the SPI lines (first address to be written)
write the 16 data bytes (then you don't have to worry about addressing since the HT1621 increments internally the address counter between each byte).

I think that's all :roll:


I hope this will help
 

ht1621 lcd driver using spi

Thank you Beel1.
I've followed your instrunctions, and infact the display now works well....
Thank you for the good support! Best regards. Paolo
 

hi.........

i am using HT1621B lcd driver with atmega88 connected on portD... i want to start my display. so i want to ask do i need a specialized ht1621.h file or a lcd.h header files?
currently i dnt have any of these header files... i dnt know wat to do next exactly..... can anyone tell me the code for its initialization or provide me these header files...
 

hey thanks............. i will try to sort out my problem..
 

hi all......i am still not getting anything on my lcd..... i hav a written a simple code just to start display without using any headers for driver..... this prog is compiled successfully but i dnt get anything on lcd.......

i am using a ext cpu clock of 8Mhzof atmega88 connected to to driver via PB0 pin

can anyone tell me the mistake i made while writing this code..........

your help will be really appriciated....

my code is like this........

#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 250000UL
//#define F_CPU 8000000UL
#include <util/delay.h>

#define LCD_WR PD4
#define LCD_RD PD3
#define LCD_CS PD2
#define LCD_DATA PD5


volatile uint16_t count;

void write_lcd_cmd(unsigned char cmd);
void write_lcd_disp(unsigned char addr,unsigned char data);


int main(void)
{


DDRB=0x01; // ext clk enable

DDRD=0xF7;



/* MAX232_R1OUT-0,MAx232_T1IN-1,HV-PP1,CS-2,RD-3, WR-4,DATA-5, EPROM_CS-6,ADC_SD0-7 */

// 1 1 1 0 1 1 1 1


CLKPR = (1<<CLKPCE);
//_delay_us(1000);
CLKPR = 0x06;//


PORTD= PORTD & ~(1<<LCD_CS); // cs low
_delay_us(100);
write_lcd_cmd(0x03) ; // lcd on command....................00000011
_delay_us(100);
PORTD= PORTD | ((1<<LCD_CS)); // cs high


PORTD= PORTD & ~(1<<LCD_CS); // cs low
_delay_us(100);
write_lcd_cmd(0x29); // cmd 1/3bias , 1/4 duty;..........00101001
PORTD= PORTD | ((1<<LCD_CS)); // cs hi

_delay_us(100);
PORTD= PORTD & ~(1<<LCD_CS); // cs low
write_lcd_disp(0x2,0xF);
write_lcd_disp(0x3,0xF);
PORTD= PORTD | ((1<<LCD_CS)); // cs hi


while(1);



}


}

void write_lcd_cmd(unsigned char cmd)
{

//1
PORTD |= (1<<LCD_WR); // wr high
_delay_us(100);
PORTD= PORTD | ((1<<LCD_DATA)); // data high MSB 3bit com
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low, active low
_delay_us(100);

//2
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_DATA); // data low
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low active low
_delay_us(100);

//3
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_DATA); // data low
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low active low
_delay_us(100);

PORTD= PORTD | (1<<LCD_WR); // wr high

for (int i= 8; i>=0; i--)
{
PORTD= PORTD | (1<<LCD_WR); // wr high
if (!(cmd& (1<<i)))
PORTD= PORTD & ~(1<<LCD_DATA); // data low, if clear
else
PORTD= PORTD | (1<<LCD_DATA); // data high , if set
PORTD= PORTD & ~(1<<LCD_WR); // wr low, active low
_delay_us(100);
}
}


void write_lcd_disp(unsigned char addr, unsigned char data)
{

PORTD |= (1<<LCD_WR); // wr high
_delay_us(100);
//1
PORTD= PORTD | (1<<LCD_DATA); // data high MSB 3bit com .... 1
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low, active low
_delay_us(100);
//2
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);
PORTD= PORTD | ((1<<LCD_DATA)); // data high ..............1
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low active low
_delay_us(100);
//3
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_DATA); // data low . ..............0
_delay_us(100);
PORTD= PORTD & ~(1<<LCD_WR); // wr low active low
_delay_us(100);

PORTD= PORTD | (1<<LCD_WR); // wr high

for (int i= 6; i>=0; i--) // write address 6 bit address,
{

PORTD= PORTD | (1<<LCD_WR); // wr high
if (!(addr & (1<<i)))
PORTD= PORTD & ~(1<<LCD_DATA); // data low, if clear
else
PORTD= PORTD | (1<<LCD_DATA); // data high , if set
PORTD= PORTD & ~(1<<LCD_WR); // wr low, active low
_delay_us(100);

}
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);


for (int i= 1; i<=4; i++) // write data 4 bit data
{
PORTD= PORTD | (1<<LCD_WR); // wr high
if (!(data & (1<<i)))
PORTD= PORTD & ~(1<<LCD_DATA); // data low, if clear
else
PORTD= PORTD | (1<<LCD_DATA); // data high , if set

PORTD= PORTD & ~(1<<LCD_WR); // wr low, active low
_delay_us(100);

}
PORTD= PORTD | (1<<LCD_WR); // wr high
_delay_us(100);


}
 

Two things immediately stand out.

1. The HT1621 clocks data in on the rising edge of WR, not the falling edge.

2. The 8-bit variable section of the 12-bit command word isn't right-aligned within the word, it's shifted to the left by one bit with the LSB set to a don't care. However, it appears that your write_lcd_cmd function places the don't care before the 8-bit variable, shifting all of that one place to the right. So when you think you're sending the LCD ON command word 100 00000011 X, you're actually sending 100 X 00000011, which isn't a valid command...
 

hi thanks for your help...............

but i am still not getting anything on my lcd.
According to you i changed my commands of WR high into WR low and vice versa.
and provide lcd on command as 0x30........i think this is wat u was saying...
but still my problem is same...

if there is any problem in my code can anyone provide me the right one.....
i will be very thankful..

waiting for reply
 

ansh2d87 said:
and provide lcd on command as 0x30........i think this is wat u was saying...

Not exactly, no... What I meant was that, after you send the initial 1 0 0 command header bits and then the byte corresponding to the actual command you want the driver to perform, you THEN have to send a final don't care bit. If you look at the bottom of page 8 in the driver datasheet you'll see a table listing the commands, and if you look at the second row in that table, you'll see:

HT1621 datasheet said:
LCD ON 1 0 0 0 0 0 0 0 0 1 1 X Turn on LCD outputs

Note the X (don't care) at the end of the bit pattern, and note how the 0x03 command byte you're trying to send sits between the leading 1 0 0 bits and the trailing X bit.

So what you need to do is send the 1 0 0 command header, THEN send the 0x03 command byte, and THEN send a single bit. It doesn't matter whether this bit is a 0 or a 1, so after you finish sending the command byte you can simply perform one extra cycle on the WR line without needing to set or clear the DATA line first.
 

hey thanks dear.....

but i am still not getting anything....
i think there is some problem with my write_cmd() and write_data() routines....

can u do me a favour...... can you tell me the routines for sending command and data to ht1621B lcd driver......

thanks
 

Post your latest code so we can check that for any problems - use the code tags to avoid the formatting being messed up.

One other thing to check is that you've set the voltage on the VLCD pin correctly - if that's too low then the display will appear blank no matter what the driver is doing...
 

hey thanks for your support but i got the solution.....
actually there was an hardware problem...... my data pin was not soldered correctly with the pad that's why it is not taking any data.....now my lcd is on....

i am very grateful to you for helping me so much.....

nw i am looking further to generate specified code on lcd....i will come back to you if i encountered any problem....i hope this community will help me.....

thanks again....
 

ansh2d87 said:
hey thanks for your support but i got the solution.....
actually there was an hardware problem...... my data pin was not soldered correctly with the pad that's why it is not taking any data.....now my lcd is on....

That's good news, and thanks for taking the time to let us know things have worked out OK!
 

can anyone tell me the way how to write sumthing on lcd......for example if i want to write 1111 on my 6x1 lcd..... how should i program my my ram segments and addresses????????
 

That depends on what the LCD duty cycle is (static drive, 1/2, 1/3, 1/4 etc), and in what order you've connected the COM and SEG lines from the LCD to the driver. Without knowing how the LCD is internally wired up, and how it's connected to the driver, it's impossible to say what you'd need to write into the driver memory.
 

ok i am sorry for asking a silly question like this...........

i am using 18 pin 6x1 lcd and i am using only 8-20 segments of ht1621. its duty cycle is 1/4......
mapping is like this---

SEGMENT/ LCD PIN
8 / 3
9 / 4
10 / 5
11 / 6
12 / 7
13 / 8
14 / 9
15 / 10
16 / 11
17 / 12
18 / 13
19 / 14
20 / 17

com1----pin15 of lcd
com2----pin2
com3----pin16
com4---pin1

pin18 is vcc......

now can u tell me how could i address all my segments... and how to write alphabets on lcd....

i am attaching details of my lcd here.....please have a look at it ...... it will help u


thanks in advance

you are really very helping...
 

ansh2d87 said:
SEGMENT/ LCD PIN
8 / 3
9 / 4
10 / 5
11 / 6
12 / 7
13 / 8
14 / 9
15 / 10
16 / 11
17 / 12
18 / 13
19 / 14
20 / 17

That seems OK...

com1----pin15 of lcd
com2----pin2
com3----pin16
com4---pin1

...as does this. However...

pin18 is vcc......
No, no, and once again NO! Pin 18 is another segment line controlling the battery icon in the lower-right corner of the display. You should NEVER apply DC power directly to a bare LCD like this, so before you go any further you need to power down your board, break the connection between this pin and Vcc, and then connect it to one of the spare segment drive pins on the HT1621.


OK, once you've fixed that, you now just need to define the bit patterns associated with each number you want to display, bearing in mind that, for a 1/4 duty display, each data address in the driver memory corresponds to 4 segments.

e.g. For the first digit on the LCD, the corresponding locations in the driver memory are addresses 8 and 9, with segments 1F, 1G, 1E and 1D mapped into the 4 bits stored at address 8, and segments 1A, 1B and 1C mapped into the lowest 3 bits at address 9. The same basic mapping is also true for the other digits, with just the addresses changing - digit 2 maps onto addresses 10 and 11, digit 3 maps onto 12 and 13, etc.

In other words, for digit n the two corresponding addresses in the driver are 6+(n*2) and 7+(n*2), which I'll now refer to as the low and high addresses.


Now, to display a 0, you need to turn on segments A, B, C, D, E and F, and turn off segment G. To display a 1 you need to turn on segments B and C, with all others turned off, and so on.

These bit patterns can be defined in a single byte, with the lowest 4 bits corresponding to the low address bits, and the highest 4 bits corresponding to the high address bits. Thus:

Bitpattern for 0 = 0x7D
Bitpattern for 1 = 0x60 etc.

Now, to display a number at a specific digit location, you just need to write the appropriate 4 bits from the bitpattern to the corresponding low and high addresses. In pseudo-code, remembering that data is written to the driver least-significant-bit first, this might look something like this...

Code:
const char bitpatterns[] = {0x7D, 0x60...}

char bitpattern = bitpatterns[number_to_display];

write_lcd_address(6 + (digit * 2));
for(writes = 0; writes < 2; writes++)
{
   for(bits = 0; bits < 4; bits++)
   {
      write_lcd_bit(bitpattern & 0x01);
      bitpattern = bitpattern / 2;
   }
}

This is all you need if you just want to display digits and you're not bothered about using any of the extra icons (P1-P6, BAT).


Of course, you first need to configure the driver for 1/4 duty 1/3 bias operation...
 

hi...... friend...

are you sure that the bit pattern is like dat only....because i am not getting a 0 by using 7D...

i think this is what you was telling...
p1 c b a d e g f
0 1 1 1 1 1 0 1 =0x7D=0
 

Yes, that's where the 0x7D comes from. If you're not getting anything when you write that data to the driver, check that you've configured the driver properly, and set the correct address first. If however you are seeing something, then please list the segments which are turned on.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top