PDA

View Full Version : Ứng dụng nhỏ với pic _ dùng I2C mềm


minhsondaklak
04-08-2008, 07:53 AM
Mạn phép anh Namqn, em pots thêm bài này khai thác thêm I2C bằng phần mềm (trên MikroC) để cùng các bạn nghiên cứu, tham khảo.

http://i452.photobucket.com/albums/qq247/minhsondaklak/Hengio_I2C.png

(xem mục đích của ứng dụng bên này:
http://www.picvietnam.com/forum/showthread.php?t=2644)


A.Cau hinh phan cung: Pic 16F84A (hoac 16F88, 16F628A voi CMCON = 0x07), Thach anh 4Mhz, ds1307
- PORTA.F2 la ngo vao noi voi nut nhan SET_19h, cho ghi ds1307 ve dung 19 h
- PORTA.F3 noi voi den bao giay
- PORTA.F4 la ngo ra dieu khien Tri ac, dong mo thiet bi may bom (ON = 0, OFF = 1)
- PORTB ngo ra 8 bit bao gio, phut dang ma nhi phan BCD
- PORTA.F0, PORTA.F1 noi chan 5, 6 cua Ds1307 qua dien tro 4,7k keo len,
la cac chan SDA, SCL cua giao tiep I2C (Pic 18 chan kong tich hop I2C, ta dung I2C phan mem tren MikroC)
- Ngat Time0: Sau moi giay cho nhay Led, 1 phut cho Doc ds1307 va xem xet ON_OFF chan PORTA.F4

B. Giai thich cac bien:
-set, luu: truy cap dia chi 0x07, 0x08 cua DS1307, xu ly khi mat nguon pin nuoi, phai set lai ds1307
-giay, phut ...nam : cac bien truy cap thoi gian tu ds1307
-flag1: co bao tin hieu chu ky phut;
-delay1s, delay1p: bien dem ngat tran, tinh chu ky giay, phut (canh chung 1s nhay led, 1 phut cho doc ds1307)



unsigned short set, luu, giay, phut, gio, thu, ngay, thang, nam, flag1, flag2, delay1s = 0, delay1p = 0;

void INIT_MAIN() // Khoi tao cac PORT, NGAT, I2C
{
/* Khoi tao cong B -----------------------------------------------------------*/
TRISB = 0x00; // Cau hinh cong B Ouput
PORTB = 0x00;
/* Khoi tao cong A ----------------------------------------------------*/
TRISA = 0x04;
PORTA = 0x10;
/* Khoi tao I2C bang phan mem --------------*/
Soft_I2C_Config(&PORTA, 0, 1); //I2C mem, khong phai khoi tao toc do baud
//Ham nay dung bien con tro de tiet kiem bo nho
/* Khoi tao ngat ngoai va Timer0 ---------------------------------------------*/
INTCON = 0b10100000; //0xA0 - Mo ngat t.cuc, ngat timer0, xoa co ngat
OPTION_REG = 0b10000111; //0x87 - Chon suon len cho ngat ngoai, ngat Timer0, bo chia ti le 1:256
TMR0 = 0x00; //Xoa thanh dem Timer0 (cho dem tu 0 den 256 -> 256 chu ky may)
//Voi Fta=4Mhz -> Chukymay =4/4Mhz=1 us, hesochia = 256 -> T =1x256x256=65536 us =~ 65,5 ms
//Vay ta can: 1000 / 65,5 =` 15 lan tran de co 1 s, 15 x 60 = 900 lan tran de co 1 phut
}

void SET_19h() //Ghi vao ds1307, gia tri 19 gio 00 phut, khi co nguoi bam SET_19h
{
Soft_I2C_Start(); // Phat bit STAR I2C
Soft_I2C_Write(0xD0); // Truyen d/c cua DS1307 la 0xD0 len duong truyen I2C
Soft_I2C_Write(0x00); // Truyen dia chi o nho dau tien cua ds1307, 0x00
Soft_I2C_Write(0x00); // Ghi gia tri ban dau bang 0, cho thanh ghi giay tai 0x00
//Soft_I2C_Write(0x00); //Ghi 00 cho phut
Soft_I2C_Write(0x07); // Chay thu: Ghi Phut = 07,
Soft_I2C_Write(0x19); // Ghi ... Gio = 19 tai 0x02
Soft_I2C_Write(0x07); // Ghi ... Chu nhat, tai 0x03
Soft_I2C_Write(0x03); // Ghi ... Ngay 03, tai 0x04
Soft_I2C_Write(0x08); // Ghi ... Thang 8, tai 0x05
Soft_I2C_Write(0x08); // Ghi ... Nam 2008, tai 0x06
Soft_I2C_Write(0x90); // Ghi cau hinh cho thanh ghi dieu khien (tai 0x07) su dung xung 1Hz cua ds1307
Soft_I2C_Write(0x55); // Lam dau tai d/c 0x08, theo doi nguon pin ds1307
Soft_I2C_Stop(); // Phat bit STOP I2C
}

void READ_DS() //Doc gio, phut, giay ... tu ds1307
{
Soft_I2C_Start(); // Phat bit Star I2C
Soft_I2C_Write(0xD0); // Truyen dia chi Slave (0xD0)len duong truyen I2C
Soft_I2C_Write(0x00); // Goi d/c o nho can truy cap (tai 0x00) den slave
Soft_I2C_Start(); // Khoi dong lai I2C
Soft_I2C_Write(0xD1); // Goi d/c Slave+1 = 0xD0+1 = 0xD1
giay = Soft_I2C_Read(1u); // Doc du lieu tai d/c tren cua Slave, phat bit ACK
phut = Soft_I2C_Read(1u); // Doc o tiep theo (0x01)
gio = Soft_I2C_Read(1u); // tiep ....0x02
thu = Soft_I2C_Read(1u); // Doc thu, tai d/c 0x03
ngay = Soft_I2C_Read(1u); // Doc ngay, tai 0x04
thang = Soft_I2C_Read(1u); // Doc thang, tai 0x05
nam = Soft_I2C_Read(1u); // Doc nam, tai d/c 0x06
set = Soft_I2C_Read(1u); // Doc d/c 0x07 (doc cho qua d/c 0x07)
luu = Soft_I2C_Read(0u); // Doc d/c 0x08 (gia tri 0x55, theo doi nguon Pin)
Soft_I2C_Stop(); // Phat bit STOP I2C
}

void HIEN_THI() //Dung hien thi gio hien hanh, dang ma nhi phan BCD
{
PORTB = gio; Delay_ms(5000); PORTB = 0; Delay_ms(1000); //xem gia tri gio,
PORTB = phut; Delay_ms(5000); PORTB = 0; Delay_ms(1000); //xem gia tri phut,
}

void ON_OFF() //Kiem tra gio (2 bien gio, phut) -> cho ON, OFF
//Neu ban ngay (tu 6h den 20h) dong thoi so hang chuc cua phut la so chan (Mod 2 bang 0)thi ON, la so le (Mod 2 bang 1) thi OFF (ON 10 phut, OFF 10 phut)
//Neu ban dem (21h den 5h)thi OFF
{
gio = Bcd2Dec(gio); phut = Bcd2Dec(phut); //Chuyen so BCD sang Dec
if (6 <= gio && gio <= 21) // An dinh thoi gian ON trong ngay
{
if ((phut / 10) % 2 == 0)
{if (PORTA.F4 == 1) PORTA.F4 = 0;}
else
{if (PORTA.F4 == 0) PORTA.F4 = 1;}
}
else
{if (PORTA.F4 == 0) PORTA.F4 = 1;}
}

void interrupt() //Chuong trinh NGAT
{
//Xu ly cho ngat timer0: Sau moi phut bat co flag1 len 1
if (INTCON.T0IF) //Neu ngat la dinh thoi timer0, co bao 1 (65,5ms)
{
delay1s++; //Tang bien dem len 1 don vi, moi khi tran timer0
if (delay1s == 15)
{
delay1p++;
PORTA.F3 = ~PORTA.F3; //Lam den nhay theo nhip 1 giay
delay1s = 0;
}
if (delay1p == 60) //Neu du 900 lan tran = (60 x 15) x 65,5ms ~ 1 phut,
{
flag1 = 1; //Tin hieu: Da du 1 phut
delay1p = 0; //xoa ve 0, dem lai tu dau
}
INTCON.T0IF = 0; //Xoa co ngat time0
}
} //Het interrup

void MAIN() //CHUONG TRINH CHINH
{
INIT_MAIN(); //khoi tao cac PORT, NGAT, I2C
Delay_ms(1000);
READ_DS(); //Doc ds1307
if (luu != 0x55) {SET_19h(); Delay_ms(100);}
HIEN_THI(); //Hien thi gio, phut hien hanh
PORTB = luu; Delay_ms(2000); PORTB = 0; //hien thi bien luu = 0x55
while (1)
{
if (flag1 == 1) {READ_DS(); HIEN_THI();ON_OFF(); flag1 = 0;}
if (PORTA.F2 == 0) SET_19h();
}
}


Kèm theo file mô phỏng trên Proteus, mong được góp ý.