📄 x1226.c
字号:
#include "Regs2407.h"
#define uint unsigned int
#define delay() asm(" NOP ");asm(" NOP ");asm(" NOP ");asm(" NOP ");asm(" NOP ") // 2us
void I2cStart(void) // 起始信号
{
SetSDA;
SetSCL;
delay();
ClrSDA;
delay();
ClrSCL;
delay();
}
void I2cStop(void) //停止信号
{
ClrSDA;
delay();
SetSCL;
delay();
SetSDA;
delay();
}
void SendAck(uint ack) //送确认信号到slave 0:应答 1: 不应答
{
if(ack==0)
ClrSDA;
else
SetSDA;
SetSCL;
delay();
ClrSCL;
}
uint SendByte(uint dat) // 发送一个BYTE
{
unsigned int i=0;
uint ack=1;
dat &= 0x00FF;
for(i=0;i<8;i++)
{
delay();
if(dat & 0x0080)
SetSDA;
else
ClrSDA;
dat <<= 1;
delay();
SetSCL;
delay();
ClrSCL;
}
delay();
SetSDAInput;
delay();
SetSCL;
asm(" NOP ");
if(GetSDA==0) //接收确认信号: 1,没收到应答; 0,收到应答,通讯正常
ack = 0;
else
ack = 1;
delay();
ClrSCL;
delay();
return ack; // 返回0表示通讯成功
}
uint ReceiveByte(void) // 接收一个BYTE
{
uint i;
uint dat = 0;
for(i=0;i<8;i++)
{
SetSCL;
delay();
dat <<= 1;
SetSDAInput;
asm(" NOP ");
if(GetSDA)
{
dat |= 0x01;
}
ClrSCL;
delay();
}
dat &= 0x00FF;
return dat;
}
uint I2cByteWrite(uint device, uint address, uint dat)
{ //将一个BYTE写入slave的某地址内
uint i;
uint ack=1;
I2cStart();
ack = SendByte(device);
if(ack==1)
return 1; // 通讯失败,返回1
ack = SendByte(address >> 8);
if(ack==1)
return 1;
ack = SendByte(address & 0x00FF);
if(ack==1)
return 1;
ack = SendByte(dat);
if(ack==1)
return 1;
I2cStop();
for(i=0;i<2000;i++) // X1226的内部写入过程,此过程中不响应主机请求
{
delay();
}
return 0; // 正常情况下返回0
}
void Write_Time(uint *p) // ******************* 写时钟
{
uint n;
I2cByteWrite(0xDE,0x3F,0x02);
I2cByteWrite(0xDE,0x3F,0x06);
n = ((p[0]/10)<<4) | (p[0]%10);
I2cByteWrite(0xDE,0x35,n); // year
n = ((p[1]/10)<<4) | (p[1]%10);
I2cByteWrite(0xDE,0x34,n); // month
n = ((p[2]/10)<<4) | (p[2]%10);
I2cByteWrite(0xDE,0x33,n); // date
n = ((p[3]/10)<<4) | (p[3]%10) | 0x0080; // 24 小时格式
I2cByteWrite(0xDE,0x32,n); // hour
n = ((p[4]/10)<<4) | (p[4]%10);
I2cByteWrite(0xDE,0x31,n); // minute
n = ((p[5]/10)<<4) | (p[5]%10);
I2cByteWrite(0xDE,0x30,n); // second
// I2cByteWrite(0xDE,0x13,0x07); // ///////// 加快时钟走的速度
// I2cByteWrite(0xDE,0x12,0x20); // ///////// 加快时钟走的速度
I2cByteWrite(0xDE,0x37,0x20); // 20**年
I2cByteWrite(0xDE,0x3F,0x00);
}
uint I2cByteRead(uint device, uint address) // 从slave的某地址接收1字节数据
{
uint dat;
I2cStart();
SendByte(device);
SendByte(address >> 8);
SendByte(address & 0x00FF);
I2cStart();
SendByte(device|0x01);
dat = ReceiveByte();
SendAck(1); // 主机在停止之前不能响应应答位
I2cStop();
return dat;
}
void Read_Time(uint *p) // ************************** 读时钟
{
uint n;
n = I2cByteRead(0xDE,0x35);
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // year 需要做BCD码转换
p++;
n = I2cByteRead(0xDE,0x34);
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // month
p++;
n = I2cByteRead(0xDE,0x33);
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // date
p++;
n = I2cByteRead(0xDE,0x32) - 0x0080; // 12-24小时选择位
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // hour
p++;
n = I2cByteRead(0xDE,0x31);
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // minute
p++;
n = I2cByteRead(0xDE,0x30);
*p = (((n & 0x00F0)>>4 ) *10) + (n & 0x000F); // second
}
// address---要访问的首地址
// num---要写入的字节个数
// p --要写入的数组
uint Write_E2prom (uint address, uint num, uint *p) // 写E2PROM
{
uint i;
uint ack=1;
I2cByteWrite(0xDE,0x3F,0x02);
I2cByteWrite(0xDE,0x3F,0x06);
I2cStart();
ack = SendByte(0xAE); // 写E2prom
if(ack==1)
return 1; // 通讯失败,返回1
ack = SendByte(address >> 8);
if(ack==1)
return 1;
ack = SendByte(address & 0x00FF);
if(ack==1)
return 1;
for(i=0;i<num;i++)
{
ack = SendByte(*p);
if(ack==1)
return 1;
p++;
}
I2cStop();
for(i=0;i<5000;i++) // X1226的内部写入过程,此过程中不响应主机请求
{
delay();
}
I2cByteWrite(0xDE,0x3F,0x00);
return 0; // 正常情况下返回0
}
// address---要访问的首地址
// num---要读取的字节个数
// p --用来存放从E2PROM中读出的数据
// ----------------------------------------------------------------------------
uint Read_E2prom (uint address,uint num, uint *p) // 读E2PROM,可连续读
{
uint i=0;
uint ack=1;
I2cStart();
ack = SendByte(0xAE); // 写E2prom
if(ack==1)
return 1; // 通讯失败,返回1
ack = SendByte(address >> 8);
if(ack==1)
return 1;
ack = SendByte(address & 0x00FF);
if(ack==1)
return 1;
I2cStart();
ack = SendByte(0xAF);
if(ack==1)
return 1;
for( i=0;i<num;i++)
{
*p = ReceiveByte();
p++;
if( (i+1)<num )
SendAck(0); // 如果要继续读下去,则主机需要发送应答位
}
SendAck(1); // 主机在停止之前不能响应应答位
I2cStop();
return 0; // 正常情况下返回0
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -