Transfer data's to Shift Register

Status
Not open for further replies.

gauravkothari23

Advanced Member level 2
Joined
Mar 21, 2015
Messages
640
Helped
5
Reputation
10
Reaction score
4
Trophy points
1,298
Activity points
6,922
Hi all...
i am working on a project where i have to interface shift register SN74HC595 (Circuit Diagram attached). with 89S52.
i have interfaced 8 LED's to shift register.
Code:
#include <reg51.h>
#include <STDIO.h>

sbit data1 = P2^0;  //DS
sbit clock = P2^2;  //SH_CP
sbit latch = P2^1;  //ST_CP

unsigned char led_data_value, led_value, on_led_counter;	

void led_data(unsigned char databyte);
	
//#define on_led 0xFE;
//#define extra1_led 0xFD;
//#define fault_led 0xFB;
//#define extra2_led 0xF7;
//#define all_call_led 0xEF;
//#define extra3_led 0xDF;
//#define extra4_led 0xBF;
//#define extra5_led 0x7F;
// fire_siren = 0xFC;

void msdelay(unsigned int value);

void led_data(unsigned char databyte)
{
	unsigned int i;
	for(i=0;i<8;i++)
	{
		data1 = ((databyte&0x80) == 0x80);

		clock=1;
		clock=0;
		databyte = databyte << 1;
	}
	latch=1;
	latch=0;
}



 void msdelay(unsigned int value)
{
 unsigned int i,j;
 for(i=0;i<value;i++)
 for(j=0;j<100;j++);
}

void main()
{
	data1=0;
	clock=0;
	latch=0;
	led_value = 0xFF;
	led_data(0xFF);
	while(1)
	{
		led_value = led_value &= 0xFE;          //    ON LED-1
		led_data(led_value);
		msdelay(2000);
		led_value = led_value &= 0xFD;         //    ON LED-2
		led_data(led_value);
		
	}
}
for example i have 8 LED's (LED-1, LED-2, LED-3........ LED-8)
so when i need to on LED-1, i write
led_value = led_value &= 0xFE;
and then again when i need to ON the LED-2, i AND the previous value with the new value i need.
led_value = led_value &= 0xFD; // ON LED-2
so this things works perfectly when i need to ON any of led.
now what my problem is...
how can i OFF the specific LED, what parameter's should i pass to OFF any LED i need. because i cannot substract the value of LED i need to OFF because the output value will be something different.
ON and OFF of any LED's will be randomly done.

- - - Updated - - -

when i add first led i write (0xFE) 1111 1110
when i need to add second LED (0xFD) i add previous value with the second LED value.
so 0xFE &= 0xFD (1111 1110 &= 1111 1101) so what i get here is 1111 1100. so here my both the LED's get ON.
but when i need to OFF led 1. what should be done to the new value (1111 1100) to again get 1111 1101.
 

Attachments

  • 74HC595.png
    85.4 KB · Views: 120

Hi,

to swtich a LED ON you correctly use the "AND" logic.

obviously to swtch OFF a LED you need to use "OR" logic.

OR 1 for LED 1
OR 2 for LED 2
OR 4 for LED 3
and so on.

Klaus

Added:
I recommend to define 8 flags for the 8 LEDs in your software
Then build the according byte for the whole of 8 LEDs
Then shift this byte to the ´595 out as already done.

Klaus
 

yes... but i guess the OR logic wont work...
because when i OR LED1 with my current value..
as example...
when i write (0xFE) to OFF LED-1
current value (1111 1100) |= LED-1 Value (1111 1110) which = 1111 1110
current value is where my both LED's are ON.
This will not OFF my LED-1, but instead it will OFF my LED-2

- - - Updated - - -

please correct me if i am wrong..
to OFF the LED, can i initially pass NOT and invert all bits of the value i need...
for example.. if suppose i need to OFF LED-1, so i will write (0xFE).
i will invert all the bits and then i can get 0000 0001. and then i can use OR logic..
so current value (1111 1100) |= Inverted LED-1 Value (0000 0001)
so output will be 1111 1101.
is this logic correct.

- - - Updated - - -

something like:-
Code:
unsigned char invert;
	data1=0;
	clock=0;
	latch=0;
	led_value = 0xFF;
	led_data(0xFF);
	while(1)
	{
		led_value = led_value &= on_led;
		led_data(led_value);
		msdelay(2000);
		led_value = led_value &= extra1_led;
		led_data(led_value);
		msdelay(2000);
		invert =~ on_led;
		led_value = led_value |= invert;
		led_data(led_value);
		msdelay(2000);
	}
 

Hi,

suppose i need to OFF LED-1, so i will write (0xFE).
i will invert all the bits and then i can get 0000 0001. and then i can use OR logic..

Good idea. For sure you can use binary value "0000 0001" which is hex 0x01, or decimal "1".

From post#2
OR 1 for LED 1
OR 2 for LED 2
OR 4 for LED 3
;-)

Klaus
 

I recommend using #define's with one bit set for each LED:
Code:
#define on_led 0x01;
#define extra1_led 0x02;
#define fault_led 0x04;
#define extra2_led 0x08;
#define all_call_led 0x10;
#define extra3_led 0x20;
#define extra4_led 0x40;
#define extra5_led 0x80;

// Turn on a LED:
led_value &= ~on_led;
led_data(~led_value);

// Also turn on another LED:
led_value &= ~fault_led;
led_data(~led_value);

// Turn off the first LED:
led_value |= on_led;
led_data(~led_value);

// You can use other defines to help:
#define LED_ON(led_bit) { led_value &= ~led_bit; led_data(~led_value); }
#define LED_OFF(led_bit) { led_value |= led_bit; led_data(~led_value); }

// Use them like this:
LED_ON(on_led);
LED_ON(fault_led);
LED_OFF(on_led);

It is possible to do the corresponding thing with the #defines with a single zero bit, but it isn't as obvious which the important bit is.
It is common to use only capital letters for #define constants so you easily can distinguish them from variable names.

Edit:
You should use series resistors for the LEDs. I suggest a value that gives about 5 mA for normal indicator LEDs. In this case maybe 680 Ohms for 5V and red LEDs. 1 kOhm could also be ok.
 
Last edited:

I used too many ~ (invert all bits).
Corrected (but not tested) code:
Code:
#define on_led 0x01;
#define extra1_led 0x02;
#define fault_led 0x04;
#define extra2_led 0x08;
#define all_call_led 0x10;
#define extra3_led 0x20;
#define extra4_led 0x40;
#define extra5_led 0x80;

// Turn on a LED:
led_value &= ~on_led;
led_data(led_value);

// Also turn on another LED:
led_value &= ~fault_led;
led_data(led_value);

// Turn off the first LED:
led_value |= on_led;
led_data(led_value);

// You can use other defines to help:
#define LED_ON(led_bit) { led_value &= ~led_bit; led_data(led_value); }
#define LED_OFF(led_bit) { led_value |= led_bit; led_data(led_value); }

// Use them like this:
LED_ON(on_led);
LED_ON(fault_led);
LED_OFF(on_led);
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…