|
|
View previous topic :: View next topic |
Author |
Message |
djsb
Joined: 29 Jan 2011 Posts: 41
|
How to store 4100 off 32 bit binary numbers in an 8 bit MCU? |
Posted: Mon Sep 11, 2023 2:28 pm |
|
|
Hi,
I need to store, 4100 off 32 bit numbers (2050 high bytes and 2050 low bytes-Both 32 bit bytes) in an 8 bit PIC. These 32-bit numbers need to be output serially to an LCD. The 32-bit numbers represent the numbers 87.50 to 108.00 on a 5 digit LCD. Only one digit changes as the numbers increment or decrement. Could this be used to somehow make the storage more efficient. Or could this code be stored externally in EEPROM somehow?
Ttelmah may remember contributing some code in this post
https://www.ccsinfo.com/forum/viewtopic.php?t=59831&start=0&postdays=0&postorder=asc&highlight=
I'm working on creating the 32 bit words, but at the moment I will need to send each word individually until I work out how to send the words one after another. I want to send 87.50 then 87.51 then 87.52 and so on up to 108.00.
It's mainly how to store these individual 32 bit words in some kind of union (which I've NEVER used) or array or table that worries me. I'm guessing that the OEM microcontroller (which only has about 8kb of mask programmed memory) used assembly language (which I will never be able to find out-and I dont want to). Any clues or insight would be helpful. Thanks. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Mon Sep 11, 2023 6:38 pm |
|
|
Back up. Tell us about the problem. What do you want to do?
There's probably a much better way of doing this that doesn't involve a LUT. |
|
|
djsb
Joined: 29 Jan 2011 Posts: 41
|
|
Posted: Mon Sep 11, 2023 11:42 pm |
|
|
Here is the latest code I've been using
Code: |
/*
FILENAME:REVOX_B261_PCE2111_LCD_TEST1.C
REVISION:0.1
Date:05 August 2022
Author: Original Ttelmah CCS INFO FORUM 04th August 2022 with contributions by David J S Briscoe
Purpose: This program is to test the Mullard/Philips PCE2111 Duplex 64 segment LCD driver on a Revox B261 FM tuner.
Status: 10th August:All segments are lit (apart from STORE and ANT-Check LCD connections.
Pin diagram
; Target Controller - PIC16F1847
;
; RS232-WHITE------RA2 |1 18| RA1-----------
; -----------------RA3 |2 17| RA0-----------
; -----------------RA4 |3 16| RA7-----------
; -----------------RA5 |4 15| RA6-----------
; GND--------------VSS |5 14| VDD-----------+5V
; PCE2111 DLEN-----RB0 |6 13| RB7-----------
; PCE2111 DATA-----RB1 |7 12| RB6-----------
; PCE2111 CLB------RB2 |8 11| RB5-----------
; -----------------RB3 |9 10| RB4-----------
;
;
NOTES:
*/
#include <16F1847.H>
#fuses INTRC_IO, NOWDT, NOBROWNOUT, PUT,NOPROTECT,MCLR,NOLVP
#use delay(clock=8000000)
#use RS232(baud=9600, xmit=PIN_A2,ERRORS) //RS232 on Pin A2
// Define pins for CBUS
#define DLEN PIN_B0
#define DATA PIN_B1
#define CLB PIN_B2 //set to suit you
//int32 low32 = 0xFFFFFFFF; //ALL segments ON (apart from MUTING and ANT-They are on an independent backplane). ON SPREADSHEET.
//int32 high32 = 0xFFFFFFFF; //Use this to check connections to LCD. START WITH THIS SETTING
//int32 low32 = 0x00000000; //ALL segments OFF. Use this setting to work out segments to turn ON. One by one. ON SPREADSHEET.
//int32 high32 = 0x00000000; //.
//int32 low32 = 0xFFDFFFFF; //STEREO (SEG 22)OFF (all others ON).
//int32 high32 = 0xFFDFFFFF; //
//int32 low32 = 0xFFFFFF7F; //25 OFF (SEG 8) ALL others ON.
//int32 high32 = 0xFFFFFFFF; //.
//int32 low32 = 0xFFFFFF7F; //25 OFF. POINT AND MHZ OFF
//int32 high32 = 0xFFFFFF7F; //
//int32 low32 = 0xFFFFFFFF; //75 OFF.25 AND 50 ON. 50 AND 75 SEG 32.
//int32 high32 = 0x7FFFFFFF; //
//int32 low32 = 0x7FFFFFFF; //50 OFF REST ON
//int32 high32 = 0xFFFFFFFF; //
//int32 low32 = 0xFFFFFFFF; //FIRST DIGIT OFF. Rest ON. ON SPREADSHEET.
//int32 high32 = 0xFFDFFFFF; //
//int32 low32 = 0x00000000; //FIRST DIGIT ON. Rest OFF.ON SPREADSHEET.
//int32 high32 = 0x00200000; //
//int32 low32 = 0x00000000; //POINT AND MHZ ON (S8). Rest OFF.
//int32 high32 = 0x00000080; //
//int32 low32 = 0x00000080; //POINT,MHZ AND 25 ON. Rest OFF.
//int32 high32 = 0x00000080; //
//int32 low32 = 0x48010000; //SEGMENTS 5A,5B,5C,5D,5E,5F,5G and 5L segments ON, Rest OFF. Shows number ZERO on DIGIT 5.
//int32 high32 = 0x6C000001; // 4 BIT NIBBLE 1 (FROM LEFT) S30,31 NIBBLE 2 S27,28 NIBBLE 8 S1 LOW32 NIBBLE 1 S31 (5G), S28 (5L) NIBBLE 4 S17 (5A)
//int32 low32 = 0x00020012; //SEGMENTS 4A,4B,4C,4D,4E,4F,4G and 4L segments ON,rest OFF. Shows ZERO on DIGIT 4,
//int32 high32 = 0x00000076; //
//int32 low32 = 0x00080900; //SEGMENTS 3A,3B,3C,3D,3E,3F,3G and 3L ON, Rest OFF. Shows number ZERO on DIGIT 3.
//int32 high32 = 0x00003B00; //
//int32 low32 = 0x01104000; //SEGMENTS 2A,2B,2C,2D,2E,2F,2G and 2L ON, Rest OFF. Shows number ZERO on DIGIT 2.ON SPREADSHEET.
//int32 high32 = 0x01C0C000; //.
//int32 low32 = 0xC89B8024; //Segments 2A,2B,2C,2D,2E,2F,2M,2H (DIGIT 2 NUMBER 8).0xC89B=0b1100100010011011 0x8024=0b1000000000100100 = 0b11001000100110111000000000100100
//int32 high32 = 0x6DC0C3D5; //Shows 87.50 MHZ with decimal point and 50 indicator. ? THIS CONTRADICTS ITSELF. DOES IT SHOW DIGIT 2 NUMBER 8 OR 87.50 MHZ?
//DIGIT 1 ALL POSSIBLE NUMBERS.PUT ON SPREADSHEET WHEN DONE. TRY ON ACTUAL DISPLAY TO CONFIRM.
//int32 low32 = 0xFFFFFFFF; //FIRST DIGIT OFF. Rest ON.
//int32 high32 = 0xFFDFFFFF; //
//int32 low32 = 0x00000000; //FIRST DIGIT ON. Rest OFF.
//int32 high32 = 0x00200000; //
//DIGIT 2 ALL POSSIBLE NUMBERS ARE 8,9 AND 0. PUT ON SPREADSHEET WHEN DONE.TRY ON ACTUAL DISPLAY TO CONFIRM.
//int32 low32 = 0x01104000; //SEGMENTS 2A,2B,2C,2D,2E,2F,2G and 2L ON, Rest OFF. Shows number ZERO on DIGIT 2.
//int32 high32 = 0x01C0C000; //.
//int32 low32 = 0xC89B8024; //Segments 2A,2B,2C,2D,2E,2F,2M,2H (DIGIT 2 NUMBER 8).
//int32 high32 = 0x6DC0C3D5; //Shows 87.50 MHZ with decimal point and 50 indicator. JUST MAKE IT SHOW DIGIT 2 NUMBER 8 FOR NOW.
// int32 low32 =0x00908000;// Shows number 9 on digit 2. Segments 2A,2B,2C,2D,2F,(2M and 2H middle 2 segments-PLEASE CONFIRM). ON SPREADSHEET
// int32 high32 =0x0140C000; // Values taken off For David CalcHiLo.txt by Robert wishlaw. Works OK.
// int32 low32 = 0x00908000;// Shows number 8 on digit 2. 2A,2B,2C,2D,2E,2F,(2M and 2H middle 2 segments-PLEASE CONFIRM).NOT ON SPREADSHEET.
// int32 high32 = 0x01C0C000; // Values taken off For David CalcHiLo.txt by Robert wishlaw. Works OK.
int32 low32 = 0x489b80A0; //Shows 87.5MHz with 25,point and MHz on.
int32 high32 = 0x6DC0C3D9; //SEG32 LOW IS 50, HIGH IS 75. Try to swap 25 for 50 and 75 next.
// CCS FORUM POST https://www.ccsinfo.com/forum/viewtopic.php?t=33377&start=11
// Modify diagram below as required.
// Change bit pattern and Hex codes to suit this application.
//
// Digit numbers:
// 8 7 6 5 4 3 2 -
// ----- ----- ----- ----- ----- ----- ----- -----
// |\|/| |\|/| |\|/| |\|/| |\|/| |\|/| |\|/| |\|/|
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
// |/|\| |/|\| |/|\| |/|\| |/|\| |/|\| |/|\| |/|\|
// ----- ----- ----- ----- ----- ----- ----- -----
//
// Change these as needed.
//
// Segment Segment bit
// letters: numbers:
//
// a 15
// ------- -------
// |\ i| /| |\ 7| /|
// f| \ | / |b 10| \ | / |14
// | h\|/j | | 8\|/6 |
// g--- ---k 9--- ---5
// | l/|\n | | 4/|\2 |
// e| / | \ |c 11| / | \ |13
// |/ m| \| |/ 3| \|
// ------- -------
// d 12
//
// Segment bit numbers: Segment
// 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 hex code:
// 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 2 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 4 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 6 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 7 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 8 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
// 9 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 0x00000000
//
// E.G 0 1 1 1 1 1 1 - - - 1 - 1 - - - -
void init(void)
{
//call at start to ensure lines are low
output_low(DLEN);
output_low(CLB);
}
#inline
void clock()
{
//generate one bit clock
delay_us(8);
output_high(CLB);
delay_us(2);
output_low(CLB);
delay_us(8);
}
void send(int32 value, int1 lowhigh)
{
int ctr;
int32 mask=1; //data is output LSb first
output_high(DLEN);
delay_us(8);
//output 32bit value to either low or high register
output_low(DATA);
clock(); //first send a 0
for (ctr=0;ctr<32;ctr++)
{
if (value & mask)
output_high(DATA);
else
output_low(DATA);
clock();
mask*=2; //Modern compiler should optimise this to shift
}
if (lowhigh)
output_high(DATA);
else
output_low(DATA);
clock(); //clock out the bit to specify high/low register
output_low(DLEN);
clock(); //now clock this into the latches.
delay_us(8); //do not do anything else for 8uSec
}
void main(void)
{
int32 loop_cntr;
for( loop_cntr = 0; loop_cntr < 0xffff; loop_cntr++)
{
init(); //ensure bus is initialised
delay_us(100);
//low32--;
send(low32, 0); //load the low 32bits
send(high32, 1); //load the high 32bits.
//delay_us(100);
//printf("Loop count: %8LX\r\n", loop_cntr);
//printf("low32 value: %8LX\r\n", low32);
delay_ms(1000);
//printf("high32 value: %8LX\r\n", high32);
printf("WORKING...\r\n");
}
}
|
I need to put the 4100 32 bit words in the int32 section in the above code. I will post further information later. It's a while since I worked on this, so I'm still refreshing my own memory on where I was up to. Thanks.
PS I've used a PIC16F1847 for most of my tests but I now have PCH as well as PCM compilers. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Sep 12, 2023 2:23 am |
|
|
Obvious answer. Add an external EEPROM or SRAM.
4100 * 32bit numbers is 16400 bytes. 131200 bits. Something like the
23K256, gives you quickly accessible memory, that is retained when the
device is switched off. If you don't need to write often, then an EEPROM
like the 24256, is cheaper and only uses two pins from the processor.
On the PIC16 you are using, the program memory is only 14bits wide, so
can only store one byte per instruction word. Your chip has just 8K words
of program memory, so you are orders of magnitude short of being able
to hold this much data. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9246 Location: Greensville,Ontario
|
|
Posted: Thu Sep 14, 2023 3:18 pm |
|
|
hmm, maybe I'm looking at this wrong but isn't it a lot easier to
1) create a table of 32bit 'bit patterns' for the digits 0...9
2) run a loop that goes from 8750 to 10800
3) inside that loop grab each digit and lookup it's bit pattern, save into an array, then get next digit.....8,7,5,0 ( so 5 times)
4) now transmit the array of 5 x 32bits to the LCD
??
No need for a huge EEPROM
1) was done in the linked previous post..
2)+3) will be very fast as PIC love tables.... |
|
|
|
|
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
|