View previous topic :: View next topic |
Author |
Message |
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
74165.c Expanded Input Chip |
Posted: Thu Apr 10, 2008 10:29 am |
|
|
Just wondered if anyone had used this code and if it is ok in it's current state? I need to convert 8 bits of parallel data into serial using the 74HCT165 in order to save on port pins.
Can someone also confirm the following connections are correct:
Signal PIC 74165
-----------------------------------------------------
EXP_IN_ENABLE PIN_B3 /CE (pin 15)
EXP_IN_CLOCK PIN_B4 /PL (pin 1)
EXP_IN_DI PIN_B5 Q7 (pin 9)
The data sheet I have for the 74HCT165 is a tad ambiguous!
Last edited by edhaslam on Fri Apr 11, 2008 1:46 am; edited 2 times in total |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Thu Apr 10, 2008 11:51 am |
|
|
I use that chip to read dip switches.
pin 1 s/L is enable(EXP_IN_ENABLE)
pin 2 clk is clock(EXP_IN_CLOCK)
pin 7 qh_bar is data(EXP_IN_DI)
(I read the inverted because the dip switch has pull-ups)
pin15 I ground
pin 9 qh goes to 10si of the next chip in the daisy-chain
on the end of the chain I pull si low with a 10k pull-down.
(i don't know if this was require tho)
I found a link. but it isn't mine
http://homepages.which.net/~paul.hills/Software/ShiftRegister/ShiftRegisterBody.html
ps: don't post code from the 74165.c file. Its copyrighted. |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Fri Apr 11, 2008 1:50 am |
|
|
treitmey wrote: | I use that chip to read dip switches.
pin 1 s/L is enable(EXP_IN_ENABLE)
pin 2 clk is clock(EXP_IN_CLOCK)
pin 7 qh_bar is data(EXP_IN_DI)
(I read the inverted because the dip switch has pull-ups)
pin15 I ground
pin 9 qh goes to 10si of the next chip in the daisy-chain
on the end of the chain I pull si low with a 10k pull-down.
(i don't know if this was require tho)
|
Many thanks treitmey, very useful information.
What happens when you have more than one 74HCT165 chip daisy chained? i.e. how do you read the n bytes from the ei array using the CCS code? |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Apr 11, 2008 7:50 am |
|
|
First the serial out of the chip(pin 9 (QH) ) goes to the serial in of the next chip (pin 10(SI)). The clock and enable are common to both chips.
You tell the driver the number of chips you have.
Any you define an array of int8 for that many chips.
And you pass the function an address to the array.
#define NUMBER_OF_74165 2
int8 ex_in[NUMBER_OF_74165];
read_expanded_inputs(&ex_in);
This way it clocks in all 16 bits of data.
I've done up to four chips,((probably can do a bunch more)) all at a cost of 3 pins.
And you can also re-use some of the 3 pins on a ex_out using 74hc595 chips. |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Fri Apr 11, 2008 8:46 am |
|
|
Ah, I can see what is going on now - thanks for the explanation. I plan to have 4 chips as well, as I have 2 rotary switches to read the position of and also 2 8-way DIP switches to read. 3 pins as opposed to 32 is a massive saving! |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Tue Apr 15, 2008 3:08 am |
|
|
Ok, I've breadboarded a demo board to test this and its almost working. I've got an 8-way switch connected to the 8 inputs of a 74HCT165 with the wiper connected to +5V. The 8 inputs are pulled low via 47k resistors. When I turn the switch I get a nice +5V on each pin, per click. This in theory should produce the following sequence: 1, 2, 4, 8, 16, 32, 64, 128.
However, I'm getting -128 displayed at the final position (should be 128 [10000000])?!
Code: |
#include <16f877A.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#include <74165.c>
#include <lcd.c>
#define GREEN_LED PIN_C7
int8 ei[8];
int8 i;
void main () {
lcd_init();
while (1)
{
read_expanded_inputs(ei); //Reads the array ei from the chips
printf(lcd_putc,"\f %d \n", ei[i]);
delay_ms (100);
}
} |
Can someone point out the deliberate mistake that I have inevitably made?!
Ed |
|
|
40inD
Joined: 30 Jul 2007 Posts: 112 Location: Moscow, Russia
|
|
Posted: Tue Apr 15, 2008 3:35 am |
|
|
I don't see where you increment i |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Tue Apr 15, 2008 3:55 am |
|
|
40inD wrote: | I don't see where you increment i |
Yes, there should be a for loop. Strange that it (almost) worked before though without it??!!
Code: | #include <16f877A.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#include <74165.c>
#include <lcd.c>
#define GREEN_LED PIN_C7
int8 ei[8];
int8 i;
void main () {
lcd_init();
while (1)
{
read_expanded_inputs(ei); //Reads the array ei from the chips
for (i=0; i<8; i++)
printf(lcd_putc,"\f %d \n", ei[i]);
delay_ms (100);
}
} |
|
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Tue Apr 15, 2008 4:31 am |
|
|
This seems to be a bit more reliable, although I'm still getting -128 when the 8th switch is selected!!
Code: | #include <16f877A.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#include <74165.c>
#include <lcd.c>
void main () {
BYTE data;
lcd_init();
do {
read_expanded_inputs (&data);
delay_ms (100);
printf(lcd_putc,"\f %d \n", data);
} while (TRUE);
} |
How would you deal with two 74HCT165s connected in series? Are two bytes passed into the array? |
|
|
40inD
Joined: 30 Jul 2007 Posts: 112 Location: Moscow, Russia
|
|
Posted: Tue Apr 15, 2008 5:43 am |
|
|
try %u instead of %d |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Tue Apr 15, 2008 5:56 am |
|
|
40inD wrote: | try %u instead of %d |
Ahh, silly mistake! Thanks, that fixed the -128 problem :-)
Any ideas for multiple chips? I now have two chips daisy chained, but somehow I need to access the two bytes in the array. I tried treitmey's suggestion above, but I can't seem to get it to work... |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Tue Apr 15, 2008 8:26 am |
|
|
here is a shell of a program to get you started.
I ran this on production hardware. It uses pins A0,1,2. All having pull-ups.
Code: |
#include <18F4620.h>
#device adc=8
#fuses hs,noprotect,nolvp,put
#use delay(clock=18432000,RESTART_WDT)
#use rs232(baud=19200,xmit=PIN_B3,invert,stream=debug)
#case
#zero_ram
#include <stdlib.h>
//========================= Defines ================================//
#define EXP_IN_CLOCK PIN_A0
#define EXP_IN_DI PIN_A1
#define EXP_IN_ENABLE PIN_A2
#define NUMBER_OF_74165 2
#include <74165.C>
#bit CREN =0xFAB.4 //18F4620
//========================= Globals =================================//
struct SN74HC165
{
int8 address;
int seconds:2;
int wieg:6;
} ex_in;
//========================= Prototypes ==============================//
void init(void);
//========================= Main ====================================//
void main(void)
{
init();
while(1)
{
read_expanded_inputs(&ex_in);
fprintf(DEBUG,"%u %u %u\n\r",ex_in.address,ex_in.seconds,ex_in.wieg);
delay_ms(1000);
}
}
//========================= Functions ==============================//
//=== init ===// setup the initial settings
void init(void)
{
int8 tmp;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
}
|
|
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Tue Apr 15, 2008 8:55 am |
|
|
Thanks treitmey, I've got this far but I'm still not getting any data out of the first chip:
Code: | #include <16f877A.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT
#use delay (clock=20000000)
#include <74165.c>
#include <lcd.c>
struct SN74165
{
int8 data;
int8 data2;
} ei;
void main () {
lcd_init();
do {
read_expanded_inputs (&ei);
delay_ms (100);
printf(lcd_putc,"\f %u %u\n", ei.data, ei.data2);
} while (TRUE);
} |
I've altered the 74165. c file to read:
Code: |
#define NUMBER_OF_74165 2
|
And:
Code: |
void read_expanded_inputs(int16 *ei)
|
|
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Tue Apr 15, 2008 11:11 am |
|
|
Normally you don't want to change the driver file. Leave it alone
The define are in a #IFDEF statement in the driver so you simply override them. Simply
#define EXP_IN_ENABLE PIN_A1 (and other #defines) in main program BEFORE the
#include<> and the driver will use your parameters.
(see my code snipit)
Also don't mess with
Quote: | void read_expanded_inputs(int16 *ei) |
Just take what is returned and use the make16() funtction. to get the type you want.
You may need to reverse the byes ie make16(array[0],array[1]) |
|
|
edhaslam
Joined: 15 Jul 2005 Posts: 89 Location: UK
|
|
Posted: Wed Apr 16, 2008 1:45 am |
|
|
Thanks for your patience treitmey.
I'll leave the original driver as is and use the defines in my main.
With regards to the make16() function - surely I need to use make8()? Doesn't the 74165 driver return a 16 bit value if two chips are used? If so, I need to split this into two 8 bit values, as I have two separate 8-way switches going into each 74HCT165. I need to monitor these two 8 bit values independantly.
[/b] |
|
|
|