?? f31xsr176.c
字號:
else{
if(SMB_data_index==SMB_data_len-1){
SMB_state=0x01;
RX_buf[SMB_data_index]=SMB0DAT;
ACK=0; /* 不響應ACK */
STO=1; /* 發(fā)停止 */
}
}
SMB_BUSY=0;
break;
default:
FAIL = 1; /* 傳送失敗,跳到中斷服務程序的最后進行失敗處理 */
break;
}
if(FAIL){ /* 如果傳送失敗 */
SMB0CN &= ~0x40; /* 復位通信 */
SMB0CN |= 0x40;
SMB_BUSY = 0; /* 釋放SMBus */
SMB_state=0x00;
}
SI=0; /* 清中斷旗標 */
}
/***************************************************************************************
函數(shù)名稱: void SMBus_Init(void)
功能描述: 初始化SMBus總線
- SMBus使能
- 無效輔模式
- 定時器0作為時鐘源,SCL的頻率大約是定時器0溢出率的1/3
- 建立和保持時間加長使能
- SCL低電平超時檢測
輸入: 無
輸出: 無
全局變量: SMB0CF -> SMBus時鐘/配置寄存器
調(diào)用模塊: 無
***************************************************************************************/
void SMBus_Init (void)
{
SMB0CF = 0x5C; /* 用定時器0的溢出率作為SMBus的時鐘源,無效SMBus的輔模式 */
/* 建立和保持時間增長使能 */
/* 使能SCL低電平超時檢測 */
SMB0CF |= 0x80; /* 使能SMBus */
}
/***************************************************************************************
函數(shù)名稱: void Timer3_Init(void)
功能描述: 初始化定時器3(用于SMBus低電平超時檢測)
- 定時器3工作在16位重載模式
- SYSCLK/12作為定時器3的時鐘源
- 定時器3重載寄存器是25ms溢出周期的值
- 定時器3的預裝載值是25ms后溢出
- 定時器3使能
輸入: 無
輸出: 無
全局變量: TMR3CN -> 定時器3控制寄存器
CKCON -> 時鐘控制寄存器
TMR3RL -> 定時器3 重載寄存器
TMR3 -> 定時器3計時寄存器
TR3 -> 定時器3使能位
調(diào)用模塊: 無
***************************************************************************************/
void Timer3_Init (void)
{
TMR3CN = 0x00; /* 定時器3工作于16位重載模式,定時器低字節(jié)中斷無效 */
TMR3 = -(SYSCLK/12/40); /* 定時器3在25ms后溢出(SMBus低電平超時檢測)*/
TMR3RL = -(SYSCLK/12/40);
CKCON &= ~0x40; /* 定時器3用SYSCLK/12作為時鐘源 */
TMR3 |= 0x04; /* 使能定時器3 */
}
/***************************************************************************************
函數(shù)名稱: void Timer0_Init(void)
功能描述: 定時器0初始化(用于SMBus總線的時鐘源)
- 定時器0工作在8位重載模式
- SYSCLK/12作為定時器0的時鐘源
- SCL時鐘率是定時器0溢出率的三分之一
- 使能定時0
輸入: 無
輸出: 無
全局變量: CKCON -> 時鐘控制寄存器
TMOD -> 定時器模式寄存器
TH0 -> 定時器0寄存器高字節(jié)
TL0 -> 定時器0寄存器低字節(jié)
TR0 -> 定時器0使能位
調(diào)用模塊: 無
***************************************************************************************/
void Timer0_Init(void)
{
CKCON &= ~0x07; /* 定時器0的時鐘源是SYSCLK / 12 */
TMOD = 0x02; /* 定時器0工作在8位自動重載模式 */
TH0 = -(SYSCLK/SMB_FREQUENCY/12/3); /* 定時器0的溢出率是SMB_FREQUENCY的1/3 */
TL0 = TH0;
TR0 = 1; /* 使能定時器0 */
}
/***************************************************************************************
函數(shù)名稱: void PORT_Init(void)
功能描述: I/O初始化
輸入: 無
輸出: 無
全局變量: XBR0 -> 端口I/O交叉開關控制0
XBR1 -> 端口I/O交叉開關控制1
P0MDIN ->P0口輸入模式控制
P0MDOUT->P0口輸出模式控制
調(diào)用模塊: 無
***************************************************************************************/
void PORT_Init(void)
{
XBR0 = 0x05; /* 使能SMBus和UART引腳 */
XBR1 = 0x40; /* 使能交叉開關和弱上拉 */
P0MDIN = 0xFF; /* P0口工作在數(shù)字模式 */
P0MDOUT = 0x00; /* P0口是開漏模式 */
P0 = 0xff;
P1MDOUT |= 0x03; /* P1.0和P1.1是推挽模式 */
}
/***************************************************************************************
函數(shù)名稱: void UART_Init(void)
功能描述: 初始化串行口
輸入: 無
輸出: 無
全局變量: SCON0 ->串行口0控制寄存器
TMOD ->定時器模式寄存器
TH1 ->定時器1高字節(jié)
TL1 ->定時器1低字節(jié)
CKCON ->時鐘控制寄存器
調(diào)用模塊: 無
***************************************************************************************/
void UART_Init(void)
{
SCON0 = 0x50; /* 工作模式1,8位數(shù)據(jù)位,使能RX */
TMOD = 0x22;
TH1 = 0x95; //C8051F300和C8051F310
//TH1 = 0xB0; //C8051F305(0xA9)
TR1 = 1; /* 使能定時器1 */
CKCON |= 0x00; /* 定時器1用SYSCLK作時基 */
}
/***************************************************************************************
函數(shù)名稱: void Timer3_ISR(void) interrupt 14
功能描述: 定時器3中斷指示SMBus的SCL低電平超時,SMBus無效并且重新使能
輸入: 無
輸出: 無
全局變量: SMB0CN ->SMBus控制寄存器
TF3H ->定時器3中斷旗標
調(diào)用模塊: 無
***************************************************************************************/
void Timer3_ISR (void) interrupt 14
{
SMB0CN &= ~0x40; /* 無效SMBus */
SMB0CN |= 0x40; /* 使能SMBus */
TMR3CN &= ~0x80; /* 清除定時器3高字節(jié)中斷旗標 */
}
/***************************************************************************************
函數(shù)名稱: BYTE Initiate(void)
功能描述: 初始化射頻卡命令
輸入: 無
輸出: 運行結果返回碼
全局變量: Tx_buf ->發(fā)送緩沖區(qū)
read_Len ->射頻卡返回字節(jié)長度
調(diào)用模塊: BYTE Send_Receive_Data(void)
***************************************************************************************/
BYTE Initiate (void)
{
BYTE rei;
read_len=0x02;
TX_buf[0] = 0x01; /* I/O口寄存器地址 */
TX_buf[1] = 0x02; /* 幀長度 */
TX_buf[2] = 0x06;
TX_buf[3] = 0x00;
rei = Send_Receive_Data();
return rei;
}
/***************************************************************************************
函數(shù)名稱: BYTE Select(BYTE CHIP_ID)
功能描述: 選擇射頻卡命令
輸入: BYTE CHIP_ID(射頻卡的識別號)
輸出: 運行結果返回碼
全局變量: read_len ->射頻卡返回字節(jié)長度
Tx_buf ->發(fā)送緩沖區(qū)
調(diào)用模塊: BYTE Send_Receive_Data(void)
***************************************************************************************/
BYTE Select(BYTE CHIP_ID)
{
read_len=2;
TX_buf[0] = 0x01;
TX_buf[1] = 0x02;
TX_buf[2] = 0x0E;
TX_buf[3] = CHIP_ID;
return Send_Receive_Data();
}
/***************************************************************************************
函數(shù)名稱: BYTE ReadBlock(BYTE Addr)
功能描述: 讀射頻卡一塊命令(4 bytes),讀到的數(shù)據(jù)放在全局變量Rx_buf中
輸入: BYTE Addr(塊地址)
輸出: 運行結果返回碼
全局變量: read_len ->射頻卡返回字節(jié)長度
Tx_buf ->發(fā)送緩沖區(qū)
調(diào)用模塊: BYTE Send_Receive_Data(void)
***************************************************************************************/
BYTE ReadBlock (BYTE Addr)
{
read_len=3;
TX_buf[0] = 0x01;
TX_buf[1] = 0x02;
TX_buf[2] = 0x08;
TX_buf[3] = Addr;
return Send_Receive_Data();
}
/***************************************************************************************
函數(shù)名稱: BYTE WriteBlock_4k(BYTE Addr, BYTE DATA_WR0,BYTE DATA_WR1,BYTE DATA_WR2,BYTE DATA_WR3)
功能描述: 寫射頻卡一塊命令(4 bytes)
輸入: BYTE Addr(塊地址)
BYTE DATA_WR0(待寫的第一字節(jié))
BYTE DATA_WR1(待寫的第二字節(jié))
BYTE DATA_WR2(待寫的第三字節(jié))
BYTE DATA_WR3(待寫的第四字節(jié))
輸出: 運行結果返回碼
全局變量: read_len ->射頻卡返回字節(jié)長度
Tx_buf ->發(fā)送緩沖區(qū)
調(diào)用模塊: BYTE Send_Receive_Data(void)
***************************************************************************************/
//BYTE WriteBlock_4K(BYTE Addr,BYTE DATA_WR0,BYTE DATA_WR1,BYTE DATA_WR2,BYTE DATA_WR3)
BYTE WriteBlock_4K(BYTE Addr,BYTE DATA_WR0,BYTE DATA_WR1)
{
read_len=0;
TX_buf[0] = 0x01;
TX_buf[1]=0x04;
TX_buf[2]=0x09;
TX_buf[3]=Addr;
TX_buf[4]=DATA_WR0;
TX_buf[5]=DATA_WR1;
return Send_Receive_Data ();
}
/***************************************************************************************
函數(shù)名稱: BYTE Get_Uid(void)
功能描述: 讀取射頻卡的識別號
輸入: 無
輸出: 運行結果返回碼
全局變量: read_len ->射頻卡返回字節(jié)長度
Tx_buf ->發(fā)送緩沖區(qū)
調(diào)用模塊: BYTE Send_Receive_Data(void)
***************************************************************************************/
/*
BYTE Get_Uid(void)
{
BYTE regu;
read_len=9;
TX_buf[0]= 0x01;
TX_buf[1]= 0x01;
TX_buf[2]= 0x0B;
regu = Send_Receive_Data();
return regu;
}
*/
/**************************************************************************************/
void main(void)
{
BYTE startflag=0;
BYTE *ptr;
BYTE data i;
BYTE m,DataType,CommandLen;
BYTE CardID1,CardID2,temp[2],Uid[8];
FirstTime=1;
Read_Bit=0;
PCA0MD &= ~0x40; /* 關閉看門狗 */
OSCICN |= 0x03; /* 用內(nèi)部24.5MHz時鐘 */
Port_Init(); /* 初始化交叉開關和GPIO */
OneBuzzer(40); /* 蜂鳴器響一次 */
Timer0_Init (); /* 配置定時器0作為SMBus時鐘源 */
Timer3_Init (); /* 配置定時器3作為SMBus的低電平超時檢測 */
SMBus_Init (); /* 配置和使能SMBus */
OpenComm(); /* 初始化串口 */
M485 = 0;
EIE1 |= 1; /* SMBus中斷使能 */
IE |= 0x20; /* 使能定時器2 */
//EIE1 |= 0x80; /* 使能定時器3 */
EA = 1; /* 所有中斷使能 */
RF_ON(); /* 打開載頻輸出*/
sleep_ms(1000);
NewCard: startflag=Initiate(); /* 初始化讀卡器工作范圍內(nèi)的射頻卡*/
startflag=RX_buf[1];
RX_buf[1]=0x44;
Select(startflag); /* 選擇卡*/
ReadID: //Get_Uid(); /* 讀卡識別號碼*/
ReadBlock(0x00);
Uid[0]=RX_buf[1];
Uid[1]=RX_buf[2];
if(RX_buf[0]!=0x02){ /* 讀識別號碼是否正確*/
ES0 = 0;
_nop_();
FirstTime = 1;
goto NewCard; /* 不正確重新開始 */
}
else{
if(FirstTime==1){ /* 是否是首次讀到該卡的識別號碼 */
CardID1=RX_buf[1]; /* 保存識別號碼 */
CardID2=RX_buf[2];
}
if((CardID1!=RX_buf[1])||(CardID2!=RX_buf[2])){
ES0=0;
FirstTime=1;
goto NewCard; /* 識別號碼不相同重新開始 */
}
else{
if(FirstTime==1){ /* 首次讀到卡的識別號碼 */
FirstTime=0;
ReadBlock(0x01);
Uid[2]=RX_buf[1];
Uid[3]=RX_buf[2];
//ReadBlock(0x02);
//Uid[4]=RX_buf[1];
//Uid[5]=RX_buf[2];
//ReadBlock(0x03);
//Uid[6]=RX_buf[1];
//Uid[7]=RX_buf[2];
RI0=1;
TI0=0;
ES0=1;
//ptr = RX_buf; /* 指針指到卡的識別號 */
//ptr++;
ptr = Uid;
for(m=0;m<4;m++){ /* 送射頻卡的識別號 */
SendCommChar(HEXToASC((*ptr)/16));
SendCommChar(HEXToASC((*ptr)%16));
ptr++;
}
SendCommBuffer("\r\n",2);
_nop_();
OneBuzzer(40); /* 蜂鳴器響一聲 */
OpenComm(); /* 打開串行口準備串行通信 */
}
while(1){
Err1: if(!IsEmtpyRecComm()){ /* 是否接收到上位機命令?*/
i=GetCommChar();
if(i==':'){ /* 命令頭是否正確?*/
if(GetCommCharWait(&i,200)){
DataType=ASCToHEX(i); /* 得到命令類型 */
}
else goto Err;
CommandLen = 0;
for(m=100;m>=1;m=m/10){ /* 得到卡的塊地址 */
if(GetCommCharWait(&i,200)){
CommandLen += ASCToHEX(i)*m;
}
else goto Err;
}
ptr=TX_buf;
for(startflag=0;startflag<2;startflag++){ /* 得到待寫塊的數(shù)據(jù)字節(jié) */
if(GetCommCharWait(&i,200)){
m=ASCToHEX(i)*0x10;
}
else goto Err;
if(GetCommCharWait(&i,200)){
m+=ASCToHEX(i);
*ptr=m;
temp[startflag]=m;
ptr++;
}
else goto Err;
}
goto dd;
Err: CommRecBufferHead=CommRecBufferTail=0;
goto Err1;
dd: CommRecBufferHead=CommRecBufferTail=0;
switch(DataType){ /* 判定命令字 */
case 0: /* 寫塊數(shù)據(jù) */
m=WriteBlock_4K(CommandLen,temp[0],temp[1]);
SendCommBuffer("OK",2);
OneBuzzer(40); /* 蜂鳴器響一聲 */
break;
case 1: /* 讀塊數(shù)據(jù) */
m=ReadBlock(CommandLen);
ptr = RX_buf;
ptr++;
for(m=0;m<2;m++){ /* 從串行口送出塊數(shù)據(jù)(4 bytes) */
SendCommChar(HEXToASC((*ptr)/16));
SendCommChar(HEXToASC((*ptr)%16));
ptr++;
}
SendCommBuffer("\r\n",2);
OneBuzzer(40); /* 蜂鳴器響一聲 */
break;
case 2:
RF_OFF(); /* 關閉載頻輸出 */
break;
default:
_nop_();
} //switch
//RF_OFF();
} //if ':'
} /* 接收數(shù)據(jù) */
ReadBlock(0x00);
if(RX_buf[0]!=0x02) break;
} //while(1)
goto ReadID;
} /* 如果識別號相同 */
} /* 讀射頻卡識別號正確 */
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -