-- EEPROM功能测试
-- 2021.05.07
-- Lingd
-- 福州泰诚网络科技有限公司
module(...,package.seeall)
require"pins"
local I2C_WR = 0x00
local I2C_RD = 0x01
local EE_DEV_ADDR = 0xA0
local EE_PAGE_SIZE = 8
local EE_SIZE = 256
local I2C_SCL = pins.setup(pio.P0_14, 0)
local I2C_SDA = pins.setup(pio.P0_15, 0)
local I2C_SDA_IN = pins.setup(pio.P0_15)
-- 发起I2C总线启动信号
local function Start()
I2C_SDA(1)
I2C_SCL(1)
I2C_SDA(0)
I2C_SCL(0)
end
-- 发起I2C总线停止信号
local function Stop()
I2C_SCL(0)
I2C_SDA(0)
I2C_SCL(1)
I2C_SDA(1)
end
-- 产生一个时钟,并读取器件的ACK应答信号
local function WaitAck()
local AckState,WaitTime = 0,0
I2C_SCL(1)
AckState = 0
while I2C_SDA_IN() ~= 0 do
if WaitTime >= 250 then
AckState = 1
break
end
WaitTime = WaitTime + 1
end
I2C_SCL(0)
return AckState
end
-- 产生一个ACK信号
local function SendAck()
I2C_SDA(0)
I2C_SCL(1)
I2C_SCL(0)
end
-- 产生1个NACK信号
local function SendNoAck()
I2C_SDA(1)
I2C_SCL(1)
I2C_SCL(0)
end
-- 向I2C总线设备发送8bit数据
local function SendByte(Dat)
local i = 0
for i = 0,7 do
if bit.band(bit.lshift(Dat,i),0x80) == 0x00 then
I2C_SDA(0)
else
I2C_SDA(1)
end
I2C_SCL(1)
I2C_SCL(0)
end
I2C_SDA(1)
end
-- 从I2C总线设备读取8bit数据
local function ReadByte()
local i,Dat = 0,0
for i = 0,7 do
Dat = bit.lshift(Dat,1)
I2C_SCL(1)
if (I2C_SDA_IN() == 1) then
Dat = Dat + 1
end
I2C_SCL(0)
end
return Dat
end
-- 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
local function CheckDevice(Addr)
local Ack = 0
Start()
SendByte(bit.bor(Addr,I2C_WR))
Ack = WaitAck()
Stop()
return Ack
end
-- 判断串行EERPOM是否正常 1 表示正常, 0 表示不正常
local function CheckOk()
if (CheckDevice(EE_DEV_ADDR) == 0) then
return 1
else
Stop()
return 0
end
end
-- 向串行EEPROM指定地址写入若干数据,采用页写操作提高写入效率
local function WriteBytes(Addr,Data)
local i,m = 0,0
for i = 1,#Data do
if (i == 1) or ((bit.band(Addr,EE_PAGE_SIZE-1)) == 0) then
Stop()
for m = 0,100 do
Start()
SendByte(bit.bor(EE_DEV_ADDR,I2C_WR))
if (WaitAck() == 0) then
break
end
end
if (m >= 99) then
Stop()
return 0
end
SendByte(Addr)
if (WaitAck() ~= 0) then
Stop()
return 0
end
end
SendByte(Data[i])
if (WaitAck() ~= 0) then
Stop()
return 0
end
Addr = Addr+1
end
Stop()
return 1
end
-- 从串行EEPROM指定地址处开始读取若干数据
local function ReadBytes(Addr,Len)
local i
local ReadBuf = {}
Start()
SendByte(bit.bor(EE_DEV_ADDR,I2C_WR))
if (WaitAck() ~= 0) then
Stop()
return ReadBuf
end
SendByte(Addr)
if (WaitAck() ~= 0) then
Stop()
return ReadBuf
end
Start()
SendByte(bit.bor(EE_DEV_ADDR,I2C_RD))
if (WaitAck() ~= 0) then
Stop()
return ReadBuf
end
for i = 1,Len do
ReadBuf[i] = ReadByte()
if (i ~= Len) then
SendAck()
else
SendNoAck()
end
end
Stop()
return ReadBuf
end
-- EEPROM全部写0
local function Erase()
local i,buf = 0,{}
for i = 1,EE_SIZE do
buf[i] = 0x00
end
if (WriteBytes(0,buf) == 0) then
return
end
end
sys.taskInit(function()
local i,hexstr,w_data = 1,"",{0x01,0x2,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0xb,0x0c,0x0d}
sys.wait(2000)
-- CheckOk()
-- Erase()
if WriteBytes(0x00,w_data) == 1 then
log.info("i2c","write ok")
else
log.info("i2c","write err")
end
while true do
res = ReadBytes(0x00,#w_data)
for i = 1,#res do
hexstr = hexstr .. string.format("%02X ",res[i])
end
log.info("i2c","read","len:",#res,"hex:",hexstr)
hexstr = ""
sys.wait(1000)
end
end)