|
|
View previous topic :: View next topic |
Author |
Message |
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
Porting 20x4 LCD Code To HT1621 OEM LCD |
Posted: Sat Sep 05, 2020 5:16 pm |
|
|
I greet all! Please I have looked for an appropriate area of this forum where I can ask this type of question but I could not locate it. Please forgive me if this is not the place for asking this. If there is such a place please do direct me there.
I have a code that I write in CCS C V5076. It is a working code that displays the result of ACIN, ACOUT, Battery, Current on 20x4 LCD. I have a HT1621 LCD I want to display on.
I am ready to submit this to Freelancer or the likes, but I decided to first of all ask If there is a way I can get someone do it here for me here which I can pay for?
Please I have 16F886 Simulation Board which currently runs my code. If other things like schematic etc, are needed I can supply them here.
Code: | #include <16F886.h>
#device ADC = 10
#fuses INTRC_IO,NOWDT,MCLR,NOPROTECT
#use delay(clock = 8000000)
//#use rs232(baud = 9600,xmit=PIN_C6,DISABLE_INTS,ERRORS)
#include <Flex_LCD420.c>
#define HAPPY PIN_C0
#define ANGRY PIN_C1
#define VDD 5.0
#define R 0.5
long ACIN,ACOUT; // AC Mains IN and OUT
long BVS; // Battery Voltage Sensor
long BCS; // Battery Current Sensor
long MS; // Mains Sensor
long MS2; // Mains Sensor2
float BATT,CURRENT;
void init()
{
setup_adc(ADC_CLOCK_DIV_8);
setup_adc_ports( sAN0 | sAN1 |sAN2 | sAN3 | VSS_VDD); // Select Analog Inputs
setup_comparator(NC_NC_NC_NC);
delay_ms(10);
}
void main()
{
init(); // Configure peripherals/hardware
lcd_init(); // Initialize LCD module
printf(lcd_putc,"\f"); // clear the LCD
delay_ms(250);
while(TRUE)
{
set_adc_channel(0); //Select AN0 as ADC Input for BCS
delay_ms(1); //Wait 1 ms
BCS = read_adc(); //Read AN0 and store in BCS
delay_ms(1); //Wait 1 ms
set_adc_channel(1); //Select AN1 as ADC Input for MS
delay_ms(1); //Wait 1 ms
MS = read_adc(); //Read AN1 and store in MS
delay_ms(1); //Wait 1 ms
set_adc_channel(2); //Select AN2 as ADC Input for BVS
delay_ms(1); //Wait 1 ms
BVS = read_adc(); //Read AN2 and store in BVS
delay_ms(1); //Wait 1 ms
set_adc_channel(3); //Select AN3 as ADC Input for MS2
delay_ms(1); //Wait 1 ms
MS2 = read_adc(); //Read AN3 and store in MS2
delay_ms(1); //Wait 1 ms
ACIN=(MS*0.5634408602150538);//576.4/1023
ACOUT=(MS2*0.5634408602150538);//576.4/1023
BATT = (BVS * 0.0689892051030422);//70.3V/1023
CURRENT=(BCS*VDD/1023)/0.5;
if(BATT <=21 || BATT >=33 || CURRENT >=7)
{
output_high(ANGRY); // Emoticon ANGRY Mood on TR2020A LCD
output_low(HAPPY); // Emoticon HAPPY Mood on TR2020A LCD
}
else
{
output_low(ANGRY); // Emoticon ANGRY Mood on TR2020A LCD
output_high(HAPPY); // Emoticon HAPPY Mood on TR2020A LCD
}
{
{
lcd_gotoxy(1,1);
lcd_putc("AC INPUT = ");
lcd_gotoxy(16,1);
printf(lcd_putc,"%Lu V ",ACIN);
}
{
lcd_gotoxy(1,2);
lcd_putc("AC OUTPUT = ");
lcd_gotoxy(16,2);
printf(lcd_putc,"%Lu V ",ACOUT);
}
{
lcd_gotoxy(1,3);
lcd_putc("Batt Voltage = ");
lcd_gotoxy(16,3);
printf(lcd_putc,"%3.1g ",BATT);
lcd_gotoxy(20,3);
lcd_putc("V");
}
{
lcd_gotoxy(1,4);
lcd_putc("Batt Current = ");
lcd_gotoxy(16,4);
printf(lcd_putc,"%3.1g ",CURRENT);
lcd_gotoxy(20,4);
lcd_putc("A");
}
delay_ms(1000);
}
}
} |
2002 LCD display
https://drive.google.com/file/d/1dxXoW4vcy4AZJ7FTSN-T3HCanSmdhzJX/view?usp=sharing
HT1621(TR2020a) LCD
https://drive.google.com/file/d/1tkCNJOakFje_dF9Lcee-ldsyhjZPk7uY/view?usp=sharing
HT1621(TR2020A) Connection
https://drive.google.com/file/d/1NoTJA4KIjsZ3aVSwyikH7cYlyHxOJBse/view?usp=sharing
HT1621 (TR2020A)
https://drive.google.com/file/d/19RBgpen9VgRM-B-H4CvIMp3lF29hLM8N/view?usp=sharing
16F886 Simulation Board
https://drive.google.com/file/d/1jDqxgMpuQE5PD6MsDhIVzPprN2HfhJMa/view?usp=sharing
Thanks. Hoping for your sincere co-operation. _________________ All is well even in the well! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Sep 05, 2020 10:49 pm |
|
|
If I type HT1621 into image search on the net, all I see are segmented
displays by Holtek. But you clearly show a graphic display in your links.
Who is the manufacturer of your display ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Sun Sep 06, 2020 12:20 am |
|
|
I think there is a significant 'misunderstanding' going on from the original
poster.
The problem is that this controller is described as a 32x4 controller, and
he therefore thinks that this supports multiple lines of text. It doesn't.
The '32' here is the number of segment drive outputs available. The '4' is
the number of common lines. So the controller is capable of driving a
maximum of 128 LCD segments. The commonest wiring is as a 6 digit
text LCD, with a couple of extra symbols implemented.
The interface can be driven using the CCS 'software' SPI, setting up two
streams, one using the WR pin as it's clock and the data pin for the output
data, the other using the RD pin for it's clock and the same data pin as
an input. You have to manually override the TRIS when switching from
read to write (and vice versa). One other CS line is needed.
You have to drive the display just like you would a 7 segment LED, with
your code knowing which segments to turn on for the values you want to
display. The data memory is organised as 32*4, and the read and write
instructions access this 'nibble by nibble'. So you send a write command
followed by the 6bit 'nibble address', then the 4 bits to write to this nibble.
To read you do the same, send a read command, then 6 bit nibble address,
then switch to the read stream (and turn off the TRIS), and clock back the
4 bit nibble.
Yes, this can be driven by the PIC, but not by the 20x4 LCD code. There
is zero compatibility between this display and this code. |
|
|
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
|
Posted: Sun Sep 06, 2020 12:27 am |
|
|
Please I want to make it clear that the code I posted is only for 2004 LCD display which I referred to as "a working code'. It the another code that can drive the TR2020A LCD module that I need.
Shenzhen Tianruixan Electronics China.
I have their own datasheet for the LCD Module. In fact I will now share all the files I have for it now
This link is a rar file that contains both the datasheet, schematic etc
https://drive.google.com/file/d/18MiuaMUSvlLDDAQgdtp63GjX5aRqZXdf/view?usp=drivesdk
Thanks. _________________ All is well even in the well! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Sun Sep 06, 2020 1:55 am |
|
|
You lack an absolutely _critical_ piece of data. Which segment of the
display connects to which segment output on the controller. Without this
you would have to experiment and drive each output in turn and make up
your own map to how the display actually works.
There will be a total of 56 segments connected to the 7 segment digits,
then probably two more for the leading '1', then ones for the 'V' and %
signs, then probably a single one for the frame round 'LOAD', five more
for the bars in this, then one for the battery frame, and three more for the
bars in this. The face will probably have one for the face itself, and two
separate ones for the lips. Single ones for the Input and output tabs,
but again there may be separate ones for the symbols inside.
Problem is though that you can't just go and test what segment does
what, without also knowing what bias and duty the LCD requires.
Also what clock rate.
You also give a circuit for the 4*20 display, but not the 4020.
Who is actually selling the module you have?. They must have data
showing what segment drives which part of the display, and probably
the specifications of the LCD. |
|
|
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9225 Location: Greensville,Ontario
|
|
Posted: Sun Sep 06, 2020 7:26 am |
|
|
Possible solution...
Find a 'driver' for the HT1621 (hint Ardunio HT1631).
Although this is for a 7 segment,4 digit display it will show how to interface the PIC to the HT1621. You'll have to create your own 'database' array of which bits of what elements of this array to control the actual LCD 'icons'.
You need to translate the Ardunio C into CCS C, then create the array of LCD icon 'database'. essentially this is a translation table.
The good news is you KNOW which bits control which icons. This will take some time, so a pencil and paper will really help !!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Sun Sep 06, 2020 7:56 am |
|
|
Driving the controller is quite easy. I'll post a bit of some code I used
latter.
However the sheet you have does not show how the sements are connected.
It shows segment 'numbers' for the extra stuff, but not which segments
on the controller these connect to, or the segment numbers for the digits.
So, looks as if you are going to have to work these out for yourself.
However we still have the problem of no data on the drive requirements
for the LCD (1/3 or 1/4 drive in particular). |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Sun Sep 06, 2020 8:11 am |
|
|
OK. This is part of a driver I did a while ago to drive this controller. I've
modified for your chip, and added pin definitions, which you will have to
change as you wire the display.
Code: |
//pin numbers
#define LCDCS PIN_B2 //CS pin
#define LCDDAT PIN_B3 //data pin
#define LCDRD PIN_B4 //read clock
#define LCDWR PIN_B5 //write clock
#use SPI(CLK=LCDWR, DO=LCDDAT, baud=150000, mode=0, stream=LCDTX)
#use SPI(CLK=LCDRD, DI=LCDDAT, baud=150000, mode=0, stream=LCDRX) //streams for the LCD
//first command ID's
#define READ_DATA 6
#define WRITE_DATA 5
#define RMW_DATA 5
#define SYS 4
//then codes for SYS commands
#define DISABLE 0
#define ENABLE 1
#define LCD_OFF 2
#define LCD_ON 3
#define TIMER_DIS 4
#define WDT_DIS 5
#define TIMER_EN 6
#define WDT_EN 7
#define TONE_OFF 8
#define TONE_ON 9
#define CLR_TIMER 0xC
#define CLR_WDT 0xE
#define XTAL32K 0x14
#define RC256K 0x18
#define EXT256K 0x1C
//six different bias options 1/2 or 1/3, then 2 to 4 commons
#define BIAS122 0x20
#define BIAS123 0x24
#define BIAS124 0x28
#define BIAS132 0x21
#define BIAS133 0x25
#define BIAS134 0x29
//tone control
#define TONE4K 0x40
#define TONE2K 0x60
//IRQ
#define IRQ_DIS 0x80
#define IRQ_EN 0x88
//WDT frequencies
#define F1 0xA0
#define F2 0xA1
#define F4 0xA2
#define F8 0xA3
#define F16 0xA4
#define F32 0xA5
#define F64 0xA6
#define F128 0xA7
//others
#define TEST 0xE0 //do not use
#define NORMAL 0xE3
void command(int8 value)
{
int16 temp;
temp=(int16)value<<1;
//send a command byte to the controller
output_drive(LCDDAT); //ensure TRIS==1
output_low(LCDCS); //select display
spi_xfer(LCDTX, SYS, 3); //start the command
spi_xfer(LCDTX, value, 9); //send 9 bit command
output_high(LCDCS); //finish writing
}
int8 read_nibble(int8 address)
{
int8 read_val;
//read nibble from RAM at address
output_drive(LCDDAT); //ensure TRIS==1
output_low(LCDCS); //select display
spi_xfer(LCDTX, READ_DATA, 3); //start the command
spi_xfer(LCDTX, address, 6); //send 6 bit address
//now must release the data line drive
output_float(LCDDAT);
//and clock back the data value
read_val=spi_xfer(LCDRX,0,4); //4 bits
output_high(LCDCS);
}
void write_nibble(int8 address, int8 value)
{
//write a nibble to the display RAM
output_drive(LCDDAT); //ensure TRIS==1
output_low(LCDCS); //select display
spi_xfer(LCDTX, WRITE_DATA, 3); //start the command
spi_xfer(LCDTX, address, 6); //send 6 bit address
//now clock out the value
spi_xfer(LCDTX,value,4); //4 bits
output_high(LCDCS);
}
void init(void)
{
//you need to configure the LCD before starting. Settings here depend on the display
command(RC256K); //enabling the 256K internal oscillator - may not be right if crystal fitted.
command(BIAS124); //You need to select the BIAS correctly for the display and
//how many common lines are used. Assuming 4.
command(NORMAL); //ensure set to normal operation
command(ENABLE); //andf enable controller
}
void set_segment(int8 segno, int1 val)
{
//set a single segment on the display. Reads the nibble at this point,
//and sets the segment, then writes it back. Val determines whether 1 or 0
int8 temp_nib;
int8 address;
address=segno/16; //RAM address
//read nibble from RAM at address
output_drive(LCDDAT); //ensure TRIS==1
output_low(LCDCS); //select display
spi_xfer(LCDTX, RMW_DATA, 3); //start the command
spi_xfer(LCDTX, address, 6); //send 6 bit address
//now must release the data line drive
output_float(LCDDAT);
//and clock out the data value
temp_nib=spi_xfer(LCDRX,0,4); //4 bits
//Now need to set the bit
if (val)
bit_set(temp_nib,segno%16); //set the required bit
else
bit_clear(temp_nib,segno%16); //or turn off
output_drive(LCDDAT); //drive data line
spi_xfer(LCDTX,temp_nib,4); //and write the value back with the bit changed
output_high(LCDCS);
}
void main()
{
int8 int_ctr;
delay_ms(250); //ensure display has time to start
init();
while(TRUE)
{
//Now demo of setting and turning off each segment in turn. You will need
//to generate look up arrays for the segment numbers needed for the digits
//and a standard '7 segment' type driver to set the right segments
for (int_ctr=0;int_ctr<128;int_ctr++)
{
set_segment(int_ctr,1); //turn segment on
delay_ms(1000); //wait one second
set_segment(int_ctr,0); //turn segment off
//and advance to next segment
}
}
}
|
|
|
|
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
|
Posted: Sun Sep 06, 2020 8:22 am |
|
|
Ttelmah wrote: | OK. This is part of a driver I did a while ago to drive this controller. I've
modified for your chip, and added pin definitions, which you will have to
change as you wire the display. |
Thanks Ttelmah, I will what I can do with this when I am at home. _________________ All is well even in the well! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19506
|
|
Posted: Sun Sep 06, 2020 11:09 am |
|
|
Ideally, you want to do something like enable the serial as well, and have
a program that then steps through the segments and allows you to record
which segment actually does what. Hopefully the 1/2 bias is right otherwise
you need to try the 1/3 setting BIAS134. It's going to need all 4 commons,
given the sheer number of segments actually involved. |
|
|
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
|
Posted: Mon Sep 07, 2020 5:36 pm |
|
|
Nothing worked for me.
Thanks. _________________ All is well even in the well! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 07, 2020 6:36 pm |
|
|
Did you change these pin numbers ?
Ttelmah wrote: | //pin numbers
#define LCDCS PIN_B2 //CS pin
#define LCDDAT PIN_B3 //data pin
#define LCDRD PIN_B4 //read clock
#define LCDWR PIN_B5 //write clock |
The pin numbers need to be as shown below. These match your schematic:
Code: |
#define LCDCS PIN_C3
#define LCDWR PIN_C4
#define LCDDAT PIN_C5
// #define LCDRD // Not used on schematic
|
|
|
|
mcmsat
Joined: 25 May 2018 Posts: 51 Location: Nigeria
|
|
Posted: Mon Sep 07, 2020 6:46 pm |
|
|
PCM programmer wrote: | Did you change these pin numbers ?
Ttelmah wrote: | //pin numbers
#define LCDCS PIN_B2 //CS pin
#define LCDDAT PIN_B3 //data pin
#define LCDRD PIN_B4 //read clock
#define LCDWR PIN_B5 //write clock |
The pin numbers need to be as shown below. These match your schematic:
Code: |
#define LCDCS PIN_C3
#define LCDWR PIN_C4
#define LCDDAT PIN_C5
// #define LCDRD // Not used on schematic
|
|
I did change the pins _________________ All is well even in the well! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Sep 07, 2020 7:21 pm |
|
|
Your schematic doesn't have LCDRD connected to the PIC. It's not even
on your connector. Your connector is only 5 pins.
But Ttelmah's code depends upon reading data from the lcd and
modifying a bit, and then writing it back. He reads 4 bits into the
variable 'temp_nib'. Then he sets or clears a bit in it. Then he
writes it back to the lcd. Your schematic doesn't permit this.
Ttelmah wrote: |
temp_nib=spi_xfer(LCDRX,0,4); //4 bits
//Now need to set the bit
if (val)
bit_set(temp_nib,segno%16); //set the required bit
else
bit_clear(temp_nib,segno%16); //or turn off
output_drive(LCDDAT); //drive data line
spi_xfer(LCDTX,temp_nib,4); //and write the value back with the bit changed
|
|
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|