📄 smbus.c
字号:
//SMBUS.C
//------------------------------------------------------//
// YnKing 原创,转载请注明出处
// http://www.21mcu.com/
// ynpsps@sina.com
//------------------------------------------------------//
#include <C8051F020.H>
#include "SMBUS.H"
#include "API/API.H"
SMBUS_ROM24_Device ROM24CXX;
//------------------------------------------------------//
// SMBUS INIT //
//------------------------------------------------------//
void SMBUS_INIT(void)
{
SMB0CN = 0x44; // 允许SMBus 在应答周期发送ACK
// SMBUS总线速度 = SYSCLK/(256-SMB0CR)
// SMB0CR = 256-(SYSCLK/SMBUS总线速度)
SMB0CR = -(SYSCLK/200000);
//SMB0CR = -80; // SYSCLK = 8MHz , SMBus 时钟频率 = 100kHz.
//EIE1 |= 2; // SMBus 中断允许
// 初始化ROM24设备
//--- 24C256 ---
#if SMBUS_ROM24_Enable == 1
SMBUS_ROM24_Device_Init(&ROM24CXX , 0 , 2 , 32); // 器件地址=0 ; 器件寻址宽度2字节 ; 器件写页面大小32字节
#endif
}
//======================================================//
// ROM24 部 分 //
//======================================================//
#if SMBUS_ROM24_Enable == 1
//-----------------------------------//
// ROM24 设备初始化 //
//-----------------------------------//
void SMBUS_ROM24_Device_Init(SMBUS_ROM24_Device *device , unsigned char chip_addr , unsigned char addrwidth , unsigned char pagesize)
{
device->IsOpen = 1;
device->Chip_Addr = chip_addr; // 器件地址
device->AddrWidth = addrwidth; // 器件内部地址宽度
device->PageSize = pagesize; // 器件写页面大小
}
//------------------------------------------------------//
// SMBUS 写字节 //
//------------------------------------------------------//
void SMBUS_ROM24_WBS(SMBUS_ROM24_Device *device , unsigned int byte_address , char *dout , unsigned char len)
// 注释 : 本子程序不使用中断,在程序中查询中断标志
// 参数 :
// chip_addr : 器件地址 = 0 ~ 7
// byte_address : 器件内部地址
// dout : 写入器件中的数据
{
unsigned char pageout;
if(device->IsOpen != 1)return;
SMBUS_ROM24_WBS_ReSTART:
AA = 1;
// 总线开始
STA = 1;
while(!SI);
// 写器件地址
if(SMB0STA != SMB_START) goto SMBUS_ROM24_WBS_Err;
SMB0DAT = 0xa0|(device->Chip_Addr<<1);
STA = 0;
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTADDACK)
{
STO = 1;
SI = 0;
goto SMBUS_ROM24_WBS_ReSTART;
}
if(device->AddrWidth == 2)
{
// 写高位地址
SMB0DAT = ((unsigned char*)(&byte_address))[0];
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_WBS_Err;
}
// 写低位地址
SMB0DAT = ((unsigned char*)(&byte_address))[1]; // 写
SI = 0;
pageout = byte_address&(device->PageSize-1);
for(;len!=0;len--)
{
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_WBS_Err;
if(pageout >= device->PageSize)
{ // 越界,需要重新开始
SMBUS_ROM24_WBS_Re:
STO = 1;
STA = 1;
SI = 0;
while(!SI);
if(SMB0STA != SMB_START) goto SMBUS_ROM24_WBS_Err;
SMB0DAT = 0xa0|(device->Chip_Addr<<1);
STA = 0;
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTADDACK) goto SMBUS_ROM24_WBS_Re;
if(device->AddrWidth == 2)
{
// 写高位地址
SMB0DAT = ((unsigned char*)(&byte_address))[0];
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_WBS_Err;
}
// 写低位地址
SMB0DAT = ((unsigned char*)(&byte_address))[1]; // 写
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_WBS_Err;
pageout = 0;
}
// 写数据
SMB0DAT = *dout;
dout++;
SI = 0;
pageout++;
byte_address++;
}
while(!SI);
// 完成
SMBUS_ROM24_WBS_Err:
STO = 1;
SI = 0;
}
//------------------------------------------------------//
// SMBUS 读字节 //
//------------------------------------------------------//
void SMBUS_ROM24_RBS(SMBUS_ROM24_Device *device , unsigned int byte_address , char *din , unsigned char len)
// 注释 : 本子程序不使用中断,在程序中查询中断标志
// 参数 :
// device : 设备信息
// byte_address : 器件内部地址
// din : 读出器件中的数据
{
if(device->IsOpen != 1)return;
SMBUS_ROM24_RBS_ReSTART:
AA = 1;
// 总线开始
STA = 1;
while(!SI);
// 写器件地址
if(SMB0STA != SMB_START) goto SMBUS_ROM24_RBS_Err;
SMB0DAT = 0xa0|(device->Chip_Addr<<1);
STA = 0;
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTADDACK)
{
STO = 1;
SI = 0;
goto SMBUS_ROM24_RBS_ReSTART;
}
if(device->AddrWidth == 2)
{
// 写高位地址
SMB0DAT = ((unsigned char*)(&byte_address))[0];
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_RBS_Err;
}
// 写低位地址
SMB0DAT = ((unsigned char*)(&byte_address))[1]; // 写
SI = 0;
while(!SI);
if(SMB0STA != SMB_MTDBACK) goto SMBUS_ROM24_RBS_Err;
// 重新开始
STA = 1;
SI = 0;
while(!SI);
if(SMB0STA != SMB_RP_START) goto SMBUS_ROM24_RBS_Err;
STA = 0;
// 发送读器件命令
SMB0DAT = 0xa1|(device->Chip_Addr<<1);
SI = 0;
while(!SI);
if(SMB0STA != SMB_MRADDACK) goto SMBUS_ROM24_RBS_Err;
//AA = 0;
SI = 0;
for(;len!=0;len--)
{
while(!SI);
if(SMB0STA != SMB_MRDBACK) goto SMBUS_ROM24_RBS_Err;
// 读数据
*din = SMB0DAT;
din++;
if(len==1)
{ // 最后一个字节不发送ACK
AA = 0;
}
SI = 0;
}
while(!SI);
// 完成
SMBUS_ROM24_RBS_Err:
STO = 1;
SI = 0;
}
#endif
//----------------------------------//
// RFID HY502 设备驱动 //
//----------------------------------//
#if HY502_Enable == 1
bit SMBUS_WaitSI(unsigned char s)
{
unsigned char c;
for(c=10;c!=0;c++)
{
if(SI==1)
{
if(SMB0STA == s)
return 1;
else
break;
}
delay_ms(1);
}
STO = 1;
SI = 0;
delay_ms(5);
return 0;
}
//----------------//
// 读数据包 //
//----------------//
bit HY502_RP(unsigned char *p)
{
bit r=0;
unsigned char c,cCheckSum;
c=0;
HY502_RP_ReSTART:
AA = 1;
// 总线开始
STA = 1;
if(!SMBUS_WaitSI(SMB_START)) goto HY502_RP_ReSTART;
// 发送读命令
SMB0DAT = 0xa1|(HY502_Addr<<1);
STA = 0;
SI = 0;
if(!SMBUS_WaitSI(SMB_MRADDACK))
{
c++;
if(c>=100)
goto HY502_RP_Err;
else
goto HY502_RP_ReSTART;
}
SI = 0;
p[0] = 2;
cCheckSum = 0;
for(c=0;c<p[0];c++)
{
if(!SMBUS_WaitSI(SMB_MRDBACK)) goto HY502_RP_Err;
//while(!SI);
//if(SMB0STA != SMB_MRDBACK) goto HY502_RP_Err;
// 读数据
p[c] = SMB0DAT;
cCheckSum += p[c];
if(c >= p[0])
{ // 最后一个字节不发送ACK
AA = 0;
}
SI = 0;
}
while(!SI);
//if(cCheckSum)goto HY502_RP_Err;
r=1;
HY502_RP_Err:
STO = 1;
SI = 0;
return r;
}
//----------------//
// 写数据包 //
//----------------//
bit HY502_WP(unsigned char *p)
{
bit r=0;
unsigned char c,cCheckSum;
c=0;
HY502_WP_ReSTART:
AA = 1;
// 总线开始
STA = 1;
if(!SMBUS_WaitSI(SMB_START))
{
c++;
if(c>=100)
goto HY502_WP_Err;
else
goto HY502_WP_ReSTART;
}
//while(!SI);
// 发送读命令
//if(SMB0STA != SMB_START) goto HY502_WP_ReSTART;
SMB0DAT = 0xa0|(HY502_Addr<<1);
STA = 0;
SI = 0;
if(!SMBUS_WaitSI(SMB_MTADDACK)) goto HY502_WP_ReSTART;
/*while(!SI);
if(SMB0STA != SMB_MTADDACK)
{
STO = 1;
SI = 0;
goto HY502_WP_ReSTART;
}*/
cCheckSum = 0;
for(c=0;c<p[0];c++)
{
SMB0DAT = p[c];
SI = 0;
cCheckSum ^= p[c];
if(!SMBUS_WaitSI(SMB_MTDBACK)) goto HY502_WP_Err;
//while(!SI);
//if(SMB0STA != SMB_MTDBACK) goto HY502_WP_Err;
}
// 最后发送校验和
SMB0DAT = cCheckSum;
SI = 0;
if(!SMBUS_WaitSI(SMB_MTDBACK)) goto HY502_WP_Err;
//while(!SI);
//if(SMB0STA != SMB_MTDBACK) goto HY502_WP_Err;
r = 1;
HY502_WP_Err:
STO = 1;
SI = 0;
return r;
}
//------------------------//
// 读 卡 类 型 //
//------------------------//
code unsigned char RCardTypeCmd[] = {0x02,0x19};
unsigned int HY502_RCardType(void)
{
unsigned char t[5];
if(!HY502_WP(RCardTypeCmd))return 0;
if(!HY502_RP(t))return 0;
return *((unsigned int*)(&t[2]));
}
//------------------------//
// 读 卡 ID 号 //
//------------------------//
code unsigned char RCardIDCmd[] = {0x02,0x20};
unsigned long HY502_RCardID(void)
{
unsigned char t[7];
if(!HY502_WP(RCardIDCmd))return 0;
if(!HY502_RP(t))return 0;
return *((unsigned long*)(&t[2]));
}
//------------------------//
// 卡 休 眠 //
//------------------------//
code unsigned char CardIdleCmd[] = {0x02,0x12};
bit HY502_CardIdle(void)
{
unsigned char t[3];
if(!HY502_WP(CardIdleCmd))return 0;
if(!HY502_RP(t))return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -