标题:
SI7021普通IO口模拟I2C例程
[打印本页]
作者:
avrjtag
时间:
2018-6-25 22:32
标题:
SI7021普通IO口模拟I2C例程
SI7021 普通IO口模拟I2C例程 兼容Si705x
单片机源程序如下:
/*-----------------------------------------------------------------------------
*
* Project: Silicon Labs Si7005 UDP Demo
*
*
* File Name: I2C.c
*
* Description: Use the I2C protocol to read and write registers on a device
*
* Revision History:
*
* 09/17/12 QHS Initial Release
*
*----------------------------------------------------------------------------*/
#include <compiler_defs.h>
#include <C8051F960_defs.h>
#include "Tick.h"
#include "I2C.h"
/* Maximum time to wait for a transfer to complete */
#define MAX_XFER_TIME 300 /* ms */
/* Maximum number of data bytes that can be read or written */
#define MAX_XFER_LENGTH 2
/* Number of I2C buses */
#define I2C_BUS_COUNT 2
/* Transfer request */
typedef struct
{
U8 Type;
U8 Status;
U8 Bus;
U8 Address;
U8 Length; /* 0,1,2 */
U8 Data[MAX_XFER_LENGTH];
} XFER;
/* Transfer type */
#define XFER_TYPE_WRITE 0x10
#define XFER_TYPE_READ 0x20
#define XFER_TYPE_WRITE_READ (XFER_TYPE_WRITE|XFER_TYPE_READ)
/* Transfer status */
#define XFER_STATUS_NONE 0x00
#define XFER_STATUS_SUCCESS 0x01
#define XFER_STATUS_ADDR_NAK 0x02
#define XFER_STATUS_DATA_NAK 0x03
#define XFER_STATUS_TIMEOUT 0x04
#define XFER_STATUS_ARBLOST 0x05
#define XFER_STATUS_BAD_LENGTH 0x06
#define XFER_STATUS_BAD_MODE 0x07
#define XFER_STATUS_BAD_STATE 0x08
/* Prototypes */
//void I2C_Transfer( void );
/* Global variables */
XFER Transfer;
U8 DataCount;
U8 CurrentBus = I2C_BUS_1;
U16 TransferStatus[8]={0};
U16 TransferStartTime;
/*****************************************************************************/
/* I2C_Init */
/*****************************************************************************/
void I2C_Init( void )
{
SFRPAGE = LEGACY_PAGE;
/* Enable SMBus on the crossbar */
XBR0 = 0x04;
XBR2 = 0x40;
/* Move SMBus to P1.5 and P1.6 for bus 1 */
P0SKIP = 0xFF;
P1SKIP = 0x1F;
/* Configure SMBus */
SMB0CF = 0xDC;
/* Timer 0 uses SYSCLK */
CKCON |= 0x04;
/* Configure timer 0 for SMBus bit rate (200 kHz) */
TCON = 0x10;
TMOD = 0x32;
TH0 = 0xDF;
/* Configure timer 3 for SCL low timeout (25ms) */
TMR3CN = 0x04;
TMR3RLH = 0x5D;
TMR3RLL = 0x3D;
/* Enable SMBus and timer 3 interrupts */
EIE1 |= 0x81;
}
#define SDIO_OUT P1MDOUT
#define SDIO_HEX 0x20
#define SCLK_HEX 0x40
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
#define READ 1
#define WRITE 0
#define IO2W_SENB0_ADDRESS 0x22
#define IO2W_SENB1_ADDRESS 0x40//0xC6
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
void _nop_(void);
//-----------------------------------------------------------------------------
// Externals
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// This is used just for debugging to detect when the si47xx is not responding.
// The 47xx should always ack 2-wire transactions. If it does not, there is a
// hardware problem that must be resolved.
//-----------------------------------------------------------------------------
static void die(void)
{
_nop_(); // put breakpoint here during debug.
}
void start(void)
{
SDIO_OUT |= SDIO_HEX; // Configure SDIO as push-pull
wait_us(1);
SCLK =1;
wait_us(1);
SDIO=1;
wait_us(5);
SDIO=0;
wait_us(5);
SCLK =0;
wait_us(50);
}
//-----------------------------------------------------------------------------
// Send a 2-wire stop. A STOP condition is defined as a low to high transition
// on the SDIO pin while SCLK is high.
//
// Pin drive status upon exit:
// SDIO = high (open-drain input)
// SCLK = high
//-----------------------------------------------------------------------------
void io2w_stop(void)
{
SDIO_OUT |= SDIO_HEX; // Configure SDIO as push-pull
SCLK = 0;
wait_us(5); // tf:IN + tLOW
SDIO = 0;
wait_us(5);
SCLK = 1;
wait_us(3); // tf:IN + tSU:STO
SDIO = 1;
}
//-----------------------------------------------------------------------------
// Write one byte of data.
//
// Inputs:
// wrdata: Byte to be written
//
// Pin drive status upon exit:
// SDIO = high (open-drain input)
// SCLK = high
//-----------------------------------------------------------------------------
void io2w_write_byte(U8 wrdata)
{
S8 i,Status;
SDIO_OUT |= SDIO_HEX; // Configure SDIO as push-pull
for ( i = 7; i >= 0; i-- )
{
SCLK = 0;
wait_us(1); // tf:IN
SDIO = ((wrdata >> i) & 0x01);
wait_us(2); // tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
}
Status=Slave_acknowledge();
}
//-----------------------------------------------------------------------------
// check the acknowledge
//
// Inputs:
// wrdata: Byte to be written
//
// Pin drive status upon exit:
// SDIO = high (open-drain input)
// SCLK = high
//-----------------------------------------------------------------------------
U8 Slave_acknowledge(void)
{
U8 i=0;
// check the acknowledge
SDIO_OUT &= ~(SDIO_HEX); // Configure SDIO as open-drain
SCLK = 0;
SDIO = 1; // Configure P0^7(SDIO) as a digital input
wait_us(2); // tf:IN + tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
SCLK = 0;
wait_us(1);
while (SDIO !=0)
{
i++;
if(i>250)
return 0; // ack not received. This should never happen. Device isn't responding.
}
return 1;
}
void Master_acknowledge(void)
{
// set the acknowledge
SCLK = 0;
SDIO_OUT |= SDIO_HEX; // Configure SDIO as push-pull
SDIO = 0;
wait_us(1); // tf:IN + tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
}
//-----------------------------------------------------------------------------
// Read one byte of data.
//
// Inputs:
// remaining bytes: Zero value indicates an ack will not be sent.
//
// Outputs:
// Returns byte read
//
// Pin drive status upon exit:
// SDIO = high (open-drain input) if no more bytes to be read
// SDIO = low (open-drain input) if read is to continue
// SCLK = high
//-----------------------------------------------------------------------------
U8 io2w_read_byte(void)
{
S8 i;
U8 rddata = 0;
SDIO_OUT &= ~(SDIO_HEX); // Configure SDIO as open-drain
for( i = 7; i >= 0; i-- )
{
SCLK = 0;
SDIO = 1; // Configure P0^7(SDIO) as a digital input
wait_us(1); // tf:IN
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
SI7021 普通IO口模拟I2C例程 兼容Si705x.rar
(261.29 KB, 下载次数: 17)
2018-6-25 22:32 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
qiang41194
时间:
2019-12-15 13:27
兼不兼容STC15W系列?
作者:
esmember
时间:
2020-6-28 09:47
不知道直接使用硬件的i2c怎么样,先研究一下,感谢。主要是在学习这个温湿度检测芯片。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1