Manual SN74LS165

Maybe try doing a full pulse on the CP output pin?

Code:
  CP2 = 0; CP2 = 1; CP2 = 0;
Or at least put a CP2 = 0; line before the PL = 0; PL = 1; line at the top of the routine. The way your code is now, you leave CP2 = 1 when you exit the routine (I think?). Not sure if that would cause a problem but it's easy to test...
 
Last edited:
LOL.. HAH HAH HAH YOU WONT BELIEVE THE WHAT THE PROBLEM WAS!

sorry for caps..
the issue was so dumb.. my code works fine. It was my breadboard. I need a new one lol. Thank god i have spares. I looked a tthe bottom to see if something was shorting and noticed that where the chip lays the metal bars came out lol through the double tape. I pushed it in and works 100% now lol.

Thanks a bunch Mike and kchriste a bunch!

Ill post updates.. here is a schematic i was playing with this idea. It would be nice to connect 255 switches to this 1 sn74ls165. I drew small schematic example on how t okeep connecting them.

EDIT:
Below image explained:
basically the transistor connects 2 or more lines together forming double or tripple etcc. highs

Like when you press button #9 it connects button 1 and 2 together and sets them high this way you are sending 00000011 its like pressing 1 and 2 at the same time.
 

Attachments

  • c.png
    15.6 KB · Views: 196
Last edited:
Ok final code for it: (i call it Read Parallel Load)
Code:
char readPL(void){
    char x;
    char buff;

    PL=0;  PL=1;

    for(x=0;x<8;x++){
        buff <<= 1;             // shift composed byte by 1
        buff &= 0xFE;           // clear bit 0

        if (DS)                 // is data line high
            buff |= 0x01;       // set bit 0 to logic 1

        CP2 = 0; CP2 = 1;
    }
    return buff;
}

Since im usng only 5 out of 8 possible pins i am ANDing it with 0x1F aka 0001-1111
 
Last edited:
Please dont laugh lol this code works even tho it may be a overkill on complexity.
//I can set time and all.
Hours: pressing down loops like 3,2,1,0,12,11,10 etc.. pressing up loops 10,11,12,01 etc which is perfect.

Minutes: pressing down loops 3,2,1,0,59,58 and pressing up loops like 89.59.0,1
perfect

seconds are set to zero auto.

I just need to code the alarm now. I will edit the time code to either program time registers or alarm registers without having to code the whole thing over. Simple heh.
Code:
#include <p18cxxx.h>
#include <stdio.h>
#include <delays.h>
#include <spi.h>

#pragma config WDT = OFF, LVP = OFF, OSC = HS
/***********************************
      Prototypes / Defines
***********************************/
void initSPI(void);
void e_togg(void);
void lcd_line(char line);
void lcd_cmd(unsigned char letter);
void lcd_char(unsigned char letter);
void lcd_string(char *senpoint);
void lcd_init(void);
void delay_ms(int ms);
void delay_us(int us);
void delay_s(int s);
void lcdByte(unsigned char dNyb,unsigned char rs);
char RTCRegRead(char adx);
void RTCRegWrite(char adx, char data);
char readPL(void);
void SetTime(void);

#define CS LATCbits.LATC2
#define CS_T  TRISCbits.TRISC2
#define SCL_T TRISCbits.TRISC3
#define SDA_T TRISCbits.TRISC4
#define SDO_T TRISCbits.TRISC5

#define LCD_DAT_T TRISCbits.TRISC0
#define LCD_CLK_T TRISCbits.TRISC1

#define LCD_DAT LATCbits.LATC0
#define LCD_CLK LATCbits.LATC1

#define LCD_E_T TRISCbits.TRISC6
#define LCD_E   LATCbits.LATC6

#define PL  LATBbits.LATB0
#define CP2 LATBbits.LATB1
#define DS  PORTBbits.RB2

#define PL_T  TRISBbits.TRISB0
#define CP2_T TRISBbits.TRISB1
#define DS_T  TRISBbits.TRISB2

char string[] = "                ";
unsigned char time[16];
/***********************************
            Main
***********************************/
void main(void){
    unsigned char tmp,tmp2;
    unsigned char buff[40];
    char i;

    ADCON1 = 0x0E;

    initSPI();
	lcd_init();

    PL_T = 0;
    CP2_T = 0;
    DS_T = 1;

	lcd_line(1);
	sprintf(string,"  AtomSoftTech",0);
	lcd_string(&string);

	lcd_line(2);
	sprintf(string," 2-Wire 74LS164",0);
	lcd_string(&string);

    delay_s(1);

	lcd_line(2);
	sprintf(string,"  DS1306 TEST.  ",0);
	lcd_string(&string);

    delay_s(1);

    while(1){

    tmp = RTCRegRead(0x02);
    time[15] = (tmp >> 4) & 0x02;

    if(time[15] == 0) 
        time[15] = 'A' ;
    else 
        time[15] = 'P';

    time[14] = 0x20;

    tmp = RTCRegRead(0x00);
    time[13] = (tmp & 0x0F) + 0x30;
    time[12] = ((tmp >> 4) & 0x0F ) + 0x30;
    time[11] = ':';

    tmp = RTCRegRead(0x01);
    time[10] = (tmp & 0x0F) + 0x30;
    time[9] = ((tmp >> 4) & 0x0F ) + 0x30;
    time[8] = ':';

    tmp = RTCRegRead(0x02);
    time[7] = (tmp & 0x0F) + 0x30;
    time[6] = ((tmp >> 4) & 0x01 ) + 0x30;

    time[5] = 0x20;
    time[4] = ':';
    time[3] = 'e';
    time[2] = 'm';
    time[1] = 'i';
    time[0] = 'T';

	lcd_line(2);
	lcd_string(time);

    tmp = readPL() & 0x1F;

    if(tmp == 0x08)
        SetTime();

    delay_ms(10);

    }
}

char readPL(void){
    char x;
    char buff;


    PL=0;  PL=1;

    for(x=0;x<8;x++){
        buff <<= 1;             // shift composed byte by 1
        buff &= 0xFE;           // clear bit 0

        if (DS)                 // is data line high
            buff |= 0x01;       // set bit 0 to logic 1

        CP2 = 0; CP2 = 1;
    }
    delay_ms(60);
    return buff & 0x1F;
}

void SetTime(void){
    char done;
    char hour,min,sec;
    char tmp,tmp2;

    done = 0;

    lcd_line(1);
    sprintf(string," Set Time: Hour ",0);
    lcd_string(&string);

    while(done <= 1 ){
        lcd_line(2);
	    lcd_string(&time);        
///////////////////////////////////////
        if(readPL() == 0x01){ //up
            if(done == 0){
                time[7]++;
                if (time[6] == 0x31){
                    if(time[7]==0x33){
                        time[7]=0x31;
                        time[6]=0x30;
                    } 
                }

                if(time[7] == 0x3A){
                    time[6]=0x31;
                    time[7]=0x30;
                } 

            }

            if(done == 1){
                time[10]++;
                if(time[10] >= 0x39){
                    time[10]=0x30;

                    if(time[9] >= 0x35)
                        time[9]=0x30;
                    else
                        time[9]++;
                }
            }

            time[12] = time[13] = 0x30;
            lcd_line(2);
    	    lcd_string(time);        
        }
////////////////////////////////////////
        if(readPL() == 0x02){ //down
            if(done == 0){
                time[7]--;
                if (time[6] == 0x31){
                    if(time[7]<=0x2F){
                        time[7]=0x39;
                        time[6]=0x30;
                    }
                } else {
                    if(time[7]<=0x2F){
                        time[7]=0x32;
                        time[6]=0x31;
                    }                    
                }
            }

            if(done == 1){
                if(time[10] == 0x30){
                    if(time[9] == 0x30)
                        time[9]=0x35;
                    else
                        time[9]--;

                    time[10]=0x39;
                } else {
                    time[10]--;
                }
            }
            time[12] = time[13] = 0x30;
            lcd_line(2);
    	    lcd_string(time);        
        }

///////////////////////////////////////////
        if(readPL() == 0x10){ //Set/enter
            done++;
            lcd_line(1);
            if(done == 1)
	            sprintf(string," Set Time: Min  ",0);

	        lcd_string(&string);
        }
     
    }

    tmp = time[6] - 0x30;
    tmp = tmp << 4;
    tmp2 = time[7] - 0x30;
    tmp2 = tmp | tmp2 | 0x40;
    hour = tmp2;

    tmp = time[9] - 0x30;
    tmp = tmp << 4;
    tmp2 = time[10] - 0x30;
    tmp2 = tmp | tmp2 ;
    min = tmp2;

    tmp = time[12] - 0x30;
    tmp = tmp << 4;
    tmp2 = time[13] - 0x30;
    tmp2 = tmp | tmp2 ;
    sec = tmp2;

    RTCRegWrite(0x80,sec);
    RTCRegWrite(0x81,min);
    RTCRegWrite(0x82,hour);

	lcd_line(1);
	sprintf(string,"  AtomSoftTech",0);
	lcd_string(&string);
}

char RTCRegRead(char adx){
    char tmp;
    CS = 1;
        WriteSPI(adx); //sec
        tmp = ReadSPI();
    CS = 0;

    return tmp;
}

void RTCRegWrite(char adx, char data){
    CS = 1;
    WriteSPI(adx);
    WriteSPI(data);
    CS = 0;
}
void initSPI(void){
    CS_T = 0;       //CS is output
    SCL_T = 0;      //SCL is output
    SDA_T = 1;      //SDA is input
    SDO_T = 0;      //SDO is output

    OpenSPI(SPI_FOSC_4,MODE_10,SMPEND);         //[b]Had to change to SMPEND[/b]

    CS = 1;
        WriteSPI(0x8F);
        WriteSPI(0x00);
    CS = 0;

}

void lcd_string(char *senpoint){
    delay_ms(1);
	while(*senpoint != '\0'){
		lcd_char(*senpoint);
		senpoint++;
	}
}
void lcdByte(unsigned char dNyb,unsigned char rs){
	int i;

	LCD_DAT=0;							//Clear 74LS164 set initial bit to 0
	for(i=0;i<8;i++){				    //repeat for 8 bits
		LCD_CLK=1;LCD_CLK=0;			//write 0's to the 164
	}

	for(i=0;i<4;i++){				    //output the nybble
		if((dNyb & 0x08) != 0)
			LCD_DAT=1;
		else
			LCD_DAT=0;

		LCD_CLK=1;LCD_CLK=0;
		dNyb=dNyb<<1;
	}

	LCD_DAT = rs;						    //output the RS bit value
	LCD_CLK=1;LCD_CLK=0;

	LCD_DAT = 0;
	LCD_CLK=1;LCD_CLK=0;
	LCD_CLK=1;LCD_CLK=0;
	LCD_CLK=1;LCD_CLK=0;

	e_togg();
}

void e_togg(void){
	LCD_E=1;LCD_E=0;
}
void clk_togg(void){
	LCD_CLK=1;LCD_CLK=0;
}
void lcd_line(char line){
    if(line == 0x01)
        lcd_cmd(0x80);
    else
	    lcd_cmd(0xc0);
}

void lcd_cmd(unsigned char letter){
	unsigned char temp;
	temp=letter;
	temp=temp>>4;
	lcdByte(temp,0);
	temp=letter;
	temp=temp&0x0f;
	lcdByte(temp,0);
}

void lcd_char(unsigned char letter){
	unsigned char temp;
	temp=letter;
	temp=temp>>4;
	lcdByte(temp,1);
	temp=letter;
	temp=temp&0x0f;
	lcdByte(temp,1);
}

void lcd_init(void){

    LCD_E_T = 0;
    LCD_CLK_T = 0;
    LCD_DAT_T = 0;

	lcdByte(0x03,0);
	delay_ms(5);
	e_togg();
	delay_us(160);
	e_togg();
	delay_us(160);
	lcdByte(0x02,0);
	delay_us(160);
	lcd_cmd(0x28);					//set 4-bit mode and 2 lines
	delay_us(160);
	lcd_cmd(0x10);					//cursor move & shift left
	delay_us(160);
	lcd_cmd(0x06);					//entry mode = increment
	delay_us(160);
	lcd_cmd(0x0d);					//display on - cursor blink on
	delay_us(160);
	lcd_cmd(0x01);					//clear display
	delay_ms(500);
}

void delay_s(int s){
    int y;
    char x;

    for(y=0;y<s;y++)
        for(x=0;x<4;x++)
            delay_ms(250);

}

void delay_ms(int ms){
    int y;

    for(y=0;y<ms;y++)
        Delay1KTCYx(5);
}

void delay_us(int us){
    int y;
    char x;

    for(y=0;y<us;y++)
        for(x=0;x<5;x++)
            Nop();
}

EDIT: I even forgot about the AM/PM stuff. I gota add it. It will be easy!
 
Last edited:
i did the Am/Pm stuff but the alarm and date will have to wait for another day. Im tired of thinking about this project lol. I need to relax my brain on this. Here is a so far PIC:



 

Attachments

  • Picture 021.jpg
    59.7 KB · Views: 263
  • Picture 022.jpg
    37.5 KB · Views: 256
hi atom.
Looking at your images, do the push buttons have PU or PD resistors.?
 
Last edited:
PD.. it works now tho. i have them on 4.7k pull downs so when nothing is pressed it shows as 0. I just have to replace the code:

tmp = readPL() & 0x1F;
to
tmp = readPL();

Since i put PD resistors on unused lines now.
 
PD.. it works now tho. i have them on 4.7k pull downs so when nothing is pressed it shows as 0. I just have to replace the code:

tmp = readPL() & 0x1F;
to
tmp = readPL();

Since i put PD resistors on unused lines now.

A good space saver for PU or PD are SILR's from 5 thru 9 resistors/SIL.
 
Hey again i figure i can save space and time if i learned how to take a normal number like 25 and split it into 2 numbers...

2 and 5

I had done this before but lost all info about it somehow.. I think futz or someone helped me with it.
 
A good space saver for PU or PD are SILR's from 5 thru 9 resistors/SIL.

ill be sure to get a few from dipmicro soon! thanks

about the splitting numbers. I think i have to divide like

25 / 10 = 2.5

i take the 2 but forgot how to

a better number to understand is 12 - 1100 - 0x0C

if i divide by 10 i get 1.2 which i assume would be just a 1 in binary. which is the first digit. Now how do i get the 2?
 
Last edited:

A simple way is multiply the top number by 10, so 250/10 = 25,insert the dp.

EDIT:
If you do simple program for the 25/10, you should find in one of registers or W, the 'remainder' [5]
 
Last edited:
I found this on Microchip Forum:
Code:
static unsigned int uint2bcd(unsigned int ival)
{
	return ((ival / 10) << 4) | (ival % 10);
}
i changed to:
Code:
static unsigned char uint2bcd(unsigned char ival)
{
	return ((ival / 10) << 4) | (ival % 10);
}

Works great!
 
I was thinking if i wanted to BCD to Char(decimal) couldnt i:

BCD = 0x31 (i need to make it 0x1F aka decimal 31)

I take the low nybble and loop it + 10 each loop like

Code:
char lowNyb = BCD & 0x0F;
char highNyb = BCD >> 4;
char MyDec = lowNyb;
char x;

for(x=0;x<highNyb;x++){
    MyDec += 10;    
}

so if i loop 3 times it will be 1 + 10 + 10 +10 = 31.

Of course would only work for 2 digit numbers but thats what i would need for this. The highest number i use is 99
 
Last edited:

hi,
Is this related to the DS1306 RTC programming,? if so, the DS data is 'packed' BCD.

EDIT: I do something similar for the DS1307 data.
Code:
'convt rtc packed bcd to a bin number for inc/dec usage
bcd2bin:
units = temp1 And 0x0f
tens = temp1 And 0xf0
tens = ShiftRight(tens, 4)
tens = tens * 10
temp1 = tens + units
Return
 
Last edited:
cool i need it for the same purpose to inc/dec the numbers. Its working nice now. I finished the Day, Date i just need to do Month , Year. Then tomorrow is the ALRARM.

ill make a small youtube vid in a min.
 
cool i need it for the same purpose to inc/dec the numbers. Its working nice now. I finished the Day, Date i just need to do Month , Year. Then tomorrow is the ALRARM.

ill make a small youtube vid in a min.

hi,
Going back to packed BCD from bin, I use this:

Code:
'convt the bin number to packed bcd for rtc write
bin2bcd:
tens = temp1 / 10
units = temp1 Mod 10
ascbfr1 = tens Or 0x30; these two lines are for the LCD display. ie; ASCII
ascbfr0 = units Or 0x30
tens = ShiftLeft(tens, 4)
temp1 = tens Or units
Return

BTW:
For using the +/- inc/dec 'time/date' buttons, I convert from packed BCD to binary, do the inc/dec on the binary,,, when done adjusting I use the above for bin to packed BCD, then write to the DS1307
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…