?? i2ctime.c
字號:
#include "p30f6014.h"
#include "I2CTime.h"
void InitializeSys()
{
SRbits.IPL = 6; // CPU中斷優(yōu)先級設(shè)為6
}
void InitializeKeyboard()
{
TRISD = (TRISD | 0xff00); //將RD8-RD15配置為輸入,D0~D7
TRISD = (TRISD & 0xfff8); //RD0-RD2配置為輸出,作138譯碼
PORTD = (PORTD & 0xfff8); //選中KEYA,針對S1~S8的按鍵
}
void ConfigI2CTime()
{
I2CCONbits.I2CEN = 1; //啟動I2C模塊
I2CBRG = 0x064; //I2C波特率
}
void InitializeSPIOut()
{
TRISF = TRISF&0xfebf; //RF6、RF8輸出
TRISG = TRISG&0xfdff; //RG9輸出
SPI1CON = 0x0379; // 字節(jié)通訊模式,CKP=1,CKE=1,FOSC/32,時鐘上升沿發(fā)送數(shù)據(jù)
SPI1STATbits.SPIEN = 1; //SPI1EN=1
IFS0bits.SPI1IF = 0; // 清除SPI1IF標(biāo)志
}
void InitializeTMR1()
{
TMR1 = 0; //定時器1計數(shù)寄存器TMR1=0
T1CON = 0x0020; //關(guān)閉定時器,使用內(nèi)部時鐘,預(yù)分頻比為1:64
PR1 = 0x3D09; //定時器Timer1周期寄存器PR1=0xf424,0.5s初值
IFS0bits.T1IF = 0; //清除TMR1的中斷標(biāo)志
IPC0bits.T1IP = 7; //中斷優(yōu)先級為7
IEC0bits.T1IE = 1; //使能中斷
}
void DealWithKeys()
{
int i;
if((PORTD&0xff00) == 0xfe00) //查詢是否S1鍵按下
{
for(i=0; i<100; i++); //延時消抖
if((PORTD&0xff00) == 0xfe00)
{
SetMode += 1; //改變當(dāng)前模式
if(SetMode == 4)
SetMode = 0;
}
while((PORTD&0xff00) == 0xfe00); //不對一次長按按鍵進(jìn)行多次計數(shù)
}
if((PORTD&0xff00) == 0xfd00) //查詢是否S2鍵按下
{
for(i=0; i<100; i++); //延時消抖
if((SetMode == 1)||(SetMode == 2)) //如果模式?jīng)]有改變,S2鍵按下無效
{
if((PORTD&0xfd00) == 0xfd00)
{
SelfIncrFlag += 1;
}
while((PORTD&0xff00) == 0xfd00); //不對一次長按按鍵進(jìn)行多次計數(shù)
}
}
}
void ModifyMode()
{
if(SetMode == 1) //修改小時數(shù)模式
{
T1CONbits.TON = 1;
ModifyHour();
}
if(SetMode == 2) //修改分鐘數(shù)模式
{
T1CONbits.TON = 1;
ModifyMinute();
}
if((SetMode == 0)||(SetMode == 3)) //其他模式
T1CONbits.TON = 0;
}
void ModifyHour()
{
if(SelfIncrFlag == 1) //小時修改范圍0~23h
{
Time[1] += 1;
if(Time[1] == 10)
{
Time[0] += 1;
Time[1] = 0;
}
if((Time[0] == 2)&&(Time[1] == 4))
Time[0] = Time[1] = 0;
SelfIncrFlag = 0;
}
}
void ModifyMinute()
{
if(SelfIncrFlag == 1) //分鐘修改范圍0~59m
{
Time[4] += 1;
if(Time[4] == 10)
{
Time[3] += 1;
Time[4] = 0;
if((Time[3] == 6)&&(Time[4] == 0))
Time[3] = Time[4] = 0;
}
SelfIncrFlag = 0;
}
}
void WriteData()
{
int i;
I2CCONbits.SEN = 1; //發(fā)送啟動位
while(I2CCONbits.SEN==1){} //等待啟動操作完成
I2CTRN = ControlByteW; //發(fā)送控制字:寫準(zhǔn)備
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
I2CTRN = AddressH;
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
I2CTRN = AddressL;
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
for (i=0;i<16;i++)
{
I2CTRN = DataReceived[i];
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
}
I2CCONbits.PEN = 1; //發(fā)送停止位
while(I2CCONbits.PEN==1){} //等待停止操作完成
}
void ReadData()
{
int i;
I2CCONbits.SEN = 1; //發(fā)送啟動位
while(I2CCONbits.SEN == 1){} //等待啟動操作完成
I2CTRN = ControlByteW; //發(fā)送控制字:寫準(zhǔn)備
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
I2CTRN = AddressH;
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
I2CTRN = AddressL;
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
I2CCONbits.RSEN = 1; //發(fā)送重啟動位
while(I2CCONbits.RSEN==1){} //等待重啟動操作完成
I2CTRN = ControlByteR; //發(fā)送控制字:讀準(zhǔn)備
while(I2CSTATbits.TRSTAT==1){} //等待發(fā)送完成
for (i=0;i<16;i++)
{
I2CCONbits.RCEN = 1; //接收數(shù)據(jù)使能
while(I2CSTATbits.RBF==0){}
DataReceived[i] = I2CRCV;
I2CCONbits.ACKDT = 0;
if (i==15)
I2CCONbits.ACKDT = 1; //最后一字節(jié)則不發(fā)ACK
I2CCONbits.ACKEN = 1;
while(I2CCONbits.ACKEN==1){}
}
I2CCONbits.PEN = 1; //發(fā)送停止位
while(I2CCONbits.PEN==1){} //等待停止操作完成
}
void FormatDataReceived()
{
Time[0] = (DataReceived[3]>>4)&0x03;
Time[1] = DataReceived[3]&0x0f;
Time[2] = 10;
Time[3] = (DataReceived[2]>>4)&0x07;
Time[4] = DataReceived[2]&0x0f;
Time[5] = 10;
Time[6] = (DataReceived[1]>>4)&0x07;
Time[7] = DataReceived[1]&0x0f;
}
void FormatTime()
{
//DataReceived[1] = (Time[6]<<4)|Time[7];
DataReceived[2] = (Time[3]<<4)|Time[4];
DataReceived[3] = ((Time[0]<<4)|Time[1])&0x7f;
}
void DisplayOnLED(unsigned int* TimeTemp)
{
int i;
PORTGbits.RG9 = 0; //為鎖存作準(zhǔn)備
for(i=0; i<2; i++) // 顯示小時
{
SPI1BUF = Table1[TimeTemp[i]];
while(SPI1STATbits.SPITBF == 1);
}
SPI1BUF = 0xbf; //顯示“-”
while(SPI1STATbits.SPITBF == 1);
for(i=3; i<5; i++) //顯示分鐘
{
SPI1BUF = Table1[TimeTemp[i]];
while(SPI1STATbits.SPITBF == 1);
}
SPI1BUF = 0xbf; //顯示"-"
while(SPI1STATbits.SPITBF == 1);
for(i=6; i<8; i++) //顯示秒
{
SPI1BUF = Table1[TimeTemp[i]];
while(SPI1STATbits.SPITBF == 1);
}
SPI1BUF = 0xff;
while(SPI1STATbits.SPITBF == 1);
PORTGbits.RG9 = 1; //給鎖存信號
}
void __attribute__((__interrupt__))_T1Interrupt(void)
{
unsigned char i;
for(i=0; i<8; i++)
TimeFlicker[i] = Time[i];
TMR1INTFlag = ~TMR1INTFlag; // 區(qū)別相鄰的兩次中斷,為了在修改時鐘時產(chǎn)生閃爍效果
TMR1 = 0;
IFS0bits.T1IF = 0; // 清定時器中斷標(biāo)志
if(SetMode == 1) // 修改當(dāng)前小時數(shù)
{
TimeFlicker[0] = 10;
TimeFlicker[1] = 10;
}
if(SetMode == 2) // 修改當(dāng)前分鐘數(shù)
{
TimeFlicker[3] = 10;
TimeFlicker[4] = 10;
}
}
int main()
{
int i;
InitializeSys();
ConfigI2CTime();
InitializeKeyboard();
InitializeSPIOut();
InitializeTMR1();
while(1)
{
if(SetMode == 0) // 時鐘顯示模式
{
ReadData();
FormatDataReceived();
}
DealWithKeys();
ModifyMode();
if(SetMode == 3) // 修改當(dāng)前時鐘
{
FormatTime();
WriteData();
}
if(TMR1INTFlag == 0) // 更改時間時產(chǎn)生閃爍效果
DisplayOnLED(&Time[0]);
else
DisplayOnLED(&TimeFlicker[0]);
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -