Trao đổi về bài tập I2C

sao không được bạn code trên mình chỉ không tắt được tải thôi. nhưng giờ mình sữa lại được rồi. nó đã chạy ầm ầm. nhìn rất đẹp muốn phát triển thêm mấy cái mà chưa nghĩ ra thêm
 

nkvu

Trứng gà
sr, tìm thấy rùi, mà sao không có bài giảng TIMER1 với TIMER2 nhỉ
 

Manhdd

Cố Vấn CLB
Staff member
2 timer này tương tự timer 0. Trước chị Phương giảng trong datasheet hok à. Bạn chịu khó xem datasheet đi, nhiều chữ nên hướng dẫn kĩ càng lắm :d
 

gaubongtrang

Trứng gà
mong các bạn giải thích dùm mình dòng code này,mình hong hiểu mấy chử màu đỏ.Mình mới học lập trình nên còn gà hì.Cám ơn! {
// mang c chua cac gia tri ascii, 14 bytes
// tach BCD, lay nibble cao
c[j]=b/16+0x30;
// lay nibble thap
c[j+1]=(b-(c[j]-0x30)*16)+0x30;
j+=2;
}
 
cái này là thế này nhé: đầu tiên bạn thu từ con DS1307 về thì được 1 by mà by này 4bit cao chứa giá trị hàng chục còn 4 bit thấp chứa giá trị hàng đơn vị. đó là giá trị của mảng b. khi chia bcho 16 tức là dịch b sang trái 4 bit có phải là còn lại 4 bit cao được chuyển xuống hàng đơn vị. giống như 00110010 thì sau lệnh đó sẽ là 00000011. còn cộng thêm 0x30 thực ra là chuyển nó về mã asci2. từ một số từ 0-> 9 bạn cộng thêm 0x30 là được mã asci2 của số đó.
còn dòng đỏ thứ 2: lấy (b-(c[j]-0x30)*16) đầu tiên trong dấu ngoặc (c[j]-0x30) là đưa số asci2 thành số bình thường vì trên bạn thu được c là mã asci2. rồi nhân cho 16 tức là bạn dịch phải 4 bit chuyển số đó lên 4 bit cao (vì nó chính là giá trị 4 bit cao của b) rồi lấy b trừ cho 4 bit cao của nó sẽ ra được 4 bit thấp của nó còn 4 bit cao luc này là bằng 0000. như chuỗ trên ta sẽ có 00000010. cộng thêm 0x30 thì giống trên thôi chuyển số đó về mã asci2
 

gaubongtrang

Trứng gà
ds1307

Cám ơn bạn mình cũng hơi hiểu hì,
Tiện đây hỏi bạn phuong tuan cái này lun.Ban xem giup minh code này không set được thời gian thực. Cám ơn bạn!
Code:
/************************************************** **************
*
* Module : main.c
* Description : INT0 / PORTC toggle
* Tool : HI-TECH PIC
* Chip : 16F887
* History : 27/11/2010
*
* Author : nguyen khac phuong tuan, CLB NCKH
* Hardware notes :
* - Hardware: DONG HO THUC
* - RB0 connect with a button: Normal-1 Press-0
************************************************** **************/
 
 
/************************************************** **************
* IMPORT
************************************************** **************/
 
#include <htc.h>
#include"i2c.h"
#include"lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);
__CONFIG(BORV21);
#define _XTAL_FREQ 4000000
#define SLAVER_ADD 0x68
#define READ 1
#define WRITE 0
char time[7];
char c[14];
int a=0;
/***************************************************************
+khai bao PORT
***************************************************************/
void init_port()
{
ANSEL=0;
ANSELH=0;
TRISB=0xFF;
PORTB=0xFF;
}
/***************************************************************
+khai bao ham cai dat time
****************************************************************/
void set_time(char g[])
{
int i;
i2c_start();
i2c_write((SLAVER_ADD<<1)|WRITE);
i2c_write(0x00);
for(i=0;i<7;i++)
{
i2c_write(time[i]);
}
i2c_stop();
}
 
/***************************************************************
+khai bao ham doc time
***************************************************************/
void read_time()
{
 
int i;
//Send Start condition
i2c_start();
//Send Slave address + WRITE command
i2c_write((SLAVER_ADD<<1)|WRITE);
// ((SLAVE_ADD<<1)| WRITE) = ((0x68<<1)|0) = 0xD0
//Send register address (register of Slave – the first register need to read data)
i2c_write(0x00); //resister first
i2c_stop();
i2c_start(); // reset to read data form DS1307
i2c_write((SLAVER_ADD<<1)|READ);
for (i=0;i<6;i++)
{
time[i]= i2c_read(0); //second to time[0],...
}
time[6]=i2c_read(1); //read year and finish read
i2c_stop(); //end read
}
/*****************************************************************
+ham hien thi time
******************************************************************/
void Display(char b[])
{
int i,j=0;
// Luu y: ket qua doc tu RTC DS1307 la so BCD
// Vi du: 24giay --> Ket qua doc ve la: 0x24
// Nen phai tach chu so "2" va so "4" rieng ra de hien thi
 
// tach bcd tu mang b, luu vao mang c -------------------------//
for(i=0;i<7;i++)
{
// mang c chua cac gia tri ascii, 14 bytes
// tach BCD, lay nibble cao
c[j]=b[i]/16+0x30;
// lay nibble thap
c[j+1]=(b[i]-(c[j]-0x30)*16)+0x30;
j+=2;
}
//--------------- hien thi tren lcd ---------------------------//
 
lcd_clear();
lcd_puts("Thu ");
if(c[7]==0x31)
lcd_puts("CN");
else
lcd_putc(c[7]); // thu trong tuan
lcd_puts(", ");
lcd_putc(c[8]); // ngay
lcd_putc(c[9]);
lcd_puts("/");
lcd_putc(c[10]); // thang
lcd_putc(c[11]);
lcd_puts("/");
lcd_putc(c[12]); // nam
lcd_putc(c[13]);
//lcd_puts("\r\n"); // xuong hang
lcd_gotoxy(0,1);
 
lcd_puts(" ");
lcd_putc(c[4]); // gio
lcd_putc(c[5]);
lcd_puts(" : ");
lcd_putc(c[2]); // phut
lcd_putc(c[3]);
lcd_puts(" : ");
lcd_putc(c[0]); // giay
lcd_putc(c[1]);
} 
/***************************************************************
+kiem tra nut nhan
****************************************************************/
void nutnhan_RB0() //nhan RB0 de vao menu cai dat thoi gian
{
if(RB0==0)
{
__delay_ms(190);
__delay_ms(190);
hoirb0: if(RB0==1)
a+=1;
else
goto hoirb0;
__delay_ms(190);
__delay_ms(190);
}
}
void nutnhan_RB1()
{
len: Display(time); //hien thi time hien tai
if(RB1==0) //kiem tra nut nhan tang giam time 
{
hoirb1: if(RB1==1) //doi RB1=1
{
__delay_ms(190);
__delay_ms(190);
switch(a)
{
case 1: //a=1 chinh trong so thap cua giay
time[0]=time[0]+1;
if((time[0]&0x0f)==10)
time[0]=(time[0]&0xf0);
nutnhan_RB0();
goto len;
case 2: //a=2 chinh trong so cao cua giay
time[0]=time[0]+0x10;
if(time[0]/16==6)
time[0]=(time[0]&0x0f);
nutnhan_RB0();
goto len;
case 3: //a=3 chinh trong so thap cua phut
time[1]+=1;
if((time[1]&0x0f)==10)
time[1]=(time[1]&0xf0);
nutnhan_RB0();
goto len;
case 4: //a=4 chinh trong so cao cua phut
time[1]=time[1]+0x10;
if(time[1]/16==6)
time[1]=(time[1]&0x0f);
nutnhan_RB0();
goto len;
case 5: //a=5 chinh trong so thap cua gio
time[2]+=1;
if((time[2]&0x0f)==10)
time[2]=(time[2]&0xf0);
nutnhan_RB0();
goto len;
case 6: //a=6 chinh trong so cao cua gio
time[2]=time[2]+0x10;
if(time[2]/16==3)
time[2]=(time[2]&0x0f);
nutnhan_RB0();
goto len;
case 7: //a=7 chinh thu 
time[3]+=1;
if(time[3]==8)
time[3]=1;
nutnhan_RB0();
goto len;
case 8: //a=8 chinh trong so thap cua ngay
time[4]+=1;
if((time[4]&0x0f)==10)
time[4]=(time[4]&0xf0);
nutnhan_RB0();
goto len;
case 9: //a=9 chinh trong so cao cua ngay
time[4]=time[4]+0x10;
if((time[4]/16)==4)
time[4]=(time[4]&0x0f);
nutnhan_RB0();
goto len;
case 10: //a=10 chinh trong so thap cua thang
time[5]+=1;
if((time[5]&0x0f)==10)
time[5]=(time[5]&0xf0);
nutnhan_RB0();
goto len;
case 11: //a=11 chinh trong so cao cua thang
time[5]=time[5]+0x10;
if((time[5]/16)==2)
time[5]=(time[5]&0x0f);
nutnhan_RB0();
goto len;
case 12: //a=12 chinh trong so thap cua nam
time[6]+=1;
if((time[6]&0x0f)==10)
time[6]=(time[6]&0xf0);
nutnhan_RB0();
goto len;
case 13: //a=13 chinh trong so cao cua nam
time[6]=time[6]+0x10;
if((time[6]/16)==10)
time[6]=(time[6]&0x0f);
lcd_puts("a=13");
__delay_ms(190);
__delay_ms(190);
__delay_ms(190);
case 14: //a=14 thoat khoi trang thai hieu chinh
set_time(time);
a=0;
return;
}
} 
else
goto hoirb1;
}
}
 
 
 
/***********************************************************
+HAM MAIN
************************************************************/
void main(void)
{
int i;
lcd_init();
i2c_init();
init_port();
__delay_ms(150);
lcd_puts(" DE CAI DAT TIME");
lcd_gotoxy(2,1);
lcd_puts("NHAN PORTRB0");
loop: nutnhan_RB0();
if (a==0)
goto loop;
time[i]=0;
while(1)
{
nutnhan_RB1();
Display(time);
if(a==0)
read_time();
nutnhan_RB0();
__delay_ms(100);
__delay_ms(100);
}
}
 
ok cái này là code của mình viết và đã tex chạy rất ok nhưng mình cũng đã có một code khác có luôn cài đặt thời gian và hẹn giờ bật tải cũng đã chạy rất ok. nếu bạn cần thì khi khác mình đưa lên. code trên bạn nhấn RB0 để vào chế độ cài đặt RB1 để tăng giá trị thời gian và RB0 cũng là control điều khiển đến vị trí cần chỉnh nhưng nó chỉ chạy lên thôi không thể giảm được. chúc bạn thành công
 
đây là code hoàn chỉnh có hẹn giờ bật tắt tải
Code:
/*
* Module : main.c
* Description : INT0 / PORTC toggle
* Tool : HI-TECH PIC
* Chip : 16F887
* History : 27/11/2010
* Author : nguyen khac phuong tuan, CLB NCKH
* Hardware notes :
* - Hardware: DONG HO THUC
**/
#include <htc.h>
#include"i2c.h"
#include"lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);
__CONFIG(BORV21);
#define _XTAL_FREQ 4000000
#define SLAVER_ADD 0x68
#define READ 1
#define WRITE 0
char time[7];
char c[14];
char t1,t2,t3=25,t4,t5,t6=25,t7,t8,t9=25,t10,t11,t12=25,t13,t14,t15=25,h1,h2,h3,h4,h5;
int a=0;
int t=0;
int k=0,i=0;
/******
+khai bao PORT
*******/
void init_port()
{
	ANSEL=0;
	ANSELH=0;
	TRISA=0xFF;
	TRISB=0x00;
	PORTB=0x00;
}
/********
+khai bao ham cai dat time
*******/
void set_time(char g[])
{
	int i;
	i2c_start();
	i2c_write((SLAVER_ADD<<1)|WRITE);
	i2c_write(0x00);
	for(i=0;i<7;i++)
	{
		i2c_write(time[i]);
	}
	i2c_stop();
}

/******
+khai bao ham doc time
*****/
void read_time()
{
int i;
		//Send Start condition
	i2c_start();
	//Send Slave address + WRITE command
	i2c_write((SLAVER_ADD<<1)|WRITE);
	//   ((SLAVE_ADD<<1)| WRITE) = ((0x68<<1)|0) = 0xD0
	//Send register address (register of Slave – the first register need to read data)
	i2c_write(0x00);									//resister first
	i2c_stop();
	i2c_start();										// reset to read data form DS1307
	i2c_write((SLAVER_ADD<<1)|READ);
	for (i=0;i<6;i++)
		{
			time[i]= i2c_read(0); 						//second to time[0],...
		}
	time[6]=i2c_read(1); 								//read year and finish read
	i2c_stop();											//end read
}
/*******
+ham hien thi time
*******/
void Display(char b[])
{
	int i,j=0;
// Luu y: ket qua doc tu RTC DS1307 la so BCD
// Vi du: 24giay --> Ket qua doc ve la: 0x24
// Nen phai tach chu so "2" va so "4" rieng ra de hien thi

// tach bcd tu mang b, luu vao mang c -------------------------//
	for(i=0;i<7;i++)
	{
// mang c chua cac gia tri ascii, 14 bytes
// tach BCD, lay nibble cao
	c[j]=b[i]/16+0x30;
// lay nibble thap
	c[j+1]=(b[i]-(c[j]-0x30)*16)+0x30;
	j+=2;
	}
//----------- hien thi tren lcd -------------------//
	
	lcd_gotoxy(0,0);
	lcd_puts("Thu ");
	if(c[7]==0x31)
		lcd_puts("CN");
	else
		lcd_putc(c[7]); // thu trong tuan
	lcd_puts(". ");
	lcd_putc(c[8]); // ngay
	lcd_putc(c[9]);
	lcd_puts("/");
	lcd_putc(c[10]); // thang
	lcd_putc(c[11]);
	lcd_puts("/");
	lcd_putc(c[12]); // nam
	lcd_putc(c[13]);
	if(t!=0)
		lcd_gotoxy(0,1);
	if(t==0)
		lcd_gotoxy(2,1);
	lcd_putc(c[4]); // gio
	lcd_putc(c[5]);
	lcd_puts(" : ");
	lcd_putc(c[2]); // phut
	lcd_putc(c[3]);
	lcd_puts(" : ");
	lcd_putc(c[0]); // giay
	lcd_putc(c[1]);
	if (t!=0)
	{
		if (a)
		{	
			lcd_gotoxy(13,1);
			lcd_putc(a/10+0x30);
			lcd_putc(a%10+0x30);
		}	
			lcd_gotoxy(15,1);		
			lcd_putc(t+0x30);
	}
	}
void settime()
{
		switch(t)
					{
						case 1:
							{
								set_time(time);
								break;
							}
						case 2:
							{	
								t1=time[0];
								t2=time[1];
								t3=time[2];
								k=1;
								
								if(t2==0x59)
									h5=0x00;
								else if((t2&0x0f)<0x09)
									h5=t2+1;
								else
								{
									h5=(t2&0xf0)+0x10;
								}
								break;	
							}
						case 3:
							{
								t4=time[0];
								t5=time[1];
								t6=time[2];
								k=1;
								if((t4&0x0f)<0x05)
									h1=t4+5;
								else
								{
									if((t4&0xf0)==0x50)
										h1=(t4&0x0f)-5;
									else
										h1=t4+0x10-5;
								}
								break;
							}
						case 4:
							{
								t7=time[0];
								t8=time[1];
								t9=time[2];
								k=1;
								if((t7&0x0f)<0x05)
									h2=t7+5;
								else
								{
									if((t7&0xf0)==0x50)
										h2=(t7&0x0f)-5;
									else
										h2=t7+0x10-5;
								}
								break;
							}
						case 5:
							{
								t10=time[0];
								t11=time[1];
								t12=time[2];
								k=1;
								if((t10&0x0f)<0x05)
									h3=t10+5;
								else
								{
									if((t10&0xf0)==0x50)
										h3=(t10&0x0f)-5;
									else
										h3=t10+0x10-5;
								}
								break;
							}
						case 6:
							{
								t13=time[0];
								t14=time[1];
								t15=time[2];
								k=1;
								if((t13&0x0f)<0x05)
									h4=t13+5;
								else
								{
									if((t13&0xf0)==0x50)
										h4=(t13&0x0f)-5;
									else
										h4=t13+0x10-5;
								}
								break;
							}
					}	
}	
/********
+kiem tra nut nhan
********/
void nutnhan_RA0()										//nhan RA0 de vao menu cai dat thoi gian
{
	if(RA0==0)
	{
		do
		{
			__delay_ms(100);
			if (RA0==1)
			{
				t+=1;
				if(t==1)
					lcd_clear();
				else if(t==7)
				{
					lcd_clear();
					t=0;
					a=0;
				}
			}
		}
		while(RA0==0);
	}
}
void nutnhan_RA1()										//nhan RA1 de vao menu cai dat thoi gian
{

	if(RA1==0)
	{
		do
		{	
			__delay_ms(100);
		 	if(RA1==1)
				a+=1;	
		}
		while(RA1==0);
	}
}
void nutnhan_RA2()
{									//hien thi time hien tai										
	 if(RA2==0)											//kiem tra nut nhan tang giam time	
	{
		do
		{
			__delay_ms(100);
			if(RA2==1)									
			{
				switch(a)
				{
				case 1:										//a=1 chinh trong so thap cua giay
					time[0]+=1;
					if((time[0]&0x0f)==10)
						time[0]=(time[0]&0xf0);
					break;
				case 2:										//a=2 chinh trong so cao cua giay
					time[0]=time[0]+0x10;
					if(time[0]/16==6)
						time[0]=(time[0]&0x0f);
					break;
				case 3:										//a=3 chinh trong so thap cua phut
					time[1]+=1;
					if((time[1]&0x0f)==10)
						time[1]=(time[1]&0xf0);
					break;
				case 4:										//a=4 chinh trong so cao cua phut
					time[1]=time[1]+0x10;
					if(time[1]/16==6)
						time[1]=(time[1]&0x0f);
					break;
				case 5:										//a=5 chinh trong so thap cua gio
					time[2]+=1;
					if((time[2]&0x0f)==10)
						time[2]=(time[2]&0xf0);
					break;
				case 6:										//a=6 chinh trong so cao cua gio
					time[2]=time[2]+0x10;
					if(time[2]/16==3)
						time[2]=(time[2]&0x0f);
					break;
				case 7:										//a=7 chinh thu 
					time[3]+=1;
					if(time[3]==8)
						time[3]=1;
					break;
				case 8:									//a=8 chinh trong so thap cua ngay
					time[4]+=1;
					if((time[4]&0x0f)==10)
						time[4]=(time[4]&0xf0);
					break;
				case 9:										//a=9 chinh trong so cao cua ngay
					time[4]=time[4]+0x10;
					if((time[4]/16)==4)
						time[4]=(time[4]&0x0f);
					break;
				case 10:										//a=10 chinh trong so thap cua thang
					time[5]+=1;
					if((time[5]&0x0f)==10)
						time[5]=(time[5]&0xf0);
					break;
				case 11:										//a=11 chinh trong so cao cua thang
					time[5]=time[5]+0x10;
					if((time[5]/16)==2)
						time[5]=(time[5]&0x0f);
					break;
				case 12:										//a=12 chinh trong so thap cua nam
					time[6]+=1;
					if((time[6]&0x0f)==10)
						time[6]=(time[6]&0xf0);
					break;
				case 13:										//a=13 chinh trong so cao cua nam
					time[6]=time[6]+0x10;
					if((time[6]/16)==10)
						time[6]=(time[6]&0x0f);
					break;
				case 14:										//a=14 thoat khoi trang thai hieu chinh
					settime();
					a=0;
					t=0;
					lcd_clear();
					break;
				}
			}		
		}
		while(RA2==0);
	}
	else if(a==15)
	{
		a=0;
		t=0;
		lcd_clear();
	}
}
void sosanh()
{
	if(time[2]==t3)
	{
		if((time[1]==t2)&&(time[0]==t1))
		{
			RB0=1;
			i=1;
		}
		else if((time[1]==h5)&&(time[0]==t1))
		{
			RB0=0;
			i=0;
		}
	}
	if(time[2]==t6)
	{
		if(time[1]==t5)
		{
			if(time[0]==t4)
			{
				RB0=1;
				RB1=1;
				i=2;
			}
			else if(time[0]==h1)
			{
				RB0=0;
				i=0;
			}
		}
		else if(time[1]==t5+1)
		{
			if(time[0]==h1)
			{
				RB0=0;
				i=0;
			}
		}
		
	}
	else if(t5==0x59)
	{
		if(time[1]==0x00)
		{
			if(time[0]==h1)
			{
				RB0=0;
				i=0;
			}
		}
	}
	if	(time[2]==t9)
	{
		if(time[1]==t8)
		{
			if(time[0]==t7)
			{
				RB0=1;
				RB2=1;
				i=3;
			}
			else if(time[0]==h2)
			{
				RB0=0;
				i=0;
			}
		}
		else if(time[1]==t8+1)
		{
			if(time[0]==h2)
			{
				RB0=0;
				i=0;
			}
		}
	}
	else if(t9==0x59)
	{
		if(time[1]==0x00)
		{
			if(time[0]==h2)
			{
				RB0=0;
				i=0;
			}
		}
	}
	if(time[2]==t12)
	{
		if(time[1]==t11)
		{
			if((time[0]==t10))
			{
				RB0=1;
				RB1=0;
				i=4;
			}
			else if(time[0]==h3)
			{
				RB0=0;
				i=0;
			}
		}
		else if(time[1]==t11+1)
		{
			if(time[0]==h3)
			{
				RB0=0;
				i=0;
			}
		}
	}
	else if(t12==0x59)
	{
		if(time[1]==0x00)
		{
			if(time[0]==h3)
			{
				i=0;
				RB0=0;
			}
		}
	}
	if(time[2]==t15)
	{
		if(time[1]==t14)
		{
		 	if(time[0]==t13)
			{
				RB0=1;
				RB2=0;
				i=5;
			}
			else if(time[0]==h4)
			{
				RB0=0;
				i=0;
			}
		}
		else if(time[1]==t14+1)
		{
			if(time[0]==h4)
			{
				RB0=0;
				i=0;
			}
		}
	}
	else if(t14==0x59)
	{
		if(time[1]==0x00)
		{
			if(time[0]==h4)
			{
				RB0=0;
				i=0;
			}
		}
	}
}

/********
+HAM MAIN
********/
void main(void)
{
	lcd_init();
	i2c_init();
	init_port();
	__delay_ms(150);
	while(1)
	{
		nutnhan_RA0();
		nutnhan_RA1();
		nutnhan_RA2();
		Display(time);
		if(t==0)
		{
			a=0;
			read_time();
			if(k==1)
			{
				sosanh();
			}
		}
		if(i==1)
		{
			RB0=1;
			__delay_ms(50);
			RB0=0;
			__delay_ms(25);
		}
		else if(i==2)
		{
			RB0=1;
			__delay_ms(75);
			RB0=0;
			__delay_ms(50);
		}
		else if(i==3)
		{
			RB0=1;
			__delay_ms(75);
			RB0=0;
			__delay_ms(50);
		}
		else if(i==4)
		{
			RB0=1;
			__delay_ms(100);
			RB0=0;
			__delay_ms(75);
		}
		else if(i==5)
		{
			RB0=1;
			__delay_ms(100);
			RB0=0;
			__delay_ms(75);
		}	
	}
}
 

gaubongtrang

Trứng gà
Bạn Phương Tuấn cho mình hỏi khi bạn test đoạn code bên dưới thì khi tắt nguồn và ở lên lại thì nó có lưu thời gian không.
Mình test thử nhưng khi reset lại thì phải cài lại thời gian. Bạn xem dùm cám ơn!
Code:
///************************************************** **************
*
* Module : main.c
* Description : INT0 / PORTC toggle
* Tool : HI-TECH PIC
* Chip : 16F887
* History : 27/11/2010
*
* Author : nguyen khac phuong tuan, CLB NCKH
* Hardware notes :
* - Hardware: DONG HO THUC
* - RB0 connect with a button: Normal-1 Press-0
************************************************** **************/
 
 
/************************************************** **************
* IMPORT
************************************************** **************/
 
#include <htc.h>
#include"i2c.h"
#include"lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & DUNPROTECT & BORDIS & IESODIS & FCMDIS & LVPDIS);
__CONFIG(BORV21);
#define _XTAL_FREQ 4000000
#define SLAVER_ADD 0x68
#define READ 1
#define WRITE 0
char time[7];
char c[14];
int a=0;
/***************************************************************
+khai bao PORT
***************************************************************/
void init_port()
{
ANSEL=0;
ANSELH=0;
TRISB=0xFF;
PORTB=0xFF;
}
/***************************************************************
+khai bao ham cai dat time
****************************************************************/
void set_time(char g[])
{
int i;
i2c_start();
i2c_write((SLAVER_ADD<<1)|WRITE);
i2c_write(0x00);
for(i=0;i<7;i++)
{
i2c_write(time[i]);
}
i2c_stop();
}
 
/***************************************************************
+khai bao ham doc time
***************************************************************/
void read_time()
{
 
int i;
//Send Start condition
i2c_start();
//Send Slave address + WRITE command
i2c_write((SLAVER_ADD<<1)|WRITE);
// ((SLAVE_ADD<<1)| WRITE) = ((0x68<<1)|0) = 0xD0
//Send register address (register of Slave – the first register need to read data)
i2c_write(0x00); //resister first
i2c_stop();
i2c_start(); // reset to read data form DS1307
i2c_write((SLAVER_ADD<<1)|READ);
for (i=0;i<6;i++)
{
time[i]= i2c_read(0); //second to time[0],...
}
time[6]=i2c_read(1); //read year and finish read
i2c_stop(); //end read
}
/*****************************************************************
+ham hien thi time
******************************************************************/
void Display(char b[])
{
int i,j=0;
// Luu y: ket qua doc tu RTC DS1307 la so BCD
// Vi du: 24giay --> Ket qua doc ve la: 0x24
// Nen phai tach chu so "2" va so "4" rieng ra de hien thi
 
// tach bcd tu mang b, luu vao mang c -------------------------//
for(i=0;i<7;i++)
{
// mang c chua cac gia tri ascii, 14 bytes
// tach BCD, lay nibble cao
c[j]=b[i]/16+0x30;
// lay nibble thap
c[j+1]=(b[i]-(c[j]-0x30)*16)+0x30;
j+=2;
}
//--------------- hien thi tren lcd ---------------------------//
 
lcd_clear();
lcd_puts("Thu ");
if(c[7]==0x31)
lcd_puts("CN");
else
lcd_putc(c[7]); // thu trong tuan
lcd_puts(", ");
lcd_putc(c[8]); // ngay
lcd_putc(c[9]);
lcd_puts("/");
lcd_putc(c[10]); // thang
lcd_putc(c[11]);
lcd_puts("/");
lcd_putc(c[12]); // nam
lcd_putc(c[13]);
//lcd_puts("\r\n"); // xuong hang
lcd_gotoxy(0,1);
 
lcd_puts(" ");
lcd_putc(c[4]); // gio
lcd_putc(c[5]);
lcd_puts(" : ");
lcd_putc(c[2]); // phut
lcd_putc(c[3]);
lcd_puts(" : ");
lcd_putc(c[0]); // giay
lcd_putc(c[1]);
} 
/***************************************************************
+kiem tra nut nhan
****************************************************************/
void nutnhan_RB0() //nhan RB0 de vao menu cai dat thoi gian
{
if(RB0==0)
{
__delay_ms(190);
__delay_ms(190);
hoirb0: if(RB0==1)
a+=1;
else
goto hoirb0;
__delay_ms(190);
__delay_ms(190);
}
}
void nutnhan_RB1()
{
len: Display(time); //hien thi time hien tai
if(RB1==0) //kiem tra nut nhan tang giam time 
{
hoirb1: if(RB1==1) //doi RB1=1
{
__delay_ms(190);
__delay_ms(190);
switch(a)
{
case 1: //a=1 chinh trong so thap cua giay
time[0]=time[0]+1;
if((time[0]&0x0f)==10)
time[0]=(time[0]&0xf0);
nutnhan_RB0();
goto len;
case 2: //a=2 chinh trong so cao cua giay
time[0]=time[0]+0x10;
if(time[0]/16==6)
time[0]=(time[0]&0x0f);
nutnhan_RB0();
goto len;
case 3: //a=3 chinh trong so thap cua phut
time[1]+=1;
if((time[1]&0x0f)==10)
time[1]=(time[1]&0xf0);
nutnhan_RB0();
goto len;
case 4: //a=4 chinh trong so cao cua phut
time[1]=time[1]+0x10;
if(time[1]/16==6)
time[1]=(time[1]&0x0f);
nutnhan_RB0();
goto len;
case 5: //a=5 chinh trong so thap cua gio
time[2]+=1;
if((time[2]&0x0f)==10)
time[2]=(time[2]&0xf0);
nutnhan_RB0();
goto len;
case 6: //a=6 chinh trong so cao cua gio
time[2]=time[2]+0x10;
if(time[2]/16==3)
time[2]=(time[2]&0x0f);
nutnhan_RB0();
goto len;
case 7: //a=7 chinh thu 
time[3]+=1;
if(time[3]==8)
time[3]=1;
nutnhan_RB0();
goto len;
case 8: //a=8 chinh trong so thap cua ngay
time[4]+=1;
if((time[4]&0x0f)==10)
time[4]=(time[4]&0xf0);
nutnhan_RB0();
goto len;
case 9: //a=9 chinh trong so cao cua ngay
time[4]=time[4]+0x10;
if((time[4]/16)==4)
time[4]=(time[4]&0x0f);
nutnhan_RB0();
goto len;
case 10: //a=10 chinh trong so thap cua thang
time[5]+=1;
if((time[5]&0x0f)==10)
time[5]=(time[5]&0xf0);
nutnhan_RB0();
goto len;
case 11: //a=11 chinh trong so cao cua thang
time[5]=time[5]+0x10;
if((time[5]/16)==2)
time[5]=(time[5]&0x0f);
nutnhan_RB0();
goto len;
case 12: //a=12 chinh trong so thap cua nam
time[6]+=1;
if((time[6]&0x0f)==10)
time[6]=(time[6]&0xf0);
nutnhan_RB0();
goto len;
case 13: //a=13 chinh trong so cao cua nam
time[6]=time[6]+0x10;
if((time[6]/16)==10)
time[6]=(time[6]&0x0f);
lcd_puts("a=13");
__delay_ms(190);
__delay_ms(190);
__delay_ms(190);
case 14: //a=14 thoat khoi trang thai hieu chinh
set_time(time);
a=0;
return;
}
} 
else
goto hoirb1;
}
}
 
 
 
/***********************************************************
+HAM MAIN
************************************************************/
void main(void)
{
int i;
lcd_init();
i2c_init();
init_port();
__delay_ms(150);
lcd_puts(" DE CAI DAT TIME");
lcd_gotoxy(2,1);
lcd_puts("NHAN PORTRB0");
loop: nutnhan_RB0();
if (a==0)
goto loop;
time[i]=0;
while(1)
{
nutnhan_RB1();
Display(time);
if(a==0)
read_time();
nutnhan_RB0();
__delay_ms(100);
__delay_ms(100);
}
}
 
uhm chắc là không vì code đó mình viết lâu rồi nên cũng không nhớ nữa. sau này mình có sữa lại. để khi bi reset không phải cài đặt lại thời gian thì bạn thêm các dòng lệnh này nhé.
ở đoạn
Code:
loop: nutnhan_RB0();
if (a==0)
goto loop;
bạn sữa lại thành:
Code:
loop: nutnhan_RB0();
nutnhan_RB1();
if(t=!0)
a=15;
if (a==0)
goto loop;
và trong hàm nhutnhan_RB1()
bạn thêm hai lệnh case này vào
Code:
case 0
{
t=1;
break;
}
case 15
{
a=0;
break;
}
mà các code trên bạn nên thay các lệnh goto lại thành các lệnh khác có thể là do{ } while() cho chính xác chứ dùng lệnh goto không được khuyến khích nhiều. code ít thì còn được chứ nhiều có thể trình dịch sẽ dịch sai.
mà bạn nhớ lần sau viết code thi nên để trong thẻ code nhé cho dễ đọc và nhìn có thẩm mỹ. cảm ơn bạn nhiều
 

gaubongtrang

Trứng gà
bạn phương tuấn ơi cho mình hỏi dòng màu đỏ bên dưới có phải a=1 hong.Bạn xem dùm cám ơn!
HTML:
case 0
{
[COLOR="red"]t=1;[/COLOR]// chổ này là a=1 đúng hong.
break;
}
case 15
{
a=0;
break;
}
 
không bạn đó là t=1; để hàm main() mình có kiểm tra nếu t=1 thì cho a=15 để thoát khỏi vòng lặp sau khi gọi lại hàm nút nhấn thì a=0; mà cái code đó còn nhiều cái lũng cũng lắm bạn nên lấy cái code sau cùng mà mình post lên ấy bài đó đã hoàn chỉnh và có thêm vài chức năng nữa, bạn có thể chỉnh lại cho phù hợp
 

Leo_Asus

Trứng gà
Phương Tuấn có thể post file mô phỏng code hoàn chỉnh có hẹn giờ bật tắt tải được không ? Mình mô phỏng nhưng ko chạy.
 

Leo_Asus

Trứng gà
Mình tìm rồi bạn ơi, không có file nào hết.Quả thật mình còn thắc mắc về vụ nút nhấn nên cần file mô phỏng Proteus của bạn để kiểm tra.Mong bạn up lên forum.Thanks
 

Leo_Asus

Trứng gà
Không biết file Proteus của Phương Tuấn sao nhưng mình dùng code đó để điều chỉnh thời gian thì có chút không hợp lí,tháng ta có thể điều chỉnh lên 13,tương tự giây và phút cũng sao đấy ?
 
ý của bạn sao mình vẫn chưa hiểu. mình chỉ up code thôi bạn còn mô phỏng thì mình ko có. từ lâu rồi mình không dùng mô phỏng mà bài đó mình làm mạch luôn và chạy rất ok. ở trong đó phần chú thích không đúng để khi nào mình sửa lại cho mọi người dễ đọc.
 
Top