CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Porting 20x4 LCD Code To HT1621 OEM LCD
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
mcmsat



Joined: 25 May 2018
Posts: 51
Location: Nigeria

View user's profile Send private message

Porting 20x4 LCD Code To HT1621 OEM LCD
PostPosted: Sat Sep 05, 2020 5:16 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Sat Sep 05, 2020 10:49 pm     Reply with quote

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: 19518

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 12:20 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 12:27 am     Reply with quote

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: 19518

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 1:55 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 5:29 am     Reply with quote

The datasheet i included as a .rar file in my previous attachments is supplied by the manufacturer.

IMPORTANT!
The code I supplied in this post is only for 20 Rows 4 Vertical (20x4) LCD. I have not written a code for the TR2020. The new code I am expecting is this code with TR2020 replacing the 20x4 LCD. I don't know if I am understood now?

Now I have cut some important pictures from the datasheet and also the full datasheet in PDF and attached them.

Thanks.

What i think is the Mapping of the segments.
https://drive.google.com/file/d/1Wuk_rslZBdYCPpYKz1AcMWpYzTlwAJAp/view?usp=sharing

The full datasheet from the manufacturer
https://drive.google.com/file/d/1QpUNKJ9yMsNGHEwoJF9nMwHMZDq1OPiH/view?usp=sharing
_________________
All is well even in the well!
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 7:26 am     Reply with quote

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: 19518

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 7:56 am     Reply with quote

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: 19518

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 8:11 am     Reply with quote

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

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 8:22 am     Reply with quote

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: 19518

View user's profile Send private message

PostPosted: Sun Sep 06, 2020 11:09 am     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 07, 2020 5:36 pm     Reply with quote

Nothing worked for me.

Thanks.
_________________
All is well even in the well!
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Sep 07, 2020 6:36 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 07, 2020 6:46 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Mon Sep 07, 2020 7:21 pm     Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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