|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19326
|
|
Posted: Mon Sep 07, 2020 11:11 pm |
|
|
Yes.
There are two choices:
Either you implement reading the data, or
you could hold your data locally. For this you would need 16 bytes of
RAM.
You would need to clear this at the start, and write the whole 16 bytes
to the chip at startup.
Then the bit set and clear routines, would have to modify the local
nibble, and write this to the chip. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19326
|
|
Posted: Tue Sep 08, 2020 6:50 am |
|
|
OK,
I've rewritten the code to use a 16byte RAM buffer instead of reading the
chip. No idea if this will work....
Code: |
//pin numbers
#define LCDCS PIN_C3 //CS pin
#define LCDWR PIN_C4 //data pin
#define LCDDAT PIN_C5 //write clock
//rewriting to not use RD instead maintain a copy of the display RAM in the PIC
#use SPI(CLK=LCDWR, DO=LCDDAT, baud=150000, mode=0, stream=LCDTX) //stream 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
byte seg_array[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //array of bytes for the segments
//must be zeroed.
void command(int8 value)
{
int16 temp;
temp=(int16)value<<1;
//send a command byte to the controller
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
}
void write_nibble(int8 address, int8 value)
{
//write a nibble to the display RAM
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 clear_display(void)
{
int8 tempctr;
//This uses a repeated write to clear the entire display RAMM
output_low(LCDCS); //select display
spi_xfer(LCDTX, WRITE_DATA, 3); //start the command
spi_xfer(LCDTX, 0, 6); //send 6 bit address - 0 == start of RAM
//now clock out the value - 32 nibbles == 16 bytes
for (tempctr=0;tempctr<16;tempctr++)
spi_xfer(LCDTX,0,8); //2*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
}
//OK, without read, I work instead from a RAM array for the segments.
void set_segment(int8 segno, int1 val)
{
//set a single segment on the display.
//This version uses a dummy copy of the display data stored in seg_array
//So accesses the required nibble and bit in this,
//then changes the segment, then writes it to the display. Val determines whether 1 or 0
int8 temp_nib;
int8 address;
int8 index; //index in RAM array
int8 bitno;
int1 highlow; //bit for whether high or low nibble
//now need to calculate the index into the RAM array
index=segno/8; //byte address
if (bit_test(segno,2))
highlow=TRUE;
else
highlow=FALSE; //now flag for which nibble
bitno=segno & 3; //now which bit in the nibble
temp_nib=seg_array[index]; //fetch the byte
if (highlow)
swap(temp_nib); //If we need the high nibble, swap
//Now need to set or clear the bit
if (val)
bit_set(temp_nib, bitno);
else
bit_clear(temp_nib, bitno);
address=segno/4; //RAM address in display chip
//Now write to display
write_nibble( address,temp_nib);
//Now update the RAM array with this change
if (highlow)
swap(temp_nib); //swap back if needed
//and update RAM array
seg_array[index]=temp_nib; //write back modified value
}
void main()
{
int8 int_ctr;
delay_ms(250); //ensure display has time to start
init();
clear_display(); //and clear display RAM
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
}
}
}
|
|
|
|
|
|
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
|