Jump to content
Sign in to follow this  
RobG

LaunchPad, 74HC165, Switches

Recommended Posts

*******************

Also checkout this post

*******************

 

In this example, I am demonstrating how to connect switches using parallel-serial shift register 74HC165.

You can daisy chain as many 165s as you want.

In my example I have 2 of them, which allowes me to connect up to 16 switches.

In the video, I am using small 6 position DIP switch and all unused inputs are grounded and do not have pull-up resistors.

Also, the state of switches is displayed on a 7 segment display (see my other post for how to connect 7 segment display.)

De-bouncing is accomplished by comparing previous state with current (switchReady.)

 

 

#include 

unsigned int data = 0;                   // data to be displayed
unsigned int digitCounter = 0;				// Digit counter
unsigned char digit = 0;					// Single digit to be displayed
unsigned char hex7digit[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x58,0x5E,0x79,0x71}; // Hex to 7 digit map
unsigned char digitSelector[4] = {0x01, 0x02, 0x04, 0x08}; // Digit selector map

unsigned int switchReady = 0x0; // When BITn is 0, means switch is unstable H->L or L->H
unsigned int switchStatus = 0x0; // Pressed or released

void main(void)
{
 WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

 P1OUT |= 0x01; 							// Port P1.0 will be used to latch both, 74HC165 and 74HC595
 P1DIR |= 0x01;

 USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE; // In, out & clk enable, SPI Master
 USICTL1 |= USICKPH + USIIE;               // Counter interrupt, flag remains set
 USICKCTL = USIDIV_4 + USISSEL_2;          // /16 SMCLK
 USICTL0 &= ~USISWRST;                     // USI released for operation
 USICNT = USI16B;                     		// Enable 16 bit

 CCTL0 = CCIE;                             // CCR0 interrupt enabled
 CCR0 = 625;								// Approx. 5ms 
 TACTL = TASSEL_2 + MC_1 + ID_3;           // SMCLK/8, upmode

 _bis_SR_register(LPM0_bits + GIE);        // Enter LPM0 w/ interrupt

   WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
}

// Timer A0 interrupt service routine
#pragma vector = TIMERA0_VECTOR
__interrupt void Timer_A (void)
{	
 //P1OUT &= ~0x01;							// You could latch input right now
 //P1OUT |= 0x01;
 if(digitCounter == 0) {		// Update switch status every 20 ms
 	switchReady = ~(USISR ^ switchStatus);	// Copy USI's register to switchReady and switchStatus
switchStatus = USISR;
if((switchReady & 0x3F) == 0x3F) {			// When all 6 switches are ready...
 		data = switchStatus;	// move input to data
}
 }

 digitCounter++;        					// Increase digit counter
 digitCounter &= 0x03; 					// Mask, counter range is 0-3
 digit = data>>(4 * digitCounter); 		// Shift digits right
 digit &= 0x0F; 							// Mask, we need first digit only
 USISRL = hex7digit[digit]; 				// Get segments from the map
 USISRH = digitSelector[digitCounter]; 	// 

 USICNT |= 16;                           	// Start USI
}

// USI interrupt service routine
#pragma vector = USI_VECTOR
__interrupt void USI_TXRX (void)
{
 USICTL1 &= ~USIIFG;               		// Clear pending flag
 P1OUT &= ~0x01;							// Latch data display (& input for next timer interrupt)
 P1OUT |= 0x01;
}

 

Schematic:

post-197-135135493649_thumb.png

Share this post


Link to post
Share on other sites

MSP 430 Launchpad 2553, I can program 74HC595. How to program 74HC165 and get from it the input values (to read them in IAR, TXT file, or other way). The easiest way to make it ? The simplest way to get from register let

Share this post


Link to post
Share on other sites


#include  "msp430g2553.h"

 

void pulseClock ( void );

void shiftOut ( void );

void pauza (void);

 

#define DATA BIT0  // DS -> P1.0      14 pin

#define CLOCK BIT4 // SH_CP -> P1.4   11 pin

#define LATCH BIT5 // ST_CP -> P1.5   12 pin

 

 

 

char a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0;

char i;

 

int main(void)

{

  WDTCTL = WDTPW | WDTHOLD;     // Stop WDT

 

 

  P1DIR |= (DATA + CLOCK + LATCH ); //connects 74HC165 or  74595

      

 

  //P1DIR |= 0x01; //P1.0 red LED output

// P1DIR |= 0x40; //P1.0 yellow LED output

 

  // P1DIR |= BITD;

 // P1DIR |= BIT9;

  P1REN |= BIT0;// like a button

  P1OUT |= BIT0;//like a button

 

 

  P1IES |= BIT0;//  down Vcc to GND

  //P1IES &= ~0x28;//  grow GND to Vcc

  P1IE |= BIT0;// interput from buton

 

  __enable_interrupt();// global interput

 

    while(1)

  {

while(b==1)

 

{

  P1DIR |= 0x40; //P1.0 yellow LED output

  __delay_cycles(10000);

  P1OUT ^= 0x40; // LED OFF

  b=0;

}

}

 

  }

     

  // If calibration constants erased

       

      

//Button

#pragma vector=PORT1_VECTOR

__interrupt void Port_1(void)

{  

  __delay_cycles(300000);//op

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...