📄 vidu4-4.c
字号:
/*******************************************************************************
; Vidu4-4.c la chuong trinh viet bang C30 de chay tren mot dsPIC *
; Chuong trinh thuc hien viec sau: Khoi tao RTC DS1307, sau do doc thong tin *
; tu RTC bang module I2C, gui thong tin thoi gian ve may tinh thong qua *
; cong RS232 (dung cac chan I/O thay the) *
;*******************************************************************************
; Tac gia : Nguyen Quang Nam *
; Don vi : PIC Viet Nam *
; Ten tap tin : Vidu4-4.c *
; Ngay : 26/08/2006 *
; Phien ban : 0.01 *
; Nhung tap tin can thiet khac: p30F4012.gld, p30f4012.h *
; Cong cu duoc dung: MPLAB 7.31 *
; C30 2.02 SE *
; ASM30 2.14 *
; LNK30 2.14 *
------------------------------------------------------------------------------*/
#include "p30f4012.h"
_FOSC(CSW_FSCM_OFF & FRC_PLL4); //Clock = 32 MHz
_FWDT(WDT_OFF);
_FBORPOR(MCLR_EN & PBOR_OFF & PWMxL_ACT_HI & PWMxH_ACT_HI);
_FGS(CODE_PROT_OFF);
//------------------------------------------------------------------------------
//Cac hang so cua chuong trinh (gia tri tuc thoi dung trong chuong trinh)
#define Fcy 8000000 //Tan so thuc thi lenh
#define I2Cbaud 100000 //Toc do baud cua giao tiep I2C
#define RSbaud 38400 //Toc do baud cua giao tiep RS232
//Cac prototype cho cac chuong trinh con
void Init_PORTS(void);
void Init_TMR1(void);
void Init_I2C(void);
void Wait_I2C(void);
void Write_I2C(unsigned char);
unsigned char Read_I2C(void);
void I2C_Fail(void);
void Init_UART1(void);
void Send_UART1(unsigned char);
//Cac bien toan cuc
unsigned short count, flag1, flag2, buf_idx, str_idx, i;
unsigned char buff[16] = {0xD0, 0x00, 0x00, 0x00, 0x67,
0x01, 0x26, 0x08, 0x06, 0x90};
unsigned char str[16], temp;
//------------------------------------------------------------------------------
//Chuong trinh chinh
int main(void) {
Init_PORTS(); //Khoi tao cac cong I/O
Init_I2C(); //Khoi tao module I2C
Init_UART1(); //Khoi tao module UART1
Init_TMR1(); //Khoi tao Timer 1
//Buoc 1, tao dieu kien START, cho hoat dong I2C hoan tat
_SEN = 1; //Tao ra dieu kien START
Wait_I2C(); //Cho hoat dong I2C hoan tat
//Buoc 2, ghi cac byte can thiet, cho va kiem tra ACK
buf_idx = 0; //Chinh con tro de bat dau tu dau bo dem
flag1 = 0; //Xoa co bao loi truoc khi ghi
for (i = 10; i > 0; i--) {
Write_I2C(buff[buf_idx++]); //Ghi 1 byte vao RTC
if (flag1 & 0x0001) I2C_Fail(); //Neu NACK thi xu ly loi
};
//Buoc 3, tao dieu kien STOP, cho hoat dong I2C hoan tat
_PEN = 1; //Tao ra dieu kien STOP
Wait_I2C(); //Cho hoat dong I2C hoan tat
while (1) {
count = 11;
while (count != 0);
//Doc thong tin thoi gian tu RTC
//Buoc 1, tao dieu kien START, cho hoat dong I2C hoan tat
_SEN = 1; //Tao ra dieu kien START
Wait_I2C(); //Cho hoat dong I2C hoan tat
//Buoc 2, ghi dia chi cua RTC, sap thao tac ghi vao RTC
flag1 = 0; //Xoa co bao loi truoc khi ghi
Write_I2C(0xD0);
if (flag1 & 0x0001) I2C_Fail(); //Neu NACK thi xu ly loi
//Buoc 3, ghi dia chi cua thanh ghi sap thao tac
Write_I2C(0x00);
if (flag1 & 0x0001) I2C_Fail(); //Neu NACK thi xu ly loi
//Buoc 4, tao dieu kien RESTART, cho hoat dong I2C hoan tat
_RSEN = 1; //Tao ra dieu kien RESTART
Wait_I2C(); //Cho hoat dong I2C hoan tat
//Buoc 5, ghi dia chi cua RTC, sap thao tac doc tu RTC
Write_I2C(0xD1); //Ghi dia chi cua RTC, chuan bi doc tu RTC
if (flag1 & 0x0001) I2C_Fail(); //Neu NACK thi xu ly loi
str_idx = 0;
//Buoc 6, doc cac byte can thiet (tru byte cuoi cung), va ACK
for (i = 2; i > 0; i--) { //Vong lap doc 2 byte du lieu, va ACK
flag2 &= 0xFFFE;
temp = Read_I2C();
str[str_idx++] = (temp & 0x0F) + '0'; //Chuyen so BCD thanh cac
str[str_idx++] = (temp >> 4) + '0'; //ky tu bieu dien gia tri
str[str_idx++] = ':';
};
//Buoc 7, doc byte cuoi cung va NACK
flag2 |= 0x0001;
temp = Read_I2C();
str[str_idx++] = (temp & 0x0F) + '0';
str[str_idx] = (temp >> 4) + '0';
//Buoc 8, tao dieu kien STOP, cho hoat dong I2C hoan tat
_PEN = 1; //Tao ra dieu kien STOP
Wait_I2C(); //Cho hoat dong I2C hoan tat
//Vong lap xuat ky tu qua cong RS232
for (i = 8; i > 0; i--) {
Send_UART1(str[str_idx--]);
};
Send_UART1(0x0a); //Xuat cap ky tu CR, LF
Send_UART1(0x0d);
};
}
//Chuong trinh con khoi tao cac cong I/O
void Init_PORTS(void) {
LATE = 0xFFFF; //Tat cac LED (anode chung) noi vao cong E
TRISE = 0xFFFE; //LED noi vao RE0
}
//Chuong trinh con khoi tao module I2C
void Init_I2C(void) {
I2CCON = 0x8200; //bit15=I2CEN, bit9=DISSLW (tat Slew Rate
//Control cho cac toc do baud khac 400 kbps)
I2CBRG = (((Fcy/I2Cbaud) - (Fcy/1111111))-1);
}
//Chuong trinh con cho hoat dong Master I2C sau cung hoan tat
void Wait_I2C(void) {
while (!_MI2CIF);
_MI2CIF = 0;
}
//Chuong trinh con xuat 1 byte qua module I2C
void Write_I2C(unsigned char d) {
I2CTRN = d;
Wait_I2C();
if (_ACKSTAT) flag1 |= 0x0001; //Bat co neu nhan duoc NACK
}
//Chuong trinh con doc byte tu I2C, che do Master
unsigned char Read_I2C(void) {
unsigned char d;
_RCEN = 1; //Cho phep nhan byte
Wait_I2C(); //Cho hoat dong I2C hoan tat
d = I2CRCV; //Lay byte da nhan dat vao d
if (flag2 & 0x0001) _ACKDT = 1; //Neu NACK thi bat ACKDT
else _ACKDT = 0; //Nguoc lai thi tat ACKDT
_ACKEN = 1; //Ghi bit ACK/NACK ra I2C bus
Wait_I2C(); //Cho hoat dong I2C hoan tat
return d; //Tra byte da doc ve chuong trinh goi
}
//Chuong trinh con xu ly khi hoat dong I2C bi loi
void I2C_Fail(void) {
_PEN = 1; //Tao ra dieu kien STOP
Wait_I2C(); //Cho hoat dong I2C hoan tat
LATE &= 0xFFFE; //Bat LED noi vao RE0 de bao loi
while (1); //Dung chuong trinh tai day
}
//Chuong trinh con khoi tao module UART1
void Init_UART1(void) {
U1MODE = 0x8400; //Alt I/O, 8-bit, no parity, 1 stop bit
U1STA = 0x0400; //bit10=UTXEN
U1BRG = (((Fcy/RSbaud)/16)-1); //38400 bps @ Fcy = 8 MHz
}
void Send_UART1(unsigned char d) {
U1TXREG = d; //Xuat 1 ky tu
while (!U1STAbits.TRMT); //Cho den khi truyen xong ky tu
}
//Chuong trinh con khoi tao Timer 1, tran sau moi 0,5 giay o muc xung 8 Mips
void Init_TMR1(void) {
TMR1 = 0; //Xoa so dem trong TMR1
PR1 = 0x7A12; //Nguong tran la 1 giay tuong ung voi clock = 32 MHz
_T1IF = 0; //Xoa co ngat cua Timer 1
T1CON = 0x8030; //Dung fcy lam clock, prescale = 1:256
_T1IE = 1; //Cho phep ngat khi Timer 1 tran
}
//Chuong trinh xu ly ngat Timer 1
void _ISR _T1Interrupt(void) {
_T1IF = 0; //Xoa co ngat
count -= 1; //Giam bien dem di 1 don vi
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -