# inerfacing 4094 with PIC12F509

Status
Not open for further replies.

#### this

##### Member level 2
Hi there.
I want to control CD4094B with PIC12F509.
I've connected Clock(CL), Data(DT), Strbe(ST) and Enable(EN) to my pic, and 8 leds to 4094 outputs.

As far as I understand datasheet, procedure is:
Set Data pin (0||1), put impulse on Clock pin(0,1) <- this will become output Q9
Set Data pin (0||1), put impulse on Clock pin(0,1) <- this will become output Q8
...
...
Set Data pin (0||1), put impulse on Clock pin(0,1) <- this will become output Q1

put inpulse on Strobe(0,1)
Setting Enable = 1 should activate output.

So my code looks like this:

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void set4094(unsigned char c)
{
EN = 0;
for(unsigned char i = 0; i<8;i++) //iterate through char bits
{
DT = (c&(1<<i)) ? 1 : 0;  //set data
CL = 1;           //pulse on clock
CL = 0;
}
ST = 1;               //pulse on strobe
ST = 0;
EN = 1;               //enable output
}

void main()
{
TRIS = 0;             //set all ports output

while(1)
{
set4094(0);       //all 4094 outputs low
__delay_ms(200);      //wait a bit
set4094(0xFF);        //all 4094 outputs high
__delay_ms(200);      //wait a bit
}                 //repeat forever
}

I was expecting all leds to flash every 200 ms, but instead they're flashing in some random manner.
What am I missing here?
Actually what does mean that my 4094 is "3 state"?

Thanks

#### wp100

Hi,
The logic of those chips can seem confusing at times, first have a look at a data sheet with a clearer timing diagram,
https://www.datasheetcatalog.org/datasheets/70/109371_DS.pdf

Then set the chip up with some manual switches as input and prove the logic in that static mode before you connect to your pic.

Note that the 4094s output drive abilty is far lower than a typical pic pin - see this thread https://www.edaboard.com/threads/187814/

Tri State - 3 output states allowed, Low Output, High Output and High Impedance - the latter is where several devices are connected to the same 'data' bus, but only one chips outputs can be active at once, so all the other are in the High Impedance mode and not seen on the bus by the master input device.

While a handy exrecise, wonder why you are using a 4094, would have though it would be much simpler to use a larger pic chip ?

#### FvM

##### Super Moderator
Staff member
The code is basically correct, deasserting EN is the only thing you should omit, because it brings up undefined output states during transfer. You can simply wire the output enable input to constant 'H' level. Coding efficiency would suggest to shift right the input data rather than using a multiple shifted bit mask. But your code is correct as well.

To understand, why the design isn't working, you have to refer to the pin setup and the hardware details. The reason can't be seen from the posted code.

I simply assume, that you have a reason to use a peripheral shift register instead of processor pins. If CD4094 output currents are too low, there's a 74HC4094 replacement available. 74HC594 or 595 is another 8-Bit shift register to be considered.

#### this

##### Member level 2
Hi.

So I pulled 'Output enable' high, and changed 'check bit' to right shift.
I've also double checked my hardware and everything seems to be fine there.
I've got CL on GP0, DT on GP1 and ST on GP2. Do I need anything else in terms of hardware?

I made few tests and I believe it is a software problem, here's why:

everytime I feed my function with byte starting with "1" (for example 0b11001100) displayed result is OK
everytime I use byte starting with "0" (for example 0b00110011) there is some random result, sometimes diff. after power off/on.

I run umpty tests and it was always like this, whenever my byte starts with 0b1.... it's ok, whenever my byte starts with 0b0... it's wrong.
I made few photos here (when you click on the image, check the file name in the address bar - it's the bit pattern used)

Any clue what's going on?

I'm not using larger µC because it doesn't have any real purpose, I'm just learning.

Here's my complete program i was using for testing:

Code C - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 4094.h------------------------------------
#ifndef __4094_h__
#define __4094_h__

__CONFIG(OSC_IntRC & WDT_OFF & MCLRE_OFF & CP_OFF);

#define CL GP0
#define DT GP1
#define ST GP2
//#define EN GP5

void set4094(unsigned char c)
{
for(unsigned char i = 0; i < 8; i++)
{
DT =((c>>i) & 1);
CL = 1;
CL = 0;
}
ST = 1;
ST = 0;
}

#endif
//4094.h end---------------------------------
//main.c ------------------------------------
#include<htc.h>
#include"4094.h"

void main()
{
TRIS = 0;
set4094(0b10001000);
while(1)
{

}
}
//main.c end---------------------------------

#### FvM

##### Super Moderator
Staff member
I don't see a problem with the code. I believe, there must be a hardware problem.

My suggestion for an efficient shift register is this, by the way:
Code:
DT =(c & 1);
c>>1;

Status
Not open for further replies.

Replies
4
Views
3K
Replies
5
Views
1K
Replies
16
Views
5K
Replies
21
Views
11K
Replies
4
Views
2K