⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2cclockandtms320lf2407.c

📁 I2C串行日历时钟与TMS320LF2407的接口及应用,该程序实现对I2C总线日历时钟芯片PCF8583的读写操作.
💻 C
字号:
I2C串行日历时钟与TMS320LF2407的接口及应用
  源程序代码:
// 该程序实现对I2C总线日历时钟芯片PCF8583的读写操作 
#include  "register.h"
// 系统初始化子程序 
void	sysinit()
{
	asm( " setc INTM ");			// 关闭总中断 
	asm( " clrc SXM ") ;			// 抑制符号扩展 
	asm( " clrc OVM ") ;			// 累加器结果正常溢出 
	asm( " clrc CNF ") ;			// B0被配置为数据空间 
	*SCSR1=0X81FE;			// CLKIN=6M,CLKOUT=24M 
	*WDCR=0X0E8	;			// 不使能看门狗 
	*IMR=0X00;				// 禁止所有中断 
	*IFR=0X0FFFF;			// 清除所有的中断标志 
	WSGR=0x0FFFF;			// 不使能所有的等待状态 
}
// 输入输出口初始化子程序 
void	IOINIT()
{
*MCRB=*MCRB&0X0FFD7;		// 配置IOPC3和IOPC5为一般的I/O口方式 
*PCDATDIR=*PCDATDIR|0X02828; // 配置IOPC3和IOPC5为输出方式,且SCL=SDA=1 
} 
// 软件延时子程序 
void delay()
{
int  i;
for(i=0X07D;i--;)	{	i=i;}
}
// 启动I2C总线子程序 
void	START()
{
*PCDATDIR=*PCDATDIR|0X028;		// SDA=SCL=1 
delay( );							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0FFDF;	// SDA=0 
delay();							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
delay();							// 软件延时,以使时序匹配 
}
// 发送字节子程序 
void	TRANSMIT(TRAN)
int    TRAN;
{
int flag,sz;						// 定义需要的局部变量 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0    
delay();							// 软件延时,以使时序匹配 
for(flag=0x0080;flag!=0x00;flag=flag/2)	{
sz=TRAN&flag;				// 屏蔽掉不需要的位 
if(sz==0)	*PCDATDIR=*PCDATDIR&0X0FFDF;// 如果相应的位为0,则SDA=0 
else	*PCDATDIR=*PCDATDIR|0X020;// 如果相应的位为1,则SDA=1 
delay();						// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR|0X08;	// SCL=1 
delay();						// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0FFF7;	// SCL=0 
delay();						// 软件延时,以使时序匹配 
}
}
// 从机(即PCF8583芯片)应答子程序。返回值为0时,代表操作成功;返回值为1时,代表操作失败 
int	SLAVE_ACK()
{
int    sz,k=0;					// 定义所需要的局部变量 
*PCDATDIR=*PCDATDIR|0X0020;		// SDA=1 
delay();							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0DFFF;	// 设置IOPC5(SDA)为输入 
delay();							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR|0X08;		// SCL=1 
delay();							// 软件延时,以使时序匹配 
sz=*PCDATDIR&0X0020;				// 检测数据位 
if(sz==0X0020)  k=1;				// 如果数据位为1,则证明失败,则令k=1 
else  k=0;  	 					// 如果数据位为0,则证明成功,则保持k=0不变 
*PCDATDIR=*PCDATDIR|0X2000;		// 设置IOPC5(SDA)为输出 
*PCDATDIR=*PCDATDIR&0X0FFD7;	// SCL=SDA=0 
return(k);
}
// I2C停止子程序 
void    STOP()
{ 
*PCDATDIR=*PCDATDIR&0X0FFDF;	// SDA=0 
delay();
*PCDATDIR=*PCDATDIR|0X0008;		// SCL=1 
delay( );							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR|0X0020;		// SDA=1 
}
// 字节写子程序,即向I2C器件写1个字节的数据,入口为地址BYTE_ADDR和需要写入的字节
// 内容T_DATA。返回值为0时,代表操作成功;返回值为1时,代表操作失败 
int	BYTE_WR(BYTE_ADDR,T_DATA)
int	BYTE_ADDR,T_DATA;
{
int  k;
START();							// 启动I2C总线 
TRANSMIT(0X0A0);					// 送写控制字 
k=SLAVE_ACK();					// 从机(即PCF8583芯片)应答 
if(k==0)	 TRANSMIT(BYTE_ADDR);	// 送出地址 
if(k==0)	 k=SLAVE_ACK();			// 从机(即PCF8583芯片)应答 
if(k==0)	TRANSMIT(T_DATA);		// 送出需要保存的数据 
if(k==0)	k=SLAVE_ACK();			// 从机(即PCF8583芯片)应答 
if(k==0)	STOP();					// 设置停止状态 
return(k);
}
// 接收一个字节子程序,出口为接收到的数据R_DATA 
int  RECEIVE()	
{
int  R_DATA=0,sz,i;
*PCDATDIR=*PCDATDIR&0X0DFFF;	// 设置IOPC5(SDA)为输入 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
delay();							// 软件延时,以使时序匹配  
for(i=0;i<8;i++)	{
R_DATA=R_DATA<<1;			// R_DATA左移一位 
*PCDATDIR=*PCDATDIR|0X0008;	// SCL=1 
delay();						// 软件延时,以使时序匹配   
sz=*PCDATDIR&0X0020;			// 取得相应的数据位 
if(sz==0)	 R_DATA=R_DATA&0XFFFE;	// 如果数据位为0,则R_DATA最低位清0 
else  R_DATA=R_DATA|0x0001;		// 如果数据位为1,则R_DATA最低位置1 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
delay();							// 软件延时,以使时序匹配  
}
*PCDATDIR=*PCDATDIR|0X2000;		// 设置IOPC5(SDA)为输出 
return(R_DATA);					// 返回接收的字节 
}
// 主机无应答信号子程序 
void	NO_ACK()
{
*PCDATDIR=*PCDATDIR|0X0008;		// SCL=1 
delay();							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
}
// 主机应答子程序 
void	MASTER_ACK()
{
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
*PCDATDIR=*PCDATDIR&0X0FFDF;	// SDA=0 
*PCDATDIR=*PCDATDIR|0X0008;		// SCL=1 
delay();							// 软件延时,以使时序匹配 
*PCDATDIR=*PCDATDIR&0X0FFF7;		// SCL=0 
}
// 字节读子程序,即从I2C器件读出1个字节的数据,入口为需要读出的地址BYTE_ADDR,出口
// 为读出的数据R_DATA,通过C语言的参数传递功能实现。返回值为0X0FFFF时,表示操作失败;
// 否则操作成功 
int	BYTE_RD(int  BYTE_ADDR)
{
int	k,R_DATA;
START();						// 启动I2C总线 
TRANSMIT(0XA0);				// 送出写控制字,以写入地址字节 
k=SLAVE_ACK( );				// 从机(即PCF8583芯片)应答 
if(k==0)	TRANSMIT(BYTE_ADDR);// 送出需要读出数据的地址 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)  {
START( );					// 启动I2C总线 
TRANSMIT(0XA1);
}							// 送出读控制字 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)	{
R_DATA=RECEIVE();		// 接收PCF8583发出的数据 
NO_ACK();				// 主机不作应答 
STOP();					// 设置停止状态 
}
if(k==0)  return(R_DATA);			// 返回一个读出的数据 
else   return(0X0FFFF);			// 如果整个读过程有误,则返回0X0FFFF 
}
// 连续写子程序,入口为需要写的起始地址ADDR,存储需要写入数据的数组的首地址ARRY,需要
// 写入的数据的个数N 
int	CON_WR(ADDR,ARRAY,N)
int   ADDR,*ARRAY,N;
{
int	k;
START();						// 启动I2C总线 
TRANSMIT(0X0A0);				// 送写控制字 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)	 TRANSMIT(ADDR);	// 送出要写数据的起始地址 
if(k==0)	 k=SLAVE_ACK();		// 从机(即PCF8583芯片)应答 
if(k==0)	 {
for(;N>0;N--,ARRAY++)	{ 
TRANSMIT(*ARRAY);	// 送出需要保存的数据,保存在数组ARRAY中 
k=SLAVE_ACK();		// 从机(即PCF8583芯片)应答,地址自动加1 
if(k==1)	break;
}
}
STOP();						// 设置停止状态 
return(k);
}
// 连续读子程序,入口为需要读的起始地址ADDR,存储读出数据的数组首地址ARRY,需要读出的
// 数据的个数N 
int	CON_RD(ADDR,ARRAY,N)
int   ADDR,*ARRAY,N;
{
int	k,R_DATA;
START();						// 启动I2C总线 
TRANSMIT(0XA0);				// 送出写控制字,以写入地址字节 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)	TRANSMIT(ADDR);		// 送出需要读出数据的地址 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)	{
START();					// 启动I2C总线 
TRANSMIT(0XA1);
}							// 送出读控制字 
k=SLAVE_ACK();				// 从机(即PCF8583芯片)应答 
if(k==0)	{
for(;N>1;N--,ARRAY++)	{
R_DATA=RECEIVE();	// 接收PCF8583发出的数据 
*ARRAY=R_DATA;		// 读出的数据存入数组 
MASTER_ACK();		// 主机应答,地址自动加1   
}
R_DATA=RECEIVE();		// 接收PCF8583发出的数据        
*ARRAY=R_DATA;			// 读出的数据存入数组 
NO_ACK();				// 主机不作应答 
STOP();					// 设置停止状态 
}
return(k);						// k=0时表示操作成功,k=1时表示操作失败 
}
// 主程序 
main()
{
int       k;
int       R_DATA;
static		int  source[6]={0x0F,0x0E,0x0D,0x0C,0x0B,0x0A};
int       result[6];  
sysinit();					// 系统初始化 
IOINIT();					// 输入输出口初始化 
k=BYTE_WR(0x00,0x00);	// 设置PCF8583的控制状态寄存器,其地址为0x00,值0x00代
// 表的意义请参考相关资料,若k==0,则证明写入成功;若k==1,
// 则证明写入失败 
R_DATA=BYTE_RD(0x00);	// 读出地址单元0X00的值,如果读出值为0X0FFFF,则表示读
// 出值有误 
k=CON_WR(0x30,source,6); // 从0x30地址开始连续写入6个数据  
k=CON_RD(0x30,result,6);  // 把写入的数据连续读出 
}
//  直接返回中断服务子程序           
void interrupt nothing() 
{
	return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -