//-----------------------------------------------------------------------------
//
// 文件名:SMBus_Master_F33x.c
//
// 编写人:JS
//
// 编写时间:2004/1/3
//
// 目标器件: C8051F33x
//
// 编译工具: Silicon Laboratories IDE
//
//-----------------------------------------------------------------------------
//程序描述:
// C8051F330作为主器件,C8051F310作为从器件,定时器1为I2C时钟源,定时器3为SCL低电平超时检测,
//此程序为单字节收发.收发数据可以由用户自己定义。
//-----------------------------------------------------------------------------
//头文件包含
//-----------------------------------------------------------------------------
#include <c8051f330.h>
//-----------------------------------------------------------------------------
//常量定义
//-----------------------------------------------------------------------------
#define SYSCLK 24500000 // 系统工作频率
#define SMB_FREQUENCY 50000 // SCL时钟
#define WRITE 0x00 // SMBus 写命令
#define READ 0x01 // SMBus 读命令
//-----------------------------------------------------------------------------
// 设备地址 (高7位)
//-----------------------------------------------------------------------------
#define F310_SLAVE 0xf0 // 从机设备地址
//-----------------------------------------------------------------------------
// 状态向量(只有高4位)
//-----------------------------------------------------------------------------
#define SMB_MTSTA 0xE0 // 准备发送
#define SMB_MTDB 0xC0 // 发送数据字节
#define SMB_MRDB 0x80 // 接收数据字节
//-----------------------------------------------------------------------------------
//全局变量定义
//----------------------------------------------------------------------------------
unsigned char SMB_DATA_IN; // 接收缓冲字节
unsigned char SMB_DATA_OUT; // 发送缓冲字节
unsigned char TARGET; // 从机地址
bit SMB_BUSY; // 读写忙标志位
bit SMB_RW; // 读写标志位
sbit LED = P1^3; // LED在P3.3口
//-----------------------------------------------------------------------------
//定时器3特殊功能寄存器定义
//-----------------------------------------------------------------------------
sfr16 TMR3RL = 0x92;
sfr16 TMR3 = 0x94;
//------------------------------------------------------------------------------------
// 函数定义
//------------------------------------------------------------------------------------
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; // 使用内部振荡器(24500000)
Port_Init (); // 内部交叉开关及I/O初始化
Timer1_Init (); // 定时器1初始化,作为SMBus的时钟源
Timer3_Init (); // 定时器3初始化,作为SMBus SCL信号低电平
// 超时检测
SMBus_Init (); // 初始化并使能SMBus
EIE1 |= 1; // SMBus 中断使能
IE |= 0x20; // 定时器2中断使能
EA = 1; // 总中断使能
//------------------------初始化结束----------------------------------------
i = 0; // 数据发送计数
error = 0; // 通讯失败计数
LED = 0; // 关闭LED
while (1)
{
for (i=0;i<255;i++)
{
SMB_DATA_OUT = i; // 定义要发送的数据
TARGET = F310_SLAVE; // 从机地址
SMB_Write();
TARGET = F310_SLAVE;
SMB_Write();
if(SMB_DATA_IN != SMB_DATA_OUT)
error++;
LED = (!LED); // LED 状态取反
}
}
}
//------------------------------------------------------------------------------------
// SMBus发送程序
//------------------------------------------------------------------------------------
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;
}
//------------------------------------------------------------------------------------
// 定时器3初始化程序
//------------------------------------------------------------------------------------
void Timer3_Init (void)
{
TMR3CN = 0x00; // 定时器3工作在16位自动重装入方式
TMR3 = -(SYSCLK/12/40); // 定时器3配制为25ms溢出
TMR3RL = -(SYSCLK/12/40);
CKCON &= ~0x40; // 定时器3时钟源=SYSCLK/12
TMR3 |= 0x04; // 使能定时器3
}
//------------------------------------------------------------------------------------
// 定时器1初始化
//------------------------------------------------------------------------------------
void Timer1_Init (void)
{
CKCON &= ~0x0B; // 定时器1时钟源 = SYSCLK / 12
TMOD = 0x20; // 定时器1工作在8位自动重装入方式
TH1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TL1 = -(SYSCLK/SMB_FREQUENCY/12/3);
TR1 = 1; // 定时器1使能
}
//-----------------------------------------------------------------------------------
// I/O口初始化
//-----------------------------------------------------------------------------------
void Port_Init (void)
{
XBR0 = 0x04; // SMBus 分配到P0.0、P0.1
XBR1 = 0x40;
P0MDIN = 0xFF;
P0MDOUT = 0x00;
P1MDOUT = 0xff;
}
//------------------------------------------------------------------------------------
// SMBus中断服务程序
//------------------------------------------------------------------------------------
void SMBus_ISR (void) interrupt 7
{
bit FAIL; // 通讯失败标志位