📄 io2w.c
字号:
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f320.h>
#include <stddef.h>
#include "typedefs.h"
//-----------------------------------------------------------------------------
// Defines
//-----------------------------------------------------------------------------
#define READ 1
#define WRITE 0
#define IO2W_ADDRESS 0x20
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
sbit RSTB = P1^3;
sbit SENB = P1^2;
sbit SCLK = P1^1;
sbit SDIO = P0^7;
//-----------------------------------------------------------------------------
// Function prototypes
//-----------------------------------------------------------------------------
void wait_us(u16 us);
void wait_ns(u16 ns);
void _nop_(void);
//-----------------------------------------------------------------------------
// Externals
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// This is used just for debugging to detect when the si470x is not responding.
// The 470x 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.
}
//-----------------------------------------------------------------------------
// Send a 2-wire stop.
//-----------------------------------------------------------------------------
static void io2w_stop(void)
{
SCLK = 0;
wait_us(2); // tf:IN + tLOW
SDIO = 0;
wait_us(1);
SCLK = 1;
wait_us(1); // tf:IN + tSU:STO
SDIO = 1;
}
//-----------------------------------------------------------------------------
// Send a 2-wire start and address byte.
//
// Inputs:
// io2w_address: Address of device to access. LSB will be set to
// indicate a read, cleared to indicate a write.
//
//-----------------------------------------------------------------------------
static void io2w_start (u8 io2w_address)
{
i8 i;
// issue the START condition
wait_us(1); // tSU:STA
SDIO = 0;
wait_us(1); // tHD:STA
SCLK = 0;
// issue the control word (7 bit chip address + R/W* bit)
// Note that tr:IN + tLOW + tf:IN + tHIGH = 2500 ns = 400 kHz
for (i=7; i>=0; i--)
{
SCLK = 0;
wait_us(1); // tf:IN
SDIO = ((io2w_address >> i) & 0x01);
wait_us(1); // tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
}
// check the acknowledge
SCLK = 0;
SDIO = 1;
wait_us(2); // tf:IN + tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
if (SDIO != 0)
die(); // ack not received. This should never happen. Device isn't responding.
}
//-----------------------------------------------------------------------------
// Write one byte of data.
//
// Inputs:
// wrdata: Byte to be written
//
//-----------------------------------------------------------------------------
static void io2w_write_byte (u8 wrdata)
{
i8 i;
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
}
// check the acknowledge
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
if (SDIO != 0)
die(); // ack not received. This should never happen. Device isn't responding.
}
//-----------------------------------------------------------------------------
// Read one byte of data.
//
// Inputs:
// remaining bytes: Zero value indicates an ack will not be sent.
//
// Outputs:
// Returns byte read
//
//-----------------------------------------------------------------------------
static u8 io2w_read_byte (u8 remaining_bytes)
{
i8 i;
u8 rddata=0;
for (i=7; i>=0; i--)
{
SCLK = 0;
SDIO = 1; // Configure P0^7(SDIO) as a digital input
wait_us(1); // tf:IN
wait_us(2); // tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
rddata = ((rddata << 1) | SDIO); // reads start at word address 0xa
}
// set the acknowledge
SCLK = 0;
if (remaining_bytes == 0)
SDIO = 1;
else
SDIO = 0;
wait_us(2); // tf:IN + tLOW
SCLK = 1;
wait_us(1); // tf:IN + tHIGH
return rddata;
}
//-----------------------------------------------------------------------------
// Sends 2-wire start, writes an array of data, sends 2-wire stop.
//
// Inputs:
// lastreg: Last register to be written
// reg_array: Source array for data to be written
//
//-----------------------------------------------------------------------------
void io2w_write (u8 lastreg, u16 *reg_array)
{
u8 reg = 2;
// issue the START condition with address lsb cleared for writes
io2w_start(IO2W_ADDRESS);
// loop writing pairs of bytes
do
{
io2w_write_byte ((u8)(reg_array[reg]>>8));
io2w_write_byte ((u8)(reg_array[reg]&0xff));
reg = (reg + 1) & 0xf;
} while (reg != ((lastreg+1)&0xf));
// issue the STOP condition
io2w_stop();
}
//-----------------------------------------------------------------------------
// Sends 2-wire start, reads an array of data, sends 2-wire stop.
//
// Inputs:
// lastreg: Last register to be read
// reg_array: Destination array for data read
//
//-----------------------------------------------------------------------------
void io2w_read (u8 lastreg, u16 *reg_array)
{
u8 reg = 10;
// issue the START condition with address lsb set for reads
io2w_start(IO2W_ADDRESS | 0x01);
// loop reading pairs of bytes
do
{
u16 shadow_high = io2w_read_byte(1);
u8 shadow_low = io2w_read_byte(lastreg-reg);
reg_array[reg] = shadow_high*256 + shadow_low;
reg = (reg + 1) & 0xf;
} while (reg != ((lastreg+1)&0xf));
// issue the STOP condition
io2w_stop();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -