View previous topic :: View next topic |
Author |
Message |
rovtech
Joined: 24 Sep 2006 Posts: 262
|
Scrolling an LED display |
Posted: Sun Apr 04, 2021 9:08 am |
|
|
The following program works as shown:
Code: | ///////////////////////////////////////////////////////////////////////////////////////
/// DL1416.c Quad alphanumeric Display Last modified: 4 april 2021 ///
/// ///
/// The DL1416 is a four digit 16 segment LED display. This is a program to scroll ///
/// text continuously from the right. The text starts with 3 spaces for spacing. ///
/// The following refers to the PIC pins that control the display: ///
/// A7 & A6 address the display; 0 selects the rightmost digit, 3 the leftmost ///
/// B1 controls CU (Cursor). Held high if not used ///
/// C7 controls CE (Chip Enable). Held low if this is the only display ///
/// B0 controls WR (Write). A low pulse loads the ASCII data on C6 to C0 ///
///////////////////////////////////////////////////////////////////////////////////////
/* Pre-processor directives */
#include <16F722A.H>
#include <stdio.h>
#fuses INTRC_IO, NOWDT, PUT, NOPROTECT
#use delay (clock=8MHZ) // osc defaults to 8 MHz
#byte PORT_A = getenv("SFR:PORTA")
#byte PORT_B = getenv("SFR:PORTB")
#byte PORT_C = getenv("SFR:PORTC")
// Function Prototypes
void load();
void clear();
/* The main function */
void main()
{
// declare variables
int i,j,k,n; // counters
char text[16] = " DISPLAY DEMO"; // text to scroll, uppercase only
// initialize ports
set_tris_a (0x0f); // set Port A7 & A6 outputs, the rest inputs
set_tris_b (0xc0); // set Port B7-B6 inputs, the rest outputs
set_tris_c (0x00); // set Port C all outputs
PORT_A = 0x00;
PORT_B = 0x03;
PORT_C = 0x00;
clear();
// main loop
while (1) // endless loop
{
for(j=0; j<=14; j++)
{
k=j; // j must not change below
for(i=3;i<=3;i--) // cycle through digits
{
// n=i; // i must not change below
// PORT_A=n<<6; // get address into position
PORT_A=(i<<6); // get address into position
PORT_C=text[k]; // select the text character
load(); // display it
k=k+1; // advance tha address to next character
} // end for(i) loop
delay_ms(800); // display 4 digits for 1.5 seconds
} // end for(j) loop
} // end of endless while loop
} // end of main function
// functions
// pulse CE low to load the LED
void load()
{
output_low(pin_B0);
delay_us(5);
output_high (pin_B0);
}
// clear display
void clear()
{
int i;
for(i=0;i<=3;i++)
{
PORT_C=32; // load space
PORT_A=i<<6; // set address
load(); // write
}
}
// end |
But if I change PORT_A to be outputs on A7 & A6 and the rest inputs the display is presented on digit 0.
If I select A7, A6, A5 to be outputs and the rest inputs I get the display on digits 0 and 2 only.
Code: | set_tris_a (0x0f); // this works
set_tris_a (0x1f); // display on digits 0 & 2
set_tris_a (0x2f); // display on digit 0 only
set_tris_a (0b00111111); // display on digit 0 only |
What is happening?
A second question; as you can see I suspected the way I was moving the counter i to the most significant bits and have left my commented out statements.
This, below, works and I remember from the distant past that things done on the right side of an equal sign are not permanent.
Code: | PORT_A=i<<6; // get address into position |
can someone explain the rules, I cannot find the reference that I obviously read once long ago.
Why is i not changed except by the 'for' statement? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: Scrolling an LED display |
Posted: Sun Apr 04, 2021 10:39 pm |
|
|
rovtech wrote: |
But if I change PORT_A to be outputs on A7 & A6 and the rest inputs the
display is presented on digit 0.
|
So pins A4 and A5 are now inputs. Are they floating ?
What happens if you connect them to ground, or to ground
with 1K pull-down resistors ? |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Mon Apr 05, 2021 4:51 am |
|
|
Gee, had to look it up, think I used one 3.5 decades ago as a display for a LSi-11 system. Back then it was NEAT (pre LCD, pre PIC, and I could see small things......)
Sad thing is I might actually still have the PDP-11 asm code here in the basement..... |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Apr 05, 2021 9:53 am |
|
|
PCM Programmer; Yes, they were floating. I set TRIS to 0x3f and clipped a couple of 6" wires onto A5 and A4. Grounding both cycles the display on digit 0 only, removing A4 ground and floating I get the display on digit 0 and digit 3. It shows a few characters on one then continues on the other but it is random (not repeatable), for example.
DI(3) SP(0) LAY(3) DEM(0) where the digits are (3) (2) (1) (0) on the display and the characters are shown in sequence on the digit indicated.
grounding A4 and floating A5 I get the display on digit 0 only (the right most).
I am using PCM C Compiler, Version 5.064
I tried a 16F722 and a 16F722A and both behave the same. I have mixed inputs and outputs on the same port on the 16F722 in the past without problems (that I am aware of).
Is there a different way than TRIS to define the pins?
temtronic: This is the most useless project I have ever built! However some people do crossword puzzles...
It is a vintage displays demonstration and a picture can be seen here (I hope):
https://www.dropbox.com/s/fv3yhrcfvbhxxwh/Display%20Demo_LR.jpg?dl=0
https://www.dropbox.com/s/dk9mk1hi11bznck/Wiring_LR.jpg?dl=0
It has the following working displays: Dekatron, Amperex 8453 Numerical tube, E1T Counting Tube, three examples of Nixie tube, Numitron incandescent 7 segment, Vacuum Fluorescent display, a couple of Magic Eye tubes, a Russian 6LO1I CRT displaying a working clock face (Ebay kit), some LED displays including the DL1416 scrolling a message, an LED bargraph, an 8x8 LED matrix displaying alphanumerics between flashing the 64 LEDs in sequence.
The photos are out of date. The LED displays go in the opening and all the tubes shown are working. I will add a static display of some Trochotrons. Since you cannot see what they are doing there is no point having them work. A Russian MELZ LP4 requires a magnet and no one seems to have a picture of one so it would be difficult to get it working. It looks like an acorn tube with about 26 wires sticking out of the glass around the circumference.
Here are a few links to this technology:
http://www.r-type.org/articles/art-132.htm
https://groups.google.com/g/neonixie-l
https://www.dos4ever.com/Z550M/Z550M.html#ZM550
This is part nostalgia and part getting to play with technology before my start in electronics. It is interesting to see how things were done before computers, transistors, integrated circuits, and LED and LCD displays. |
|
|
Jerson
Joined: 31 Jul 2009 Posts: 125 Location: Bombay, India
|
|
Posted: Mon Apr 05, 2021 9:54 am |
|
|
Thinking aloud : PA_6 could be conflicting with the capsense module function. Therefore, you see only digit 0,2 etc as only PA_7 works correctly. I suggest, you check the capsense functionality is disabled / configured correctly. |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Apr 05, 2021 10:03 am |
|
|
Jerson; I don't understand capsense and have no idea where to start on that one. I have never heard the word before but I do appreciate your help. I will search on it.
edit: OK capacitive inputs for touchpads. If the pins are input they should not care what happens and should not prevent an output on a pin set as output.
Last edited by rovtech on Mon Apr 05, 2021 10:09 am; edited 2 times in total |
|
|
Jerson
Joined: 31 Jul 2009 Posts: 125 Location: Bombay, India
|
|
Posted: Mon Apr 05, 2021 10:06 am |
|
|
I've never used capsense on Microchip parts and am as clueless as you. However, I looked up the datasheet for your part 16F722A and it seems to have a (3) note on the RA6 pin which happens to be related to capsense module. |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Apr 05, 2021 11:44 am |
|
|
I don't see how the Capacitive sensing module could affect a pin. It relies on a frequency change.
I'm going to set up another 16F722A on a plugin breadboard to experiment easier. I don't like shorting a pin to ground in case it is output. I will use resistors to set inputs and LEDs to see the outputs.
The choice of pins on my present circuit is because my circuit is on perfboard and I have a 6 pin header on the left (pins 9 thru 14) and an 8 pin header on the right (pins 15 thru 22) eliminating jumper wires for the connections (the perfboard has sets of 4 holes connected). The headers connect to the display on a stacked board with various other LED displays like the 8x8 matrix. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9244 Location: Greensville,Ontario
|
|
Posted: Mon Apr 05, 2021 2:05 pm |
|
|
gee, I've got Numitrons, VFL and magic eyes here...
sigh, thought I was the only one with 'dust collectors'....
I've also got some Mostek 5213 clock chips..somewhere....
WHY ? I don't know...wish they'd find a 'good home' though...
Jay |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Mon Apr 05, 2021 7:05 pm |
|
|
Jay: I have Mostek 5002 and 5009, some of my favourite chips at one time.
Re my problem. I have LEDs on A7 and A6 using a simple circuit on a breadboard. All other pins floating (except MCLR and the two ICSP of course).
The following works. Note that TRIS is 0x3f but I have used output_x
If I comment out the output_a(i<<6); and use the PORT_A=(i<<6); instead the LEDs act randomly. Both on for many seconds, off for many seconds, etc
If I then make TRIS 0x0f it starts working again counting 0 to 3 in binary on the LEDs. It confirms what I was seeing in my original circuit.
Code: | // initialize ports
set_tris_a (0x3f); // set Port A7, A6 to outputs, the rest inputs
// main loop
while (1) // endless loop
{
for(i=0;i<=3;i++) // cycle through digits
{
output_a(i<<6); // get address into position
// PORT_A=(i<<6);
delay_ms(1000); // display for 1 second
} // end for(i) loop
|
Using output_a(i<<6); in my original circuit also works.
I suspected the PORT_A=(i<<6); but for the wrong reason hence my question about the rules for why i does not get permanently changed. Sometimes you do things for years until there are problems then you can't remember why. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 05, 2021 9:30 pm |
|
|
Since you are not using #fast_io, CCS defaults to standard i/o mode.
This means output_a(i<<6); will set all 8 pins on PortA to be outputs.
To me, your situation is wacky. It's some sort of artifact of one or more of these:
- your 16F722 or 16F722A.
- your board construction, including decoupling, wiring, connections, etc.
- the obscure display device you're using.
- the floating inputs.
- your compiler version, or possibly a damaged installation. |
|
|
Jerson
Joined: 31 Jul 2009 Posts: 125 Location: Bombay, India
|
|
Posted: Mon Apr 05, 2021 9:38 pm |
|
|
You could possibly get it right by using an intermediate variable like this
int c;
c = i << 6;
PORT_A = c;
Now, it should work just like output_a(i << 6) |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue Apr 06, 2021 8:50 am |
|
|
Thanks PCM Programmer; Those are suggestions I was hoping for, as well as pointing out my errors. I investigated each of them:
"Since you are not using #fast_io, CCS defaults to standard i/o mode. This means output_a(i<<6); will set all 8 pins on PortA to be outputs." I did not know that. I added #use fast_io(A) see below. I hope I'm using it correctly. It makes no difference.
"- your 16F722 or 16F722A" unlikely that both chips are defective.
"- your board construction, including decoupling, wiring, connections, etc." I'm using two different constructions, one on a prototype plugboard and the other soldered perfboard. I have Tantalum plus ceramic between pins 19 & 20. Wiring is short and neat.
"- the obscure display device you're using." The display is not used in the 722A version, only 2 LEDS with 1k.
"- the floating inputs." A0 through A5 have short 1k standing vertical with the other ends soldered together. I tried connecting to ground and to +5v and it makes no difference.
"- your compiler version" Very possible. Updates to a system running nicely invites problems. That is why I use Win7.
"or possibly a damaged installation" Unlikely.
Code: | /* Pre-processor directives */
#include <16F722A.H>
#include <stdio.h>
#fuses INTRC_IO, NOWDT, PUT, NOPROTECT
#use delay (clock=8MHZ) // osc defaults to 8 MHz
#byte PORT_A = getenv("SFR:PORTA")
#use fast_io(A)
/* The main function */
void main()
{
int i; // counter
// initialize ports
// set_tris_a(0x0f); // this works with PORT_A=(i<<6);
set_tris_a(0x3f); // this does NOT work with PORT_A=(i<<6);
// main loop
while (1) // endless loop
{
for(i=0;i<=3;i++) // cycle through digits
{
output_a(i<<6); // works with set_tris_a(0x3f);
// PORT_A=(i<<6); // does not work with set_tris_a(0x3f);
delay_ms(1000); // display for 1 second
} // end for(i) loop
} // end of endless while loop
} // end of main function
// end |
If there are no errors in my code I will assume a compiler problem. I can get it to work so it is not enough incentive to update my software. I ran into problems last time I did that and I would like my ROV project with its 9 PICs to remain unchanged in the middle of my present re-build.
I suppose I could install the latest CCS on another computer like my new Win10 laptop i7, uggh! I hate that computer. |
|
|
rovtech
Joined: 24 Sep 2006 Posts: 262
|
|
Posted: Tue Apr 06, 2021 9:04 am |
|
|
Thanks Jerson;
Interesting fact. The following works.
Code: | // main loop
while (1) // endless loop
{
for(i=0;i<=3;i++) // cycle through digits
{
j=i<<6;
// output_a(i<<6); // works with set_tris_a(0x3f);
PORT_A=j; // solves problem of set_tris_a(0x3f);
delay_ms(1000); // display for 1 second
} // end for(i) loop
|
I had tried masking i and other variations but had not done it exactly the way you suggested.
OK experts why does this work? I am confused because I was not confident in my skills, especially the way I was using i from the 'for' loop.
Edit: works with or without #use fast_io(A) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Apr 06, 2021 11:10 am |
|
|
I read the data sheets for the 16F722 and 16F722A. Both these PICs
require a VCAP. I notice there is no VCAP fuse setting at the end of
the .LST file. It says "NOVCAP". Maybe this is the cause of all your
problems. What voltage are you using for Vdd ? If it's 5v, then you
need the VCAP.
Fuses for vs. 5.064:
Code: | Configuration Fuses:
Word 1: 3FE4 INTRC_IO NOWDT PUT MCLR NOPROTECT BROWNOUT BORV19 PLLEN NODEBUG
Word 2: 0030 NOVCAP
|
I did a comparison of the .LST files between versions 5.064 and 5.103.
They are the same except that for 5.103 the 2nd fuse word is 0x3FFF.
But that word has the same NOVCAP setting, so it's effectively the same. |
|
|
|