+ Post New Thread
Results 1 to 6 of 6
  1. #1
    Advanced Member level 1
    Points: 2,594, Level: 11

    Join Date
    Mar 2015
    Posts
    430
    Helped
    2 / 2
    Points
    2,594
    Level
    11

    Transfer data's to Shift Register

    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.

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 66,847, Level: 63
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    13,639
    Helped
    3122 / 3122
    Points
    66,847
    Level
    63

    Re: Transfer data's to Shift Register

    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
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



    •   AltAdvertisment

        
       

  3. #3
    Advanced Member level 1
    Points: 2,594, Level: 11

    Join Date
    Mar 2015
    Posts
    430
    Helped
    2 / 2
    Points
    2,594
    Level
    11

    Re: Transfer data's to Shift Register

    Quote Originally Posted by KlausST View Post
    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);
    	}



    •   AltAdvertisment

        
       

  4. #4
    Super Moderator
    Points: 66,847, Level: 63
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    13,639
    Helped
    3122 / 3122
    Points
    66,847
    Level
    63

    Re: Transfer data's to Shift Register

    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
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  5. #5
    Advanced Member level 3
    Points: 6,410, Level: 19
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    821
    Helped
    337 / 337
    Points
    6,410
    Level
    19

    Re: Transfer data's to Shift Register

    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 by std_match; 11th November 2018 at 02:47.



    •   AltAdvertisment

        
       

  6. #6
    Advanced Member level 3
    Points: 6,410, Level: 19
    Achievements:
    7 years registered

    Join Date
    Jul 2010
    Location
    Sweden
    Posts
    821
    Helped
    337 / 337
    Points
    6,410
    Level
    19

    Re: Transfer data's to Shift Register

    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);



--[[ ]]--