📄 f020smbus.txt
字号:
--------------------------------------------------------------------------------
/***********************************************************************************/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/***********************************************************************************/
#include"common.h"
char SLAW,DATA1[64]; // 保存从地址+ WRITE 位
char SLAR; // 保存从地址+ WRITE 位
char WORD,WORDADR; // 保存被收/发的数据字节
char xdata sendnumber; // 保存被收/发的数据字节的数目
//unsigned char xdata WORDADR; // 保存被传送的数据在24C02中的首地址.
unsigned char xdata SENDMODE; // SENDMODE作读/写控制字
unsigned char xdata i,j,k,sla,n,m,p;
bit SM_BUSY; // 忙碌标志位
unsigned char check; // 测试用的工作变量
void main (void)
{
system_initial();
delay_nus(100);
i=0x10;
sla=CHIP_A;
for (j=0;j<0x40;j++) // 向24C02的000地址依次写入64个数据,
{ // 64个数据的数值从10H---4FH
smbus_send(sla, j, i,0x01); // 写入AT24C02
i++;
}
for (j=0;j<0x40;j++) // 从24C02的00地址依次连续读出64个数据,
{ // 64个数据的数值应该是从10H---3FH(连续存放)
check=smbus_read(sla, j,0x01);
DATA1[j]=check; // 读出来的数据依次连续存入数组DATA[]中
}
delay_nms(1000);
while(1);
}
/***********************************************************************************/
/**/
/**/
/***********************************************************************************/
void smbus_send(char chip, char wordadr, char word,char number)
{
SENDMODE=0x01;
sendnumber=number+1;
while(SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // 置SM_BUSY位(忙碌标志位)为1
SLAW = (chip| WRITE); // COMMAND = 7 个地址位 + 一位WRITE.
WORD = word; // WORD中存放要送到24C02中去的数据(8位)
WORDADR = wordadr; // OP_CODE 中存放被传送数据送入24C02的首地址.
STO = 0;
STA = 1; // 启动数据传输
while(SM_BUSY); // 等待传输完成
}
/***********************************************************************************/
/**/
/**/
/***********************************************************************************/
char smbus_read(char chip, char wordadr,char number)
{
sendnumber=number;
SENDMODE=0;
while(SM_BUSY); // 若SMBUS忙碌就等待
SM_BUSY = 1; // 置SM_BUSY位(忙碌标志位)为1
SLAR = (chip| READ); // COMMAND = 7 个地址位 + 一位READ
WORDADR = wordadr; // OP_CODE 中存放从24C02读出数据的的首地址.
STO = 0;
STA = 1; // 启动传输
while(SM_BUSY); // 等待传输完成
return WORD; // 返回读出来的数据(一个字节)
}
void SMBUS_ISR (void) interrupt 7 // 中断服务程序
{
switch (SMB0STA)
{ // 根据中断状态码跳转
// (SMB0STA 是中断状态寄存器)
case SMB_START: // 0x08, (MT & MR) 发送起始位
SMB0DAT = SLAW ; // 装入被访问的从芯片的写地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_RP_START: // 0x10,(MT & MR) 重复发送起始位
SMB0DAT = SLAR; // 装入被访问的从芯片的读地址
STA = 0; // 人工清除 STA 位
SI = 0; // 清除中断标志位
break;
case SMB_MTADDACK: // 0x18 ,(MT) 发送从地址 + W 后收到ACK
SMB0DAT = WORDADR;
SI = 0; // 清除中断标志位
break;
case SMB_MTADDNACK: // 0x20,(MT) 发送从地址 + W 后收到NACK
STO = 1;
STA = 1;
SI = 0; // 清除中断标志位
break;
case SMB_MTDBACK: // 0x28,(MT) 发送数据后收到ACK
switch (SENDMODE)
{ // 检查低1位
case 1:
sendnumber--;
if(sendnumber)
SMB0DAT = WORD;
else
{
STO=1;
SM_BUSY=0;
}
break;
case 0:
STO = 0;
STA = 1;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
SI = 0;
break;
case SMB_MTDBNACK: // 0x30
STO = 1;
STA = 1;
SI = 0; // 清除中断标志
break;
case SMB_MRADDACK: // 0x40
AA = 0;
SI = 0;
break;
case SMB_MRADDNACK: //0x48
STO = 0;
STA = 1;
SI = 0;
break;
case SMB_MRDBNACK: //0x58
WORD = SMB0DAT;
STO = 1;
SM_BUSY = 0;
AA = 1;
SI = 0;
break;
default:
STO = 1;
SM_BUSY = 0;
break;
}
}
/***********************************************************************************/
/* end */
/***********************************************************************************/
/***********************************************************************************/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/**/
/***********************************************************************************/
#include"common.h"
extern bit SM_BUSY; // 忙碌标志位
void system_initial (void)
{
WDTCN = 0xde; // 关闭看们狗
WDTCN = 0xad;
clock_initial(); // 时钟初始化
XBR0 = 0x01; // 选交叉开关 :P0.0-->SDA,P0.1-->CLK
XBR2 = 0x40; // 交叉开关使能
SMB0CN = 0x44; // 允许SMBUS, 应答返回AA(低电平
SMB0CR = 0xc9; // SMBus 速率= 100 kHz,系统时钟为11.0592MHZ
EIE1 |= 2; // SMBus 中断使能
EA = 1; // 开中断
SM_BUSY = 0; // SM_BUSY是忙碌标志位
SI = 0; // SM_BUSY中断标志位
}
void clock_initial (void)
{
int i; // i 用于延时计数
OSCXCN = 0x67; // 先选择外捕振荡器,频率位11.0592MHZ
for (i=0; i < 256; i++) ; // 再延时(>1ms),
while (!(OSCXCN & 0x80)) ; // 等待外部晶振稳定
OSCICN = 0x88; // 选择外部晶振,允许时钟丢失检测
}
/*============================================================================*/
/*函数名称:delay.c */
/*函数功能:延时函数 */
/*函数说明:函数中的参数可以根据自己需要改变 */
/*编写日期:2007-1-26 */
/*============================================================================*/
/*============================================================================*/
/*函数头文件 */
/*============================================================================*/
#include "common.h"
#include "delay.h"
/*============================================================================*/
/*============================================================================*/
/*1us延时函数 */
/*============================================================================*/
void delay_1us(void) /*1us延时函数*/
{
_nop_();
}
/*============================================================================*/
/*N us延时函数 */
/*============================================================================*/
void delay_nus(unsigned int n) /*N us延时函数*/
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1us();
}
/*============================================================================*/
/*1ms延时函数 */
/*============================================================================*/
void delay_1ms(void) /*1ms延时函数*/
{
unsigned int i;
for (i=0;i<154;i++);
}
/*============================================================================*/
/*N ms延时函数 */
/*============================================================================*/
void delay_nms(unsigned int n) /*N ms延时函数*/
{
unsigned int i=0;
for (i=0;i<n;i++)
delay_1ms();
}
/*============================================================================*/
/*函数结束 */
/*============================================================================*/
#ifndef _common_H_
#define _common_H_
/************************************************************************************/
#include <c8051f020.h> // function declarations
#include <intrins.h>
#include <absacc.h>
#include <delay.h>
/************************************************************************************/
#define uint unsigned int //Data type definition
#define uchar unsigned char
#define ulong unsigned long
/************************************************************************************/
void clock_initial (void); //system clock initial
void SMBUS_ISR (void); //smbus_ISR
char smbus_read (char chip,char wordadr,char number);
void smbus_send (char chip,char wordadr, char word,char number);
void system_initial();
#define WRITE 0x00 //SMBUS Addressing byte write-flag
#define READ 0x01 //SMBUS Addressing byte read-flag
//Device addresses
#define CHIP_A 0xA0 //AT24C02 own addressing word
#define CHIP_B 0x70 //AT24C02 own addressing word
#define SMB_BUS_ERROR 0x00 //bud error
//MT is main transmitter ,MR is main receiver
#define SMB_START 0x08 //(MT & MR) sending starting byte
#define SMB_RP_START 0x10 //(MT & MR) Repeat starting byte
#define SMB_MTADDACK 0x18 //(MT) 发送从地址 + W 后收到ACK
#define SMB_MTADDNACK 0x20 //(MT) 发送从地址 + W 后收到NACK
#define SMB_MTDBACK 0x28 //(MT) 发送数据后收到ACK
#define SMB_MTDBNACK 0x30 //(MT) 发送数据后收到NACK
#define SMB_MTARBLOST 0x38 //(MT) 竞争失败
#define SMB_MRADDACK 0x40 //(MR) 发送从地址 + R 后收到 ACK
#define SMB_MRADDNACK 0x48 //(MR) 发送从地址 + R 后收到 NACK
#define SMB_MRDACK 0x50 //(MR) 收到数据字节 后已发送ACK
#define SMB_MRDBNACK 0x58 //(MR) 收到数据字节 后已发送NACK
/************************************************************************************/
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -