关于c8051f020 i2c 通信

来源:互联网 发布:怪物猎人p3锤子数据库 编辑:程序博客网 时间:2024/05/18 01:02

#include <stdio.h>

#include <C8051F020.h>

#include<intrins.h>

 

 

 

/**********************常量及全局变量**************************************************/

#define Smb_Contrl_init0x44//IIC控制寄存器初始化

#define Smb_Clk_init0x22//IIC时钟寄存器初始化

#define Smb_StartEIE1|0x02//启动IIC中断服务

 

#define uchar unsigned char 

#define uint  unsigned int

#define read  0x81     //add-read for 

#define write 0x80

 

/**************************************************************************************/

 

 

/*************************************************************************************

* 全局变量

*************************************************************************************/

unsigned char Command;//命令缓存

unsigned char *I2CDataBuff;//待法发数据、接收数据指针

unsigned char ByteNumber;

bit BusBusy;//总线忙

 

 

 

//*********************************************************************

//函数功能: uart0 init 

//input   :  none

//output  :  none

//*********************************************************************

void uart0_init()

{

SCON0 = 0x50;     //work at  mode 1

PCON  = 0x80;      //speed of 2

CKCON = 0x10;      //T1M = 1;          //system clock

TMOD  = 0x20;       //timer 1 mode 2

 

TL1   = 0xf4;//115200 8 1 0

TH1   = 0xf4;

 

TR1   = 1;      // timer 1 open

 

}

 

 

//*********************************************************************

//*****函数功能: 外部中断0,初始化

//*****input   :  none

//*****output  :  none

//*********************************************************************

void int0_init()

{

 

IT0 = 1;    // 下降沿触发

EX0 = 1;    //allowed int 0

 

}

 

//*********************************************************************

//*****函数功能: delay time function

//*****input   :  n us delay

//*****output  :  none

//*********************************************************************

void delayus ( uint us )

{

while( us )

{

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();

_nop_();

--us;

}

}

 

 

//*********************************************************************

//函数功能: system clock init

//input   :  none

//output  :  none

//*********************************************************************

void sysclk_init (void)

{

   int i;                              // delay counter

   OSCXCN = 0x67;                      // start external oscillator with

                                       // 18.432MHz crystal

   for (i=0; i < 256; i++) ;           // Wait for osc. to start up

   while (!(OSCXCN & 0x80)) ;          // Wait for crystal osc. to settle

   OSCICN = 0x88;                      // select external oscillator as SYSCLK

                                       // source and enable missing clock

                                       // detector

  //OSCICN = 0x07;   //interal 16MHZ

}

 

 

//*********************************************************************

//函数功能: system interface init

//input   :  none

//output  :  none

//*********************************************************************

void system_init()

{

 

WDTCN  =0xde;     //禁止看门狗

WDTCN = 0xad;

 

P74OUT = 0xff;

P3MDOUT = 0xff;

 

XBR0 = 0x07;     //check to uart0,SPI ,.enable p0.6--sda;p0.7---scl

XBR1 = 0x04;     //check int0 

XBR2 = 0x40;     //OPEN 

 

}

 

/***********************************************************************************

* 函数名称:SMBusInit;

*

* 函数功能描述:SMBus初始化;

*              

* 输入参数:none;

*

* 返回数据:none;

*

* 注意:    none;

************************************************************************************/

void SMBusInit(void)//SMBus初始化

{

SMB0CN=Smb_Contrl_init; //SMBus控制寄存器

SMB0CR=Smb_Clk_init;//SCL速率设置l_0xed--0xf0

EIE1=Smb_Start;//开启中断

}

 

/*************************************************************************************

* 函数名称:at24cXX_Read_byte;

*

* 函数功能描述:24cXX器件按字节读取;

*              

* 输入参数:unsigned char类型BytesAddress,读出数据的24C01的操作地址;

*           unsigned char类型chip_cs,多片存储器片选或02以上单片存储阵列页地址选择

*此项默认值为0;

*

* 返回数据:unsigned char类型,返回值是形参地址读回的数据;

*

* 注意:    使用前请根据具体器件改动相应头文件宏定义;

************************************************************************************/

unsigned char *At24C_RdByte (unsigned char BytesAddress)//按字节读24C系列器件

{

unsigned char Re_Dat;

 

 

while (BusBusy);

*I2CDataBuff = BytesAddress;

BusBusy      = 1;

AA           = 1;

ByteNumber   = 1;

Command      = write;

STA          =1;

 

 

//while (BusBusy);

I2CDataBuff  = &Re_Dat;

BusBusy      = 1;

AA           = 1;

ByteNumber   = 12;

 

Command      = read;

STA          = 1;

 

if(BusBusy == 1)

{

 

P6 = 0xf0;

//没有中断!!!!!!!!!!!!!!

 

}

//while (BusBusy);

 

return &Re_Dat;

}

 

 

void SMBusService (void);

 

 

main()

{

sysclk_init();   //system clock

system_init();   //系统初始化

 

 

int0_init();     

uart0_init();

 

 

    SMBusInit();

BusBusy = 0;

EA = 1;

 

 

while(1)

{};

 

}

 

 

 

 

 

 

 

 

 

//*********************************************************************

//*****函数功能: 外部中断0,检测attb信号

//*****input   :  none

//*****output  :  none

//*********************************************************************

void int0() interrupt 0

{   

    uchar j,*p,i = 0;

 

EX0 = 0;  //disable int 0

    p= At24C_RdByte( i );

 

for( j=0; j<3; j++)

{

 

SBUF0 =  *p;

p++;

 

    while( TI0==0);

    TI0=0;

}

 

 

EX0         = 1;  //allowed int 0

 

}

 

 

 

 

 

 

/***********************************************************************************

* 函数名称:SMBusService;

*

* 函数功能描述:SMBus中断响应服务程序,判断状态码进行下步操作;

*              

* 输入参数:none;

*

* 返回数据:none;

*

* 注意:    none;

************************************************************************************/

void SMBusService (void) interrupt 7

{

 

switch (SMB0STA)

{

case 0x08: //0x08起始条件已发送

SMB0DAT=Command;

STA=0; 

 

break;

 

case 0x10://0x10 重复起始条件已发送

SMB0DAT=Command;

STA=0;

break;

case 0x18://0x18 地址+W已发送收到ACK

if (ByteNumber>0)

{

SMB0DAT=*I2CDataBuff;

I2CDataBuff++;

ByteNumber--;

 

}

else

{

STO=1;

BusBusy=0;

}

break;

 

case 0x20://0x20 地址+W 已发送收到NACK,从器件不应答发送STOP + START 重试

STO=1;

STA=1;

break;

 

case 0x28://0x28 数据字节已发送收到ACK

if (ByteNumber>0)

{

SMB0DAT=*I2CDataBuff;

I2CDataBuff++;

ByteNumber--;

}

else

{

STO=1;

BusBusy=0;

}

break;

 

case 0x30://0x30 数据字节已发送收到NACK,从器件不应答发送STOP + START 重试

STO=1;

STA=1;

break;

 

case 0x38://0x38 竞争失败

STO=1;

STA=1;

break;

//---------------read dat----------------------------------------------------

 

case 0x40://0x40 地址+R 已发送,收到ACK

if(ByteNumber<=1) AA=0; 

else AA=1; // 在应答周期ACK

if (ByteNumber==0)

{

STO=1;

BusBusy=0; // 释放SMBus

}

break;

 

case 0x48://0x48 地址+R 已发送收到NACK,从器件不应答发送重复起始条件重试

STA=1;

break;

 

case 0x50://0x50 收到数据字节ACK 已发送

if (ByteNumber>0)

{

*I2CDataBuff=SMB0DAT;

I2CDataBuff++;

ByteNumber--;

}

if (ByteNumber==1) AA=0;   //每次写完或读完 AA=0  ,at the end : ByteNumber = 1.

break;

 

case 0x58://0x58 收到数据字节NACK 已发送

*I2CDataBuff=SMB0DAT;

STO=1;

BusBusy=0; // 释放SMBus

 

break;

default:// 其它状态码没有意义,复位SMBus

STO=1; 

BusBusy=0; 

break;

}

SI=0; // 清除中断标志

}

 

/************************************************************************************

* 文件结束

************************************************************************************/

忙线处理不正确,可能是smb的中断没有弄好,明天再弄一下。

原创粉丝点击