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

eMagic

Gà mẹ
Staff member
Không thể thế được, nếu bạn phương tuấn cũng bị trường hợp trên thì chính xác là trường hợp thứ 3, hiện giờ em có biết mấy bạn đang code đi code lại bài của mình nhưng vẫn hiện ??
 

2death

Cố Vấn CLB
Staff member
Mấy bạn kêu bạn Hồng Khiêm post code lên đi, không "trong sáng" lắm cũng được :D
 

eMagic

Gà mẹ
Staff member
Chị ơi Khiêm cũng đang bị rờ tay vào phần cứng nó mới chạy, code đó dễ mà, em thấy ai cũng chạy được hết! Nhưng em thấy có 5 trường hợp phải chạm tay vào SCL nó mới chạy!
 

Lee

Cố Vấn CLB
Staff member
Oh, tự nhiên ngồi vu vơ, anh nghĩ ra 1 chuyện hơi bị vui vui. Có khi nào em quên bật swicht cho điện trở kéo lên. Khi chạm tay vô thì em vô tình thành con điện trở . :D
 

2death

Cố Vấn CLB
Staff member
Sao nghi mấy đứa này cắm lộn bus quá. Trên mạch MainPic có tới mấy chỗ có thể cắm bus được, suy nghĩ cho kĩ rồi hãy cắm :D, chỗ header 2x2 nó ngắt cái chân I2C ra rồi đó, cắm bus 1 bên thì được, cắm bên kia thì không có tác dụng gì đâu.
- Nếu cắm đúng dây rồi thì kiểm tra xem đã bật công tắc kéo trở lên chưa? Nếu bật rồi thì lấy VOM đo thử xem mấy chân đó có ăn nhau không?
 
em cũng không biết nữa. ngồi suốt bổi chiều với buổi tối mà vẫn không tìm ra được nguyên nhân.
PHP:
/************************************************** **************
*
* 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: PORTC connect LEDs.
* - 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
unsigned char time[6];
 char c[14];
/************************************************** **************
* EXTERN
************************************************** **************/

/*none...*/

/************************************************** ***************
GLOBAL VARIABLE
************************************************** ****************/

/*none...*/

/************************************************** ***************
* ROUTINES
************************************************** ****************/

/* -- void init_port(void) --------------------------------------
*
* Description : disable all analog pins, init PORTC as output .
* Parameters : none
* Return : don't care
*/
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]);
}
void set_time()
{
	//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_write(0x58);//set second
	i2c_write(0x59);//set minute, auto register ++ (0x01)|
	i2c_write(0x23);//set hour
	i2c_write(0x07);//set day
	i2c_write(0x31);//set date
	i2c_write(0x12);//set month
	i2c_write(0x34);//set year
	i2c_stop();
}

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
}


/************************************************** **************
* MAIN
************************************************** **************/

/* -- void main (void) -----------------------------------------
*
* Description : INT0 Interrupt control.
* Parameters : none
* Return : don't care
* Notes :
*/

void main(void)
{
lcd_init();
i2c_init();
__delay_ms(150);
lcd_putc(6);
set_time();
__delay_ms(150);
while(1)
{
      lcd_putc(6);
      read_time();
      Display(time);
     __delay_ms(100);
     __delay_ms(100);
}
}
 
mấy chân đó ăn hết rồi chị ơi điện trở kéo lên cũng ok. nhưng nó vẫn vậy. còn của em thì có thêm hiện tượng không cài đặt năm còn lại thì đều cài dặt được. hôm trước thấy hiện toàn dấu ?? em tưởng con của em đã đai rồi chứ
 

eMagic

Gà mẹ
Staff member
Oh, tự nhiên ngồi vu vơ, anh nghĩ ra 1 chuyện hơi bị vui vui. Có khi nào em quên bật swicht cho điện trở kéo lên. Khi chạm tay vô thì em vô tình thành con điện trở . :D
-đã switch on/off (gạc qua lại) nhưng hok có tác dụng, chứ hok có ngây thơ đến mức đó đâu anh!
Sao nghi mấy đứa này cắm lộn bus quá. Trên mạch MainPic có tới mấy chỗ có thể cắm bus được, suy nghĩ cho kĩ rồi hãy cắm :D, chỗ header 2x2 nó ngắt cái chân I2C ra rồi đó, cắm bus 1 bên thì được, cắm bên kia thì không có tác dụng gì đâu.
- Nếu cắm đúng dây rồi thì kiểm tra xem đã bật công tắc kéo trở lên chưa? Nếu bật rồi thì lấy VOM đo thử xem mấy chân đó có ăn nhau không?
- Chưa thử dùng I2C port trên main PIC, chỉ kéo bus rồi on switch thôi chị.
- Em cũng nghĩ điện trở kéo nguồn có vấn đề, em sẽ cố gắng tìm ra nguyên nhân.
- Cám ơn các anh chị giúp đỡ.
 
theo như mình nghĩ thì không phải là do điện trở. vì nếu do điện trở thì chạm vào bên mainpic và bên ds1307 thì đều giao tiếp được nhưng ở đây chỉ cham vào bên ds1307 thì mới được thôi
 

hongkhiem1990

Trứng gà
pó tay luôn rồi,hok biết mạch I2C có bị lỗi gì hok mà khi lấy da tay ấn vào 2 chân SCL & SDA thì nó mới hiện ngày giờ lên LCD còn thả ra là nó hiện toàn dấu "???"
anh em có ai tìm ra đc lỗi này chưa thì cho ý kiến ngen!!
còn đây là code đã test ok trên lớp:
PHP:
#include <htc.h>
#include "i2c.h"
#include "lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word

__CONFIG(BORV21); //2st config. Word

#define _XTAL_FREQ 	4000000 //t?n s? th?ch anh 4Mhz

// DS1307 7-bit address =  0b 110 1000 = 0x68
#define 	SLAVE_ADD	0x68	
#define 	READ		1
#define	   WRITE		0
char b[7];
char c[14];
void set_time()
{
 	i2c_start();
	i2c_write((SLAVE_ADD<<1)|WRITE);
	i2c_write(0X00);
	i2c_write(0X01);		//giay
	i2c_write(0X23);		//phut
	i2c_write(0X09);		//gio
	i2c_write(0X07);		//thu
	i2c_write(0X20);		//ngay
	i2c_write(0X03);		//thang
	i2c_write(0X11);		//nam
	i2c_stop();
}
void read_time()
{	unsigned char i;
	i2c_start();
	i2c_write((SLAVE_ADD<<1)|WRITE);
	i2c_write(0x00);
	i2c_stop();
	i2c_start();
	i2c_write((SLAVE_ADD<<1)|READ);
	for(i=0;i<=5;i++)
	{
	b[i]=i2c_read(0);
	}
	b[6]=i2c_read(1);
	i2c_stop();
}

void Display(char b[])
{   
	int i,j=0;
//	unsigned char c[];
	// 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 ");
			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]);
}

	
void main()
{
	lcd_init();
	i2c_init();
	__delay_ms(150);
	set_time();
	__delay_ms(150);
	while(1)
	{
		read_time();
		Display(b);
		__delay_ms(150);
		__delay_ms(150);
	}
}
 

2death

Cố Vấn CLB
Staff member
Kiểm tra lại cấp nguồn, xem đã nối chung mass chưa?
Nếu vấn đề không phải do phần cứng mà là do nhiễu thì thử xoắn hai sợi dây tín hiệu lại với nhau (SCL và SDA xoắn đôi lại với nhau khi đi từ mạch mainPIC sang)
 
đây là bài code viết đông hồ thực có điều chỉnh thời gian bằng hai nút buton trên main pic chân RB0 là vào menu chỉnh thời gian nhấn nút RB1 để thay đổi thời gian. mọi người xem và cho ý kiến nhé.
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);
}
}
 
Kiểm tra lại cấp nguồn, xem đã nối chung mass chưa?
Nếu vấn đề không phải do phần cứng mà là do nhiễu thì thử xoắn hai sợi dây tín hiệu lại với nhau (SCL và SDA xoắn đôi lại với nhau khi đi từ mạch mainPIC sang)
đúng rồi chị phương ơi nguyên nhân là do nhiễu em phải xoắn chực đại hai giây đó lại mới chạy được. thank anh chị nhiều;:)
 

nakatatran

Trứng gà
Mô phỏng đồng hồ thời gian thực (ds1307) trên protues ko chạy .

Mấy bạn ơi ! cho mình hỏi mình có tham khảo code của mấy bạn , như khi mô phỏng với protues nó ko chạy đúng , chỉ 00 ..các bạn giúp mình với.(mặc dù cũng hiểu code).

// còn đây là code
Code:
#include <htc.h>
#include "i2c.h"
#include "lcd.h"
__CONFIG(XT & WDTDIS & PWRTEN & MCLREN & UNPROTECT & SWBOREN & IESODIS & FCMDIS & LVPDIS & DEBUGDIS); //1st config. Word
 
__CONFIG(BORV21); //2st config. Word
 
#define _XTAL_FREQ 4000000 //t?n s? th?ch anh 4Mhz
 
// DS1307 7-bit address = 0b 110 1000 = 0x68
#define SLAVE_ADD 0x68
#define READ 1
#define WRITE 0
char b[7];
char c[14];
void set_time()
{
i2c_start();
i2c_write((SLAVE_ADD<<1)|WRITE);
i2c_write(0X00);
i2c_write(0X01); //giay
i2c_write(0X23); //phut
i2c_write(0X09); //gio
i2c_write(0X07); //thu
i2c_write(0X20); //ngay
i2c_write(0X03); //thang
i2c_write(0X11); //nam
i2c_stop();
}
void read_time()
{ unsigned char i;
i2c_start();
i2c_write((SLAVE_ADD<<1)|WRITE);
i2c_write(0x00);
i2c_stop();
i2c_start();
i2c_write((SLAVE_ADD<<1)|READ);
for(i=0;i<=5;i++)
{
b[i]=i2c_read(0);
}
b[6]=i2c_read(1);
i2c_stop();
}
 
void Display(char b[])
{
int i,j=0;
// unsigned char c[];
// 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 ");
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]);
}
 
 
void main()
{
lcd_init();
i2c_init();
__delay_ms(150);
set_time();
__delay_ms(150);
while(1)
{
read_time();
Display(b);
__delay_ms(150);
__delay_ms(150);
}
}
 

Manhdd

Cố Vấn CLB
Staff member
@ dinale: cái đó là do thời gian mô phỏng thôi.
Bạn vô System > Set Animation Options rồi tùy ý mà chỉnh lại nhé!
 
mình có đoạn code dùng giao tiếp I2C như thế này. nhưng mình tes mãi mà ko được. mong các bạn tes thử giúp. ý tưởng của đoạn code như sau. dùng 3 nút nhấn RA0,RA1,RA2
làm 3 nút nhấn. RA0 điều chỉnh menu cài đặt giờ, hẹn giờ để tắt bật 2 tải bàng chân RB1,RB2 và loa RB0. RA1 chỉnh vị trí của số cần chỉnh. RA2 dùng để tăng giá trị thời gian.
nạp vào đã chạy nhưng sao khi hẹn giờ bật RB1 và RB2 được rồi nhưng hẹn giờ tắt nó trở lại thì không tắt được mặc dù loa đã có báo là vào thời gian tắt. mong mọi người tes giúp.
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];
char thoigian11[3];
char thoigian21[3];
char thoigian31[3];
char thoigian12[3];
char thoigian22[3];
char thoigian32[3];
int a=0;
int t=0;
int k=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_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]);
	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%10+0x30);
	}
	}
void settime()
{
	int i;
		switch(t)
					{
						case 1:
							{
								set_time(time);
							}
						case 2:
							{	
								for(i=0;i<3;i++)
									thoigian11[i]=time[i];
									k=1;	
							}
						case 3:
							{
								for(i=0;i<3;i++)
									thoigian21[i]=time[i];
									k=1;
							}
						case 4:
							{
								for(i=0;i<3;i++)
									thoigian31[i]=time[i];
									k=1;
							}
						case 5:
							{
								for(i=0;i<3;i++)
									thoigian12[i]=time[i];
							}
						case 6:
							{
								for(i=0;i<3;i++)
									thoigian22[i]=time[i];
							}
						case 7:
							{
								for(i=0;i<3;i++)
									thoigian32[i]=time[i];
									k=1;
							}
					}	
}	
/***************************************************************
+kiem tra nut nhan
****************************************************************/
void nutnhan_RA0()										//nhan RB0 de vao menu cai dat thoi gian
{
	if(RA0==0)
	{
hoira0: if(RA0==1)
		{
			__delay_ms(190);
			t+=1;
			if(t==8)
			{
				t=0;
				a=0;
			}
		}
		else
			goto hoira0;
	}
}
void nutnhan_RA1()										//nhan RB0 de vao menu cai dat thoi gian
{

	if(RA1==0)
	{
hoira1: if(RA1==1)
			a+=1;
		else
			goto hoira1;
	}
}
void nutnhan_RA2()
{
int i;
len:	Display(time);										//hien thi time hien tai										
	 if(RA2==0)											//kiem tra nut nhan tang giam time	
		{
hoira2:		if(RA2==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);
					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);
					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);
					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);
					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);
					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);
					goto len;
				case 7:										//a=7 chinh thu 
					time[3]+=1;
					if(time[3]==8)
						time[3]=1;
					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);
					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);
					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);
					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);
					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);
					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);
					goto len;
				case 14:										//a=14 thoat khoi trang thai hieu chinh
					settime();
					a=0;
					t=0;
					return;
				}
			}		
		else
			goto hoira2;
	}
	else if(a==15)
	{
		a=0;
		t=0;
	}
}
[COLOR="red"]void sosanh1()
{
if((time[2]==thoigian11[2])&&(time[1]==thoigian11[1])&&(time[0]==thoigian11[0]))
{
RB0=1;
}
else if((time[1]==(thoigian11[1]+1))&(time[0]==thoigian11[0]))
{
RB0=0;
}
}
void sosanh2()
{
if((time[2]==thoigian21[2])&&(time[1]==thoigian21[1])&&(time[0]==thoigian21[0]))
{
RB0=1;
RB1=1;
}
else if((time[1]==(thoigian21[1]+1))&&(time[0]==thoigian21[0]))
{
RB0=0;
}
}
void sosanh3()
{
if((time[2]==thoigian31[2])&&(time[1]==thoigian31[1])&&(time[0]==thoigian31[0]))
{
RB0=1;
RB2=1;
}
else if((time[1]==(thoigian31[1]+1))&&(time[0]==thoigian11[0]))
{
RB0=0;
}
}
void sosanh4()
{
if((time[2]==thoigian12[2])&&(time[1]==thoigian12[1])&&(time[0]==thoigian12[0]))
{
RB1=0;
RB0=1;
}
else if((time[1]==(thoigian12[1]+1))&&(time[0]==thoigian12[0]))
{
RB0=0;
}
}
void sosanh5()
{
if((time[2]==thoigian22[2])&&(time[1]==thoigian22[1])&&(time[0]==thoigian22[0]))
{
RB0=1;
RB2=0;
}
else if((time[1]==(thoigian22[1]+1))&&(time[0]==thoigian22[0]))
{
RB0=0;
}
}
void sosanh6()
{
if((time[2]==thoigian32[2])&&(time[1]==thoigian32[1])&&(time[0]==thoigian32[0]))
{
RB0=1;
RB1=1;
RB2=1;
}
else if((time[1]==(thoigian32[1]+1))&&(time[0]==thoigian32[0]))
{
RB0=0;
}[/COLOR]}/************************************************** *********
+HAM MAIN
************************************************** **********/
void main(void)
{
int i;
lcd_init();
i2c_init();
init_port();
__delay_ms(150);
while(1)
{
nutnhan_RA1();
nutnhan_RA2();
Display(time);
if(t==0)
{
read_time();
if(k=1)
{
sosanh1();
sosanh2();
sosanh3();
sosanh4();
sosanh5();
sosanh6();
}
}
nutnhan_RA0();
__delay_ms(190);
__delay_ms(190);
}
}
 
Top