PIC with shift register

Want to just shoot the breeze? Forum 42 is the place!

Moderator: Moderators

Post Reply
lio
Posts: 3
Joined: Fri Sep 17, 2010 4:18 pm

PIC with shift register

Post by lio »

Hello everyone,

I'm trying to use a PIC 16F819 with a 74HC595 shift register, and I can't make it work. Here is the microC program:

#define dataPIN PORTB.f0
#define latchPIN PORTB.f1 //0 la tranmisie si 1 la afisare
#define clockPIN PORTB.f2 //1 dupa fiecare bit

void outOneByte(int dispData) {
int i;
clockPIN = 0; // pregatire transmitere date
for (i=0; i<8; i++) { //trimite cei 8 biti
if ((dispData & 0x01)== 1){
dataPIN = 1;}
else {dataPIN = 0;}
clockPIN =1;
clockPIN = 0;
dispData >> 1;
}
}

void main() {
int dispData, j;
TRISB = 0x00;
while(1){
for(j=0;j<255;j++){
dispData = j;
latchPIN = 0;
outOneByte(dispData);
latchPIN = 1;
delay_ms(500);
}
}
}

Is there anything wrong with it? Can anybody help? I'm quite new to this. Thank you in advance.

Best wishes!
Snow_Cat
Posts: 463
Joined: Fri Aug 13, 2010 12:40 pm
Steam ID: Snow_Cat
Location: Here
Contact:

Re: PIC with shift register

Post by Snow_Cat »

how exactly have you connected each pin of the 74HC595 ?
lio
Posts: 3
Joined: Fri Sep 17, 2010 4:18 pm

Re: PIC with shift register

Post by lio »

Thank you for trying to help me. Here is how I connected the pins:
PINs 8 and 13 to ground
PINs 10 and 16 to +5v
PIN 14 to RB0
PIN 12 to RB1
PIN 11 to RB2
PINs 1-7 and 9 to LEDs through resistors

I also have a .1uf capacitor between PIN 12 and ground. If I take out the capacitor, all the 8 LEDs are turning on and off together. It's like I would continuously transmit 0xFF.
Snow_Cat
Posts: 463
Joined: Fri Aug 13, 2010 12:40 pm
Steam ID: Snow_Cat
Location: Here
Contact:

Re: PIC with shift register

Post by Snow_Cat »

Okay, the hardware connections are mostly correct, the capacitor is silly.

Software
  • port b
    • TRISb (port b output enable) set
    • Option<7> !rbpu (port b pull up) is set?
    • SPI disabled?
    • Port b interrupt disabled?
  • delay_ms function/macro defined?
  • dispData >> 1
    • >> is not an assignment operator
    • did you mean to use >>=
Code
Spoiler:
edited from what lio wrote: /*
This code will drive a 74HC595 using a PIC16F819
74HC595 pins
  • 1-7 Q1-7
    8 GND
    9 Q7’ serial data output
    10 MR master reset (active LOW)
    11 SH_CP shift register clock input
    12 ST_CP storage register clock input
    13 OE output enable (active LOW)
    14 DS serial data input
    15 Q0
    16 VCC

PIC16F819 pins
  • 1-4 RA2-5
    5 VSS
    6-9 Rb0-3
    10-13 Rb4-7
    14 VDD
    15-16 RA6-7
    17-18 RA0-1

RB0 as serial data
RB2 as serial clock
RB1 as register clock

datasheets

*/

#define dataPIN PORTB.f0
#define latchPIN PORTB.f1 //74HC595 will output Q0-7 on rising edge
#define clockPIN PORTB.f2 //74HC595 will load serial bit on rising edge

/*
outOneByte loads 74HC595's shift register with dispData using port B.
*/

void outOneByte(int dispData) {
  • int i;
    clockPIN = 0; // pregatire transmitere date
    for (i=0; i<8; i++) {
    • //iterates 8 times for {0,1,2,3,4,5,6,7}
      if ((dispData & 0x01) == 1){
      • dataPIN = 1;
      }
      else {dataPIN = 0;}
      clockPIN = 1;
      clockPIN = 0;
      dispData >>= 1;// >>= is an assignment operator
    }
}

/*
main initilizes Port B then outputs 0-255 repeatedly using port B and outOneByte.
Also triggers 74HC595's latch to output Q0-7 when the shift register is full/ready.
*/

void main() {
  • int dispData, j;
    TRISB = 0x00;
    while(1){
    • for(j=0;j<255;j++){
      • dispData = j;
        latchPIN = 0;
        outOneByte(dispData);
        latchPIN = 1;
        delay_ms(500); //where is this defined? defined in IDE libary
      }
    }
}
edit: added english comments to code, encapsulated code in spoiler tags.
Last edited by Snow_Cat on Sat Sep 18, 2010 2:17 pm, edited 2 times in total.
lio
Posts: 3
Joined: Fri Sep 17, 2010 4:18 pm

Re: PIC with shift register

Post by lio »

IT WORKS!!! :D

So I didn't use the capacitor.

As for the software the mistake was ">>". That's why all the LEDs were on. I changed it to ">>=" :idea: and it works.

I didn't quite understand your questions about port B (I'm new to to this). TRISB = 0x00 sets all the pins on port B as outputs.

As for delay_ms(), this is am embeded function in microC for PIC.

I put here for reference the code that works with explanations, in case someone else is looking for a solution:

#define dataPIN PORTB.f0
#define latchPIN PORTB.f1 // 0 when transmiting and 1 for display
#define clockPIN PORTB.f2 // 1 after each bit

void outOneByte(int dispData) { // function to transmit each bit at a time
int i;
clockPIN = 0; // prepare for data transmition
for (i=0; i<8; i++) { // send 8 bits
if ((dispData & 0x01)== 1){
dataPIN = 1;}
else {dataPIN = 0;}
clockPIN =1;
clockPIN = 0;
dispData >>= 1; //here was my mistake
}
}

void main() {
int dispData, j;
TRISB = 0x00; //set port B as output
while(1){
for(j=0;j<255;j++){ //this displays numbers from 0 to 254 on 8 LEDs. As it is here bit0 is on LED8 and bit7 on LED1
dispData = j;
latchPIN = 0; //ready for transmition
outOneByte(dispData); //call the function
latchPIN = 1; //display
delay_ms(500); //pause 500ms
}
}
}

Thank you for your time and help!
Snow_Cat
Posts: 463
Joined: Fri Aug 13, 2010 12:40 pm
Steam ID: Snow_Cat
Location: Here
Contact:

Re: PIC with shift register

Post by Snow_Cat »

I've edited the above with english comments for a more detailed explination.

Aparently the microC (IDE) you are using includes a number of functions/macros, since delay_ms(int) is not a standard function, and while I was still a lab-assistant at the institute I saw many students struggle to understand why their code suddenly stopped working with a fresh install of Keil (or was it Bloodshed?). Like other common functions, unless it is defined in the IDE's library or the user's code it will fail. And it would seem that your IDE has included it for you.

The reason that I ask about !RBPU, SPI and port B interrupt is because these other peripherials share the pins on Port B and will interfere if they are not initilized properly; which can cause otherwise perfect code to fail.
However, It would seem that your IDE has initilized them for you.


It is not entirely correct to say that the clock is high for output, and low when idle in this case. The 74HC595 is edge triggered. Meaning that the data is loaded on the rising edge of the clock pulse, and changes to the input after the propagation delay(s) are irrelevant.

The sequence for loading data through the 74HC595 is:
  1. in any order
    • load shift register
      1. in any order
        • lower shift register clock
        • set next bit to load
      2. raise shift register clock/leading edge
      3. repeat until fully loaded
    • lower storage register clock
  2. raise storage register clock
  3. repeat until data is exausted
Schematic/Board art at docs.google.com2010.09.18.pdf
Spoiler:
Image
edit:replaced ordered list with unordered
Post Reply