|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
本帖最后由 cjsb37 于 2013-4-29 09:06 编辑
TMS320LF2407与24LC256连接程序不知那出错了!帮忙看看IOPC4---WP;
IOPC3---SDA;
IOPC2---SCL;
我是根据刘和平的书中改编的,感觉他的书中也有错误!
下面是只发送数据0X05,然后读取数据,但是读取的数据是255(24LC256是刚买的片子)
现在问题是,读写程序能执行下来,但是不知道真正写进去数据没?,读取的数据也不对!!!!
// 24LC256的应用编程
// 该程序实现DSP2407与EEPROM芯片24LC256的接口编程
#include "register.h"
int source[4]={4,3,2,1};
int result;
int n,control,j,m,rect,rec[8]; //变量在调试时看看数据有没有变化,而判断程序是否执行了
// 系统初始化子程序
void sysinitial()
{
asm( " setc INTM "); // 关闭总中断
asm( " clrc SXM ") ; // 抑制符号扩展
asm( " clrc OVM ") ; // 累加器结果正常溢出
asm( " clrc CNF ") ; // B0被配置为数据空间
SCSR1=0x81FE; // CLKIN=6M,CLKOUT=24M
WDCR=0x0E8; // 不使能看门狗
IMR=0x00; // 禁止所有中断
WSGR=0x0FFFF; // 不使能所有的等待状态
}
// IO口初始化子程序
void ioinitial()
{
// 选择定义IOPD0,IOPA2,IOPE0为通用I/O口
//MCRA=MCRA&0xfffb;
MCRB=MCRB&0xffe3;
//MCRC=MCRC&0xfffe;
PCDATDIR=PCDATDIR|0x1c00;
//PADATDIR=PADATDIR|0x0400; // IOPA2为输出
//PDDATDIR=PDDATDIR|0x0100; // IOPD0为输出,且写允许
}
// 启动I2C总线子程序
void I2CStart()
{
int k;
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
// IOPE0(SDA为输出)
PCDATDIR=PCDATDIR|0x0800;
// SDA=SCL=1
PCDATDIR=PCDATDIR|0x0008;
PCDATDIR=PCDATDIR|0x0004;
for(k=3;k>=0;k--) { k=k;} // 软件延时6us
// SDA=0
PCDATDIR=PCDATDIR&0xfff7;
for(k=3;k>=0;k--) { k=k;} // 软件延时6us
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
for(k=3;k>=0;k--) { k=k;} // 软件延时6us
// SDA=1
PCDATDIR=PCDATDIR|0x0008;
}
// 向I2C总线写入数据子程序
void I2CSendByte(int data)
{
int flag,sz,k; // 定义局部寄存器
// 设置IOPE0(SDA为输出)
PCDATDIR=PCDATDIR|0x0800;
for(flag=0x0080;flag!=0x00;flag=flag/2)
{
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
for(k=2;k>=0;k--) { k=k;}
sz=data&flag; // 屏蔽掉相应的位
if(sz==0)
// 如果相应的位为0,则SDA=0
PCDATDIR=PCDATDIR&0xfff7;
else
// 如果相应的位为1,则SDA=1
PCDATDIR=PCDATDIR|0x0008;
// SCL=1,在SCL=1期间数据线上的状态必须保持不变
PCDATDIR=PCDATDIR|0x0004;
for(k=2;k>=0;k--) { k=k;}
}
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
}
// 检查应答位子程序
int I2CRECACK()
{
int k;
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
for(k=3;k>=0;k--) { k=k;} // 软件延时6us
// SCL=1,在SCL=1期间数据线上的状态必须保
PCDATDIR=PCDATDIR|0x0004;
// 持不变
for(k=3;k>=0;k--) { k=k; } // 软件延时6us
// IOPE0(SDA为输入)
PCDATDIR=PCDATDIR&0xf7ff;
for(k=3;k>=0;k--) { k=k; } // 软件延时6us
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
k=(PCDATDIR&0x0008)>>3; // k值存储应答位,若K=0,则表示操作成功;
// 若k=1,则表示操作失败
return(k);
}
// 从I2C总线读取数据
int I2CRecByte()
{
int k,i=0;
int flag;
int sz;
// IOPE0(SDA为输入)
PCDATDIR=PCDATDIR&0xf7ff;
// SCL=0
PCDATDIR=PCDATDIR&0xfffb;
for(flag=0x0080;flag!=0x00;flag=flag/2)
{
for(k=3;k>=0;k--) { k=k; }
// SCL=1
PCDATDIR=PCDATDIR|0x0004;
for(k=2;k>=0;k--) { k=k; }
sz=PCDATDIR&0X0008; // 取得应该读取的相应位
if(sz==0X0008) i=i|flag; // 若读取的相应位为1,则k值的相应位置1
//sz=PEDATDIR&flag; // 取得应该读取的相应位
//if(sz==flag) k=k|flag; // 若读取的相应位为1,则k值的相应位置1
for(k=1;k>=0;k--) { k=k; }
PCDATDIR=PCDATDIR&0x0fffb; // SCL=0
}
return(i);
}
// 对I2C总线产生应答
void I2CAck()
{
int k;
PCDATDIR=PCDATDIR|0x0800; // 设置IOPE0为输出口
PCDATDIR=PCDATDIR&0x0fff7; // SDA=0
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR|0x0004; // SCL=1
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR&0x0fffb; // SCL=0
PCDATDIR=PCDATDIR|0x0008; // SDA=1,数据线恢复为1,但此时SCL=0,SDA在
// 后来可以改变
}
// 不对I2C总线产生应答
void I2CNoAck()
{int k;
PCDATDIR=PCDATDIR|0x0800; // 设置IOPE0为输出口
PCDATDIR=PCDATDIR|0x0008; // SDA=1
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR|0x0004; // SCL=1
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR&0x0fffb; // SCL=0
}
// 停止I2C总线
void I2CStop()
{
int k;
PCDATDIR=PCDATDIR&0x0FFFb; // SCL=0
PCDATDIR=PCDATDIR|0x0800; // 设置IOPE0为输出口
PCDATDIR=PCDATDIR&0x0FFF7; // SDA=0
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR|0x0004; // SCL=1
for(k=4;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR|0x0008; // SDA=1
for(k=3;k>0;k--) { k=k;} // 软件延时
PCDATDIR=PCDATDIR&0x0FFFb; // SCL=0
}
// 读数据子程序
int read(array,control,n)
int array,control,n;
{
int dat;
I2CStart(); // 设置I2C总线的开始状态
I2CSendByte(control);
rec[7]=control; // 送出控制字节(R/W=1)
dat=I2CRECACK(); // 检查应答位
rec[4]=dat;
if(dat==0){
dat=I2CRecByte(); // 接收最后一个字节的数据
I2CNoAck(); // 不产生应答信号
array=dat; // 把读取的数据存入数组
dat=0x00; // dat值赋0,表示前面的操作成功
}
return(dat);
}
// 写数据子程序
int write(array,control,n)
int array,control,n;
{
int dat;
PCDATDIR=PCDATDIR|0x1000; //输出
PCDATDIR=PCDATDIR&0x0FFEF; // 设置写允许,WP=0
I2CSendByte(array); // 写出一个字节数据
dat=I2CRECACK();
PCDATDIR=PCDATDIR|0x0010; // 写操作完成,设置写保护:WP=1
return(dat);
}
// 通用读写24LC256子程序,入口参数为输入/输出缓冲区首地址array,
// 24LC256的块内地址adress,控制字节control,需要读写的字节数n
int EEPROM(array,adress,control,n)
int array,adress,control,n;
{
int dat;
I2CStart(); // 设置I2C总线的开始状态
dat=control&0x0FFFE; // 清除控制字节的第0位
I2CSendByte(dat); // 送出控制字节(R/W=0)
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=adress&0x0FF00;
dat=dat>>8; // dat=24LC256的块内地址的高字节
I2CSendByte(dat); // 送出24LC256的块内地址的高字节
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=adress&0x00FF;
I2CSendByte(dat); // 送出24LC256的块内地址的低字节
dat=I2CRECACK(); // 检查应答位
if(dat==0) {
dat=control&0x0001;
switch(dat) {
case 1 :dat=read(array,control,n);break;// 调用读数据子程序
case 0 :dat=write(array,control,n);break;// 调用写数据子程序
}
}
}
}
I2CStop();
return(dat); // 返回一个状态字,以确定操作是否成功
}
// 主程序
main()
{
int k;
sysinitial(); // 系统初始化
ioinitial(); // io端口初始化
while(1)
{
while(1)
{
j=EEPROM(0x05,0x0000,0x00A0,4);
if(j==0) break;
for(k=10;k>0;k--) {k=k;}
}
while(1)
{
m=EEPROM(result,0x0000,0x00A1,4);
if(m==0) break; // 如果读出成功,则终止读操作,否则继续读
for(k=10;k>0;k--) {k=k;}
}
}
}
// 直接返回中断服务子程序
void interrupt nothing()
{
return;
}
|
|