Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Manual SN74LS165

Status
Not open for further replies.
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! :D

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
    c.png
    15.6 KB · Views: 148
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:

picture-021-jpg.24758


picture-022-jpg.24759
 

Attachments

  • Picture 021.jpg
    Picture 021.jpg
    59.7 KB · Views: 206
  • Picture 022.jpg
    Picture 022.jpg
    37.5 KB · Views: 203
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:
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?

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:
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

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:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top