?? smbuskeyboard______完成.c
字號(hào):
/////////////////////////////////////
// smbuskey_dispaly.c File ////////////
/////////////////////////////////////
////2007.7.30//fengkun
/////////////////////////////////////
#include <C8051F020.h>
#include <intrins.h>
#define PCF8574 0x71 // 芯片A的器件地址CHIP_A = 1110001最后一位沒(méi)有用
#define dat P7
unsigned char num=0,a=0,ke=0;
unsigned char hh,j,k,m; //顯示位定義
xdata unsigned char aa[3]; //用于存放接收數(shù)據(jù)
code unsigned char LedCode[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
// 0 1 2 3 4 5 6 7 8 9
sbit dpy1=P3^0;
sbit dpy2=P3^1;
sbit dpy3=P3^2;
sbit dpy4=P3^3;
bit flag;
////////////////////////////////////////////////////////////////////////////
/////////初始化
////////////////////////////////////////////////////////////////////////////
void Reset_Sources_Init()
{
WDTCN = 0xDE;
WDTCN = 0xAD;
}
void Port_IO_Init()
{
//P0MDOUT = 0xFF;
P3MDOUT = 0xFF;
P74OUT = 0xC0;
XBR0 = 0x01;
XBR1 = 0x04;
XBR2 = 0x40;
}
void Oscillator_Init()
{
int i = 0;
OSCXCN = 0x67;
for (i = 0; i < 3000; i++); // Wait 1ms for initialization
while ((OSCXCN & 0x80) == 0);
OSCICN = 0x08;
}
void Init_Device(void)
{
Reset_Sources_Init();
Port_IO_Init();
Oscillator_Init();
}
void Smbus_Init()
{
BUSY=0; // 釋放總線
SMB0CR =200; // SMBus時(shí)鐘頻率 = 50kHz.
EIE1 |= 2; // SMBus中斷允許
SMB0CN = 0x44; // 允許SMBus在應(yīng)答周期發(fā)送ACK
SMB0ADR=PCF8574;
}
void Display_Init() //顯示模塊初始化
{
hh=4;j=5;k=6;m=7; //初始化顯示值
P3=0xf0; //初始化端口-------------
dat=0x00; //-----------------------
TMOD=0x11; //初始化定時(shí)器-----------
TR0=1;
ET0=1;
}
////////////////////初始化外部中斷0/////////////////////////////////////
void Int0_Init()
{
EX0=1;
PX0=1;
IT0=0;
}
/////////////////////////////////////////////////////////////////////////////
//鍵盤(pán)判斷數(shù)據(jù)處理-----------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////
void keySMBUS()
{
while(BUSY); //wait busybit
BUSY =1; // 為第一次傳輸釋放SMBus。
SMB0CN = 0x44; // 允許SMBus在應(yīng)答周期發(fā)送ACK
STA=1; //開(kāi)始
while (BUSY); // 等待傳輸結(jié)束
switch(aa[2]&0x0f)
{
case 0x0e:
hh++;
if(hh>9)
hh=0;
break;
case 0x0d :
j++ ;
if(j>9)
j=0;
break;
case 0x0b :
k++ ;
if(k>9)
k=0;
break;
case 0x07 :
m++ ;
if(m>9)
m=0;
break;
}
}
////////////////////////////////////////////////////////////////////////////
//smbus中斷,此中斷只考慮關(guān)鍵狀態(tài)處理,以便調(diào)試
////////////////////////////////////////////////////////////////////////////
void smbusInt(void) interrupt 7
{
if(SMB0STA==0x08) //起始位發(fā)送成功,將地址+讀控制裝入發(fā)送緩沖區(qū)
{
SMB0DAT=PCF8574;
ke=0;
STA=0; //將STA清零,否則將處于重發(fā)狀態(tài)
}
if(SMB0STA==0x40) //地址+讀控制發(fā)送成功,此時(shí)SMB0DAT里的數(shù)據(jù)無(wú)意義,不作為接收數(shù)據(jù),
{
ke=0;
AA=0; //要確保AA為1,因?yàn)榻酉氯ナ侵鳈C(jī)發(fā)送ACK確認(rèn)信號(hào)如果只接受一位,AA至0
}
/*if(SMB0STA==0x50)//數(shù)據(jù)成功接收,ACK成功發(fā)送
{
if(ke>=3)//共接收4個(gè)數(shù)據(jù),所以在接收到第3個(gè)時(shí)將AA清零,注意第一個(gè)數(shù)據(jù)是從ke=1時(shí)接收
AA=0;
a[ke]=SMB0DAT;
} *///多組數(shù)據(jù)用這條
if(SMB0STA==0x10) //重發(fā)狀態(tài)的處理
{
SMB0DAT=0x71;
STA=0;
}
if(SMB0STA==0x58) //最后一個(gè)數(shù)據(jù)接收成功,將STO置1,釋放總線本程序只接受一個(gè)位數(shù)據(jù)
{
STO=1;
aa[2]=SMB0DAT;
}
/* ke++;
if(ke>=5)
ke=0;//在此設(shè)斷點(diǎn)觀察全速運(yùn)行結(jié)果 */
SI=0;
}
/////////////////外部中斷///////////////////////////////////////////////////
void intInterrupt(void) interrupt 0 using 2
{
EX0=0; //關(guān)外部中斷
flag=1; //中斷標(biāo)志位
}
////////////////////////////////////////////////////////////////////////////
/////////////定時(shí)器0中斷----數(shù)碼管掃描////////////////////////////
////////////////////////////////////////////////////////////////////////////
void time0(void) interrupt 1 using 1
{
EA=0;
TH0=0xff;
TL0=0x00;
TR0=1;
TF0=0;
num++;
if(num>3)
num=0;
////////////////////////////////////////////////////////////////////////////
//以后數(shù)碼管多了可以在上面加case,但是調(diào)節(jié)TL的大小,調(diào)到使數(shù)碼管不閃就行!!
switch (num)
{
case 0: dpy4=0;
dat=LedCode[hh];
dpy1=1;
break;
case 1: dpy1=0;
dat=LedCode[j];
dpy2=1;
break;
case 2: dpy2=0;
dat=LedCode[k];
dpy3=1;
break;
case 3: dpy3=0;
dat=LedCode[m];
dpy4=1;
break;
}
EA=1;
}
////////////////////////////////////////////////////////////////////////////
/////主函數(shù)///////////////////////////////////////////----------------------
////////////////////////////////////////////////////////////////////////////
main()
{ Init_Device();
Display_Init();
Int0_Init();
Smbus_Init();
EA = 1; // 全局中斷允許
while(1)
{
if(flag)
{ long int rr=50000;
keySMBUS();
while(--rr);
EX0=1; //打開(kāi)外部中斷
flag=0; //清標(biāo)志位
}
}
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -