?? smbus_master_f33x.c
字號(hào):
//-----------------------------------------------------------------------------
//
// 文件名:SMBus_Master_F33x.c
//
// 編寫人:JS
//
// 編寫時(shí)間:2004/1/3
//
// 目標(biāo)器件: C8051F33x
//
// 編譯工具: Silicon Laboratories IDE
//
//-----------------------------------------------------------------------------
//程序描述:
// C8051F330作為主器件,C8051F310作為從器件,定時(shí)器1為I2C時(shí)鐘源,定時(shí)器3為SCL低電平超時(shí)檢測(cè),
//此程序?yàn)閱巫止?jié)收發(fā).收發(fā)數(shù)據(jù)可以由用戶自己定義。
//-----------------------------------------------------------------------------
//頭文件包含
//-----------------------------------------------------------------------------
#include <c8051f330.h>
//-----------------------------------------------------------------------------
//常量定義
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // 系統(tǒng)工作頻率
#define SMB_FREQUENCY 50000 // SCL時(shí)鐘
#define WRITE 0x00 // SMBus 寫命令
#define READ 0x01 // SMBus 讀命令
//-----------------------------------------------------------------------------
// 設(shè)備地址 (高7位)
//-----------------------------------------------------------------------------
#define F310_SLAVE 0xf0 // 從機(jī)設(shè)備地址
//-----------------------------------------------------------------------------
// 狀態(tài)向量(只有高4位)
//-----------------------------------------------------------------------------
#define SMB_MTSTA 0xE0 // 準(zhǔn)備發(fā)送
#define SMB_MTDB 0xC0 // 發(fā)送數(shù)據(jù)字節(jié)
#define SMB_MRDB 0x80 // 接收數(shù)據(jù)字節(jié)
//-----------------------------------------------------------------------------------
//全局變量定義
//----------------------------------------------------------------------------------
unsigned char SMB_DATA_IN; // 接收緩沖字節(jié)
unsigned char SMB_DATA_OUT; // 發(fā)送緩沖字節(jié)
unsigned char TARGET; // 從機(jī)地址
bit SMB_BUSY; // 讀寫忙標(biāo)志位
bit SMB_RW; // 讀寫標(biāo)志位
sbit LED = P1^3; // LED在P3.3口
//-----------------------------------------------------------------------------
//定時(shí)器3特殊功能寄存器定義
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92;
sfr16 TMR3 = 0x94;
//------------------------------------------------------------------------------------
// 函數(shù)定義
//------------------------------------------------------------------------------------
void SMBus_Init (void);
void Timer1_Init (void);
void Timer3_Init (void);
void Port_Init (void);
void SMBus_ISR (void);
void Timer3_ISR (void);
void SMB_Write (void);
void SMB_Read (void);
//------------------------------------------------------------------------------------
// 主程序
//------------------------------------------------------------------------------------
void main (void)
{
unsigned char i, error;
PCA0MD &= ~0x40; // 禁止看門狗
OSCICN |= 0x03; // 使用內(nèi)部振蕩器(24500000)
Port_Init (); // 內(nèi)部交叉開關(guān)及I/O初始化
Timer1_Init (); // 定時(shí)器1初始化,作為SMBus的時(shí)鐘源
Timer3_Init (); // 定時(shí)器3初始化,作為SMBus SCL信號(hào)低電平
// 超時(shí)檢測(cè)
SMBus_Init (); // 初始化并使能SMBus
EIE1 |= 1; // SMBus 中斷使能
IE |= 0x20; // 定時(shí)器2中斷使能
EA = 1; // 總中斷使能
//------------------------初始化結(jié)束----------------------------------------
i = 0; // 數(shù)據(jù)發(fā)送計(jì)數(shù)
error = 0; // 通訊失敗計(jì)數(shù)
LED = 0; // 關(guān)閉LED
while (1)
{
for (i=0;i<255;i++)
{
SMB_DATA_OUT = i; // 定義要發(fā)送的數(shù)據(jù)
TARGET = F310_SLAVE; // 從機(jī)地址
SMB_Write();
TARGET = F310_SLAVE;
SMB_Write();
if(SMB_DATA_IN != SMB_DATA_OUT)
error++;
LED = (!LED); // LED 狀態(tài)取反
}
}
}
//------------------------------------------------------------------------------------
// SMBus發(fā)送程序
//------------------------------------------------------------------------------------
void SMB_Write (void)
{
while (SMB_BUSY);
SMB_BUSY = 1;
SMB_RW = 0;
STA = 1;
}
//------------------------------------------------------------------------------------
// SMBus接收程序
//------------------------------------------------------------------------------------
void SMB_Read (void)
{
while (SMB_BUSY);
SMB_BUSY = 1;
SMB_RW = 1;
STA = 1;
while (SMB_BUSY);
}
//------------------------------------------------------------------------------------
// SMBus初始化
//------------------------------------------------------------------------------------
void SMBus_Init (void)
{
SMB0CF = 0x5D;
SMB0CF |= 0x80;
}
//------------------------------------------------------------------------------------
// 定時(shí)器3初始化程序
//------------------------------------------------------------------------------------
void Timer3_Init (void)
{
TMR3CN = 0x00; // 定時(shí)器3工作在16位自動(dòng)重裝入方式
TMR3 = -(SYSCLK/12/40); // 定時(shí)器3配制為25ms溢出
TMR3RL = -(SYSCLK/12/40);
CKCON &= ~0x40; // 定時(shí)器3時(shí)鐘源=SYSCLK/12
TMR3 |= 0x04; // 使能定時(shí)器3
}
//------------------------------------------------------------------------------------
// 定時(shí)器1初始化
//------------------------------------------------------------------------------------
void Timer1_Init (void)
{
CKCON &= ~0x0B; // 定時(shí)器1時(shí)鐘源 = SYSCLK / 12
TMOD = 0x20; // 定時(shí)器1工作在8位自動(dòng)重裝入方式
TH1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TL1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TR1 = 1; // 定時(shí)器1使能
}
//-----------------------------------------------------------------------------------
// I/O口初始化
//-----------------------------------------------------------------------------------
void Port_Init (void)
{
XBR0 = 0x04; // SMBus 分配到P0.0、P0.1
XBR1 = 0x40;
P0MDIN = 0xFF;
P0MDOUT = 0x00;
P1MDOUT = 0xff;
}
//------------------------------------------------------------------------------------
// SMBus中斷服務(wù)程序
//------------------------------------------------------------------------------------
void SMBus_ISR (void) interrupt 7
{
bit FAIL; // 通訊失敗標(biāo)志位
bit ADDR_SEND; // 發(fā)送從機(jī)地址標(biāo)志位
switch (SMB0CN & 0xF0) // 狀態(tài)向量
{
case SMB_MTSTA:
SMB0DAT = TARGET;
SMB0DAT |= SMB_RW; // 裝入從機(jī)地址和讀寫位
STA = 0; // 清發(fā)送位
ADDR_SEND = 1; //此時(shí)發(fā)送的是從機(jī)地址和讀寫位,置標(biāo)志位為1
break;
//----------------------------------------------------------------------------
// 主機(jī)發(fā)送:數(shù)據(jù)發(fā)送
case SMB_MTDB:
if (ACK) // 從機(jī)應(yīng)答信號(hào)?
{
if (ADDR_SEND) // 前一次發(fā)送的是否是從機(jī)地址
{
ADDR_SEND = 0; // 如是從機(jī)地址,下一次將不再發(fā)送從機(jī)地址
if (SMB_RW==WRITE) // 前一次發(fā)送的命令是讀還是寫
{
SMB0DAT = SMB_DATA_OUT; // 前一次發(fā)送的命令如果是寫,就裝入要發(fā)送的數(shù)據(jù)
}
else {} // 如果這個(gè)命令是讀, 程序?qū)⒉粫?huì)寫SMB0DAT
// (切換到接收模式)
}
else // 前一次發(fā)送的不是從機(jī)地址
{
STO = 1; // 置停止位為1
SMB_BUSY = 0; // 設(shè)置SMBus總線空閑
}
}
else // 如果接收到的是非應(yīng)答信號(hào),
{
FAIL = 1; // 就設(shè)置失敗標(biāo)志位,并退出中斷
}
break;
// 主機(jī)接收:?jiǎn)巫止?jié)接收
case SMB_MRDB:
SMB_DATA_IN = SMB0DAT; // 保存接收字節(jié)
SMB_BUSY = 0; // 設(shè)置SMBus總線空閑
ACK = 0; // 發(fā)送應(yīng)答信號(hào)
STO = 1; // 發(fā)送停止位
break;
default:
FAIL = 1;
break;
}
if (FAIL) // 是否有通訊失敗,
{
SMB0CN &= ~0x40; // 復(fù)位總線
SMB0CN |= 0x40;
SMB_BUSY = 0; // SMBus 總線空閑
}
SI=0; // 清SMBus中斷為標(biāo)志位
}
//-----------------------------------------------------------------------------------
// 定時(shí)器3中斷服務(wù)程序
//-----------------------------------------------------------------------------------
//
//定時(shí)器3中斷表示SMBus總線的SCL位號(hào)低電平超時(shí)
// 這里將禁止和重新使能SMBus總線
//
void Timer3_ISR (void) interrupt 14
{
SMB0CN &= ~0x40; // 禁止SMBus
SMB0CN |= 0x40; // 重新使能SMBus
TMR3CN &= ~0x80; // 清定時(shí)器3中斷標(biāo)志位
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -