![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
seifpic
Joined: 11 Mar 2012 Posts: 45 Location: Egypt
|
Array routine not working |
Posted: Sun Mar 11, 2012 6:57 pm |
|
|
Hello,
I am making a digital clock using LEDs powered by a shift register instead of a 7 segment display. Anyway, since it's going to be powered by a shift register instead of a 7 seg-display, I have made a routine for numbers from 0 to 12 (I made it up to 12 for a specific reason). Anyway, my code doesn't seem to function right (simulating using Proteus Professional 7.7).
here is my code:
Code: |
#include <16f628a.h>
#use delay (crystal=32768)
int1 zero[]={true, true, true, true, false, true, true, false};
int1 one[]={false, false, false, true, false, true, false, false};
int1 two[]={true, false, true, true, true, false, true, false};
int1 three[]={true, true, true, false, true, false, true, false};
int1 four[]={true, true, false, false, true, true, false, false};
int1 five[]={false, true, true, false, true, true, true, false};
int1 six[]={false, true, true, true, true, true, true, false};
int1 seven[]={true, true, false, false, false, false, true, false};
int1 eight[]={true, true, true, true, true, true, true, false};
int1 nine[]={true, true, true, false, true, true, true, false};
int1 ten[]={true, true, true, true, false, true, true, true};
int1 eleven[]={false, false, false, true, false, true, false, true};
int1 twelve[]={true, false, true, true, true, false, true, true};
void finset(int1* fnum, char out, char clk) {
int i=1;
for(i=1; i<=8; ++i) {
if(fnum[i]) {
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
} else {
output_low(out);
output_high(clk);
output_low(clk);
}
}
}
void num(int rnum, char out, char clk) {
switch(rnum) {
case 0:
finset(zero, out, clk);
break;
case 1:
finset(one, out, clk);
break;
case 2:
finset(two, out, clk);
break;
case 3:
finset(three, out, clk);
break;
case 4:
finset(four, out, clk);
break;
case 5:
finset(five, out, clk);
break;
case 6:
finset(six, out, clk);
break;
case 7:
finset(seven, out, clk);
break;
case 8:
finset(eight, out, clk);
break;
case 9:
finset(nine, out, clk);
break;
case 10:
finset(ten, out, clk);
break;
case 11:
finset(eleven, out, clk);
break;
case 12:
finset(twelve, out, clk);
break;
}
}
//==============================
void main() {
while(true) {
num(1, pin_a1, pin_a0);
delay_ms(1500);
num(2, pin_a1, pin_a0);
delay_ms(1500);
num(3, pin_a1, pin_a0);
delay_ms(1500);
num(4, pin_a1, pin_a0);
delay_ms(1500);
num(5, pin_a1, pin_a0);
delay_ms(1500);
num(6, pin_a1, pin_a0);
delay_ms(1500);
num(7, pin_a1, pin_a0);
delay_ms(1500);
num(8, pin_a1, pin_a0);
delay_ms(1500);
num(9, pin_a1, pin_a0);
delay_ms(1500);
num(10, pin_a1, pin_a0);
delay_ms(1500);
num(11, pin_a1, pin_a0);
delay_ms(1500);
num(12, pin_a1, pin_a0);
delay_ms(1500);
}
}
|
this is how the finset function should turn out for the number zero:
Code: |
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
|
Thanks in advance |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Mar 11, 2012 7:29 pm |
|
|
well, you've just found out about rule number one.
1) Get rid of Proteus ! It is full of errors, bugs and faulty DRCs.NO version will EVER correctly 'simulate' a PIC.If I had a nickel for every time this comes up,I'd get free lifetime upgrades of PCM !
2) You never say which 'shift register' you're using.There are drivers for some that CCS kindly supplies in the 'examples' folder.
Without knowing the device, no one can properly comment on why you simulated code doesn't work.
Really , you should buy real PICs, a white breadboard and support chips.Everyone here is more than happy to help, but you need to understand, we can only really help with programs running in real PICs. |
|
![](templates/subSilver/images/spacer.gif) |
seifpic
Joined: 11 Mar 2012 Posts: 45 Location: Egypt
|
|
Posted: Sun Mar 11, 2012 7:36 pm |
|
|
temtronic wrote: | well, you've just found out about rule number one.
1) Get rid of Proteus ! It is full of errors, bugs and faulty DRCs.NO version will EVER correctly 'simulate' a PIC.If I had a nickel for every time this comes up,I'd get free lifetime upgrades of PCM !
2) You never say which 'shift register' you're using.There are drivers for some that CCS kindly supplies in the 'examples' folder.
Without knowing the device, no one can properly comment on why you simulated code doesn't work.
Really , you should buy real PICs, a white breadboard and support chips.Everyone here is more than happy to help, but you need to understand, we can only really help with programs running in real PICs. |
Proteus has worked good so far using this code for zero:
Code: |
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
|
It displays zero (the other numbers work too in that way), but using that way for many numbers causes an Out of ROM error: http://www.ccsinfo.com/forum/viewtopic.php?t=47717
The reason I got Proteus was to debug circuits before buying the components. The shift register I'm using is the 74164 sipo.
If proteus isn't good, what other simulator (that has the same functions) do you recommend?[/code] |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9170 Location: Greensville,Ontario
|
|
Posted: Sun Mar 11, 2012 8:47 pm |
|
|
I can't recommend ANY simulator even though I've got almost 25 years using PICs.No simulator to date (I've tried all of them, ok, a LOT of them) truly 'simulates' PICs. 'Close' is NOT good enough. If it fails ONE aspect of operation, the simulator is garbage.
Nothing compares to real chips in the real world. PICs and other parts are CHEAP compared to 10, 25, 35 years ago and NO amount of 'simulation' will prove that your circuit and code will ACTUALLY work in the real world.
All of the simulators might 'virtually' work but that isn't good enough.
As for your code for the 74164, look at the CCS example for using the '595' shift register and modify it for 74164 operation. It'll produce smaller code and you'll gain a lot of hands on knowledge. There might be a driver in the 'code library' or in the 'examples' folder, I haven't checked to see 'what's new' for several months. If nothing comes up, try 'googling ccs c code 74164'.... |
|
![](templates/subSilver/images/spacer.gif) |
dezso
Joined: 04 Mar 2010 Posts: 102
|
Re: Array routine not working |
Posted: Sun Mar 11, 2012 11:24 pm |
|
|
seifpic wrote: |
Code: |
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_high(out);
output_high(clk);
output_low(clk);
output_low(out);
output_high(clk);
output_low(clk);
|
|
That is a duct tape MacGiver version !!!
Try something like this
Code: |
int8 zero = 0b11110110;
int8 one = 0b00010100;
int8 two = 0b10111010;
void Shift_out(b)
{
int8 i = 0;
for(i=0; i<=8; ++i) // loop thru 8 bit
{
if(bit_test(b,i)) // test if bit set or clear
{
output_high(out); // set output high
output_high(clk); // clock
output_low(clk);
}
else
{
output_low(out); // set output low
output_high(clk); // clock
output_low(clk);
}
}
}
void main()
{
Shift_out(two);
while (true)
{}
} |
_________________ I'm could be wrong many time's, at least I know what I'm doing ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Serial to parallel shift register |
Posted: Wed Mar 14, 2012 7:41 am |
|
|
There are possible problems is trying to use the 74164 serial to parallel shift register for this kind of task.
Post a schematic and we may be able to help you.
And I totally endorse temtronic's view. Get rid of Proteus.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Mar 14, 2012 9:05 am |
|
|
Quote: |
That is a duct tape MacGiver version !!!
|
Sorry, this is coding assembler in C !!! |
|
![](templates/subSilver/images/spacer.gif) |
dezso
Joined: 04 Mar 2010 Posts: 102
|
|
Posted: Wed Mar 14, 2012 1:01 pm |
|
|
Don't see a smile face in your post, have to assume that you aren't kidding
I know assembly, probably more than C, even in asm would use BTFSC and DECFSZ instead of BSF and BCF for shifting out a variable !! _________________ I'm could be wrong many time's, at least I know what I'm doing ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Mar 14, 2012 6:00 pm |
|
|
Code: |
-----------------
RD7 -------WWW---------| o o o o o o o o |
RD6 -------WWW---------| o o o o o o o o |
RD5 -------WWW---------| o o o o o o o o |
RD4 -------WWW---------| o o o o o o o o |
RD3 -------WWW---------| o o o o o o o o |
RD2 -------WWW---------| o o o o o o o o |
RD1 -------WWW---------| o o o o o o o o |
RD0 -------WWW---------| o o o o o o 0 0 |
-----------------
| | | | | | | |
-----------------
| Q Q Q Q Q Q Q Q |
| 7 6 5 4 3 2 1 0 |
RB0 -------------------| CK |
| |
RB1 -------------------| DATA |
| 74HC164 |
-----------------
|
The above shows how a 74HC164 MIGHT be connected to a PIC and an 8*8 matrix.
Without confirmation from the original author I have no way of knowing if this suggestion is even close.
In a multiplex display each column (row) is activated in rapid succession.
It's ESSENTIAL to turn the entire display OFF between transitions from one phase to the next.
If the display is not turned off there is leakage between phases.
I'm assuming PortD is row driver (common anodes), and 74HC164 is column driver (common cathodes).
Using '595's the way to drive this kind of setup COULD go as follows.
(1) Turn OFF all column drives i.e. OE off.
(2) Set row drives for current column.
(3) Turn column drive ON for current column i.e. shift column , then OE on.
(4) Repeat (1) (2) (3) for each column 0 to 7 ad nausium.
The 74HC164 does not have '595's output enable so the above can't work.
However, it is possible to operate the other way round.
(1) Turn OFF all row drives i.e. all RDx = 0.
(2) Turn ON current column drive, i.e. shift data in 74HC164.
(3) Set row drives for current column.
(4) Repeat (1) (2) (3) for each column 0 to 7 ad nausium.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
seifpic
Joined: 11 Mar 2012 Posts: 45 Location: Egypt
|
|
Posted: Wed Mar 14, 2012 9:19 pm |
|
|
Mike Walne wrote: |
(1) Turn OFF all row drives i.e. all RDx = 0.
(2) Turn ON current column drive, i.e. shift data in 74HC164.
(3) Set row drives for current column.
(4) Repeat (1) (2) (3) for each column 0 to 7 ad nausium.
Mike |
The reason I am not clearing the 74164 shift register between every update is that I am already shifting 8 times for every number. I updated my code and got rid of Proteus as others were suggesting. Now I just need to wait till I get the components to test it.
Function for 74164:
Code: | int8 zero = 0b11110110;
int8 one = 0b00010100;
int8 two = 0b10111010;
int8 three = 0b11101010;
int8 four = 0b11001100;
int8 five = 0b01101110;
int8 six = 0b01111110;
int8 seven = 0b11000010;
int8 eight = 0b11111110;
int8 nine = 0b11101110;
int8 ten = 0b11110111;
int8 eleven = 0b00010101;
int8 twelve = 0b10111011;
void Shift_out(int8 b, char out, char clk) {
int8 i = 0;
for(i=0; i<=8; ++i) // loop thru 8 bit
{
if(bit_test(b,i)) // test if bit set or clear
{
output_high(out);// set output high
output_high(clk);// clock
}
else
{
output_low(out); // set output low
output_high(clk); // clock
}
}
output_low(clk);
}
void main() {
Shift_out(zero, pin_b7, pin_b6) ;
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Mar 14, 2012 9:51 pm |
|
|
What range of index values (i) does your for() loop create ?
Which ones should it create ? Run this test program
to show the indexes that it creates:
Code: |
#include <16F628A.H>
#fuses INTRC_IO, NOWDT, BROWNOUT, PUT, NOLVP
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, ERRORS)
//==========================================
void main()
{
int8 i;
for(i=0; i<=8; ++i)
{
printf("%u \n\r", i);
}
while(1);
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
Your schematic |
Posted: Thu Mar 15, 2012 5:04 am |
|
|
Quote: |
I am making a digital clock using LEDs powered by a shift register instead of a 7 segment display. Anyway, since it's going to be powered by a shift register instead of a 7 seg-display, I have made a routine for numbers from 0 to 12 (I made it up to 12 for a specific reason). Anyway, my code doesn't seem to function right (simulating using Proteus Professional 7.7).
here is my code:
|
OK, so I've got your schematic totally wrong, I read it that you were NOT using a 7 segment display and assumed that you were using some sort of matrix. What I now believe is that you ARE using something similar to a 7 segment display, but driving it from a 74164 rather than directly from a PIC.
So it seems your schematic COULD look like this:-
Code: |
---------------
| |
| 74HC164 Q0 |___|\|___/\/\/\___ GND
| | |/|
| |
| Q1 |___|\|___/\/\/\___ GND
| | |/|
RB6 -------------------| CK |
| Q2 |___|\|___/\/\/\___ GND
| | |/|
RB7 -------------------| DATA |
| Q3 |___|\|___/\/\/\___ GND
| | |/|
| |
| Q4 |___|\|___/\/\/\___ GND
| | |/|
| |
| Q5 |___|\|___/\/\/\___ GND
| | |/|
| |
| Q6 |___|\|___/\/\/\___ GND
| | |/|
| |
| Q7 |___|\|___/\/\/\___ GND
| | |/|
---------------
The LEDs arranged in a pattern:-
1
2 7
3
4 6
5 0
|
please confirm that I have now got somewhere close.
And DO READ PCM programmer's post.
Mike |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
![](templates/subSilver/images/spacer.gif) |
seifpic
Joined: 11 Mar 2012 Posts: 45 Location: Egypt
|
|
Posted: Thu Mar 15, 2012 9:34 am |
|
|
PCM programmer wrote: | What range of index values (i) does your for() loop create ?
Which ones should it create ? Run this test program
to show the indexes that it creates:
|
Yeah, it was supposed to do 8 loops but it did nine because I set i to 0. I set it to 1 and it's supposed to work now. |
|
![](templates/subSilver/images/spacer.gif) |
seifpic
Joined: 11 Mar 2012 Posts: 45 Location: Egypt
|
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|