CS5460A芯片读取数据时经常出现读回0的状况,请教各位了.
CS5460A芯片读取数据时经常出现读回0的状况,但有时读的数据准确.请教各位了.有人说是SPI的时序问题.但现在还没查明!下面是我的SPI的读写时序.请大家帮我看看.//////////////////////////////////////////////////
void send_5460a(unsigned char dat)
{
unsigned char i,d=dat;
for(i=0;i<8;i++)
{
SCLK=0;
if(d&0x80)
SDI=1;
else
SDI=0;
SCLK=1;
d<<=1;
SCLK=0;
}
SDI=1;
}
///////////////////////////////////////////
unsigned char receive_5460a(void)
{
unsigned char i,result=0;
SDI=1;
for(i=0;i<8;i++)
{
//if(i==7)SDI=0;
//SCLK=0;
result<<=1;
SCLK=1;
if(SDO)
result|=1;
SCLK=0;
}
//SDI=1;
return(result);
}
//////////////////////////////////////////////////
void write_5460a(void)
{
unsigned char i;
CS=0;
NOP();
NOP();
NOP();
send_5460a(buf);
//sec= 0;
//while(SDO&& sec< 1000);
for(i=1;i<4;i++)
{
send_5460a(buf);
}
NOP();
NOP();
NOP();
CS=1;
}
////////////////////////////////////////////////
void read_5460a(unsigned char cmd)
{
unsigned char i;
CS=0;
NOP();
NOP();
NOP();
send_5460a(cmd);
sec= 0;
while(SDO&& sec< 1000);
for(i=0;i<3;i++)
{
buf=receive_5460a();
}
NOP();
NOP();
NOP();
CS=1;
}
////////////////////////////////////////// 自己顶一下了./emotion/em035.gif 哪位大哥指点一下了! 还是自己顶一下! unsigned char i,result=0;
改成unsigned char i,result=0XFE;
大概就可以了 unsigned char i,result=0;
改成unsigned char i,result=0XFE;
大概就可以了
谢谢楼上的!
似乎与这没多大的关系.改了,但还是不行.读数据并不是一直不行,而是可以读到正确数据,但会频繁出现读回来是0的状况.还有个问题我现在使用3片单片机.只有一片出现上面说的情况.其它两片连正确的数据都还不能读到(同一程序,运行结果不一样)! void Send_5460(uchar send_data)
{
uchar i;
SCLK=1;
for(i=0;i<8;i++)
{
if(send_data&0x80)
SDI=1;
else
SDI=0;
SCLK = 0;
send_data<<=1;
SCLK=1;
}
SDI=1;
} TO;agency
按你说的那样改了还是没见效!真是郁闷了,你的完整读写程序程序能否共享一下了.
哥们再帮我看看是哪里出问题了.谢谢! 期待着高手的解答!!.......~^~ unsigned char receive_5460a(void)
{
unsigned char i,result=0;
SDI=1;
for(i=0;i<8;i++)
{
//if(i==7)SDI=0; //此处有没有,好像这些地方都要有,即读的同时 要发送0xfe
//SCLK=0;
result<<=1;
SCLK=1;
if(SDO)
result|=1;
SCLK=0;
}
//SDI=1;
return(result);
} signed long cs5460a_read_3byte(uchar read_comm_byte)
{
uchar i,j;
uchar input_data={0xfe,0xfe,0xfe,0xfe};
unionUL_temp return_data;
return_data.L_tmp=0;
DDRA&=~(_BV(CS5460A_SDO));
PORTA|=_BV(CS5460A_SDO);
cs5460a_init();
asm("nop");
asm("nop");
asm("nop");
asm("nop");
EN_CS5460A_CS;
cs5460a_write_byte(read_comm_byte);
for (i=3;i>0;i--)
{
for(j=0;j<8;j++)
{
return_data.P_tmp=return_data.P_tmp<<0x01;
if((PINA&_BV(CS5460A_SDO))==0x10)
{
return_data.P_tmp=return_data.P_tmp|0x01;
}
if((input_data&0x80)==0x00)
{
CLR_CS5460A_SDI;
}
else
{
SET_CS5460A_SDI;
}
input_data=input_data<<1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SET_CS5460A_SCLK;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
CLR_CS5460A_SCLK;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
CN_CS5460A_CS;
return_data.P_tmp=0x00;
//dprintf(0,string_20,return_data.P_tmp,return_data.P_tmp,return_data.P_tmp,return_data.P_tmp);
return return_data.L_tmp;
}
这是我的成熟产品中的一部分,供你参考 读的同时要一边发送OXFE吗?这步我好像没做到.
谢谢.我马上试试. 问题有些转机了!!现在可以读到数据,暂时还没发现频繁读到0的状况.
非常高兴!在此谢谢回复过的朋友与关注的朋友.再次谢谢你们了! 注意这个芯片直接看英文资料,就是从中文官方那里下的资料也别看,全是错误,国人都太不负责了吧!那几天差点搞死我,还好,最后醒悟了全部扔掉了。 呵呵.实在是翻译得不好.像有"O"就搞成是"0"了.真是晕倒. 请教,读出来的功率数据如何转换为实际的功率?满量程的功率大约是多少?
以下是我的电路图:
http://cache.amobbs.com/bbs_upload782111/files_15/ourdev_447258.JPG
接线原理图 (原文件名:接线原理图.JPG)
都回来的数据如下:
9V电压,1.955A电流,81/20W功率
03DB70V 0958F1A 00004Bw 000472W FED2F8v FC9CBCa
9V电压,1.955A/2电流,81/40W功率
03BD7CV 0488A3A 000D6Fw 000212W FD7A4Cv FCE1FAa
请问如何转换呢??
谢谢大侠的回答!!! 上面给的原理图出错了,应该在电流互感器哪里还有一个10欧姆的电阻
http://cache.amobbs.com/bbs_upload782111/files_15/ourdev_452144.jpg
接线图 (原文件名:接线图.jpg) 同志们还在吗?我把11楼的程序改了改:
void SPI_MasterTransmit_8(unsigned char Data8)
{
unsigned char i;
CS_L;
//delay(2);
SCLK_L;
for(i=0;i<8;i++)
{
if(Data8&0x80) SDI_H;
else SDI_L;
Data8<<=1;
//delay(2);
SCLK_H;
NOP();
SCLK_L;
NOP();
}
NOP();
CS_H;
}
void cs5460a_read_3byte(unsigned char read_comm_byte)
{
unsigned char tmp;
unsigned char i,j;
unsigned char input_data={0xfe,0xfe,0xfe,0xfe};
DDRA&=~(1<<PC3);
PORTA|=(1<<PC3);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
CS_L;
SPI_MasterTransmit_8(read_comm_byte);
for (i=3;i>0;i--)
{
for(j=0;j<8;j++)
{
tmp=tmp<<0x01;
if((PINC&(1<<PC3))==0x08)
{
tmp=tmp|0x01;
}
if((input_data&0x80)==0x00)
{
SDI_L;
}
else
{
SDI_H;
}
input_data=input_data<<1;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SCLK_H;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
SCLK_L;
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
CS_H;
put_char(tmp);
put_char(tmp);
put_char(tmp);
}
void main(void)
{
init_devices();
while(1) cs5460a_read_3byte(0x0c);
}
我用的是CS5460,现在的情况是,我只接了电源,以及SDI,SDO,CS,SCLK,上点后,我就读一个寄存器,但是读出来的值不正确。
大家帮忙看一下,我SPI发送函数的时序或者其他地方有问题吗?谢谢了! 越来越惨了,现在读出来全部是零了…… 我做的项目和你一样用到这个芯片,有机会交流一下,zhuxianglin@yeah.net 我还以为是有人给我解答了,呵呵,程序应该是没有问题的,只要你的寄存器没做错的话,有空大家交流下,我也是用这个做项目,不过我想选cs5463,但是我现在手上的只有cs5460的样板,只能先做5460的。 为什么看SPI发的程序都是模拟的啊, 回复【21楼】yanrz yanrz
-----------------------------------------------------------------------
请问我状态寄存器状态位总是不对,以前正常使用过好长一段时间,最近又不行了,是怎么回事 求助-我的CS5460A读出寄存器的数据一直是0????
http://cache.amobbs.com/bbs_upload782111/files_43/ourdev_663129JY5T4O.jpg
(原文件名:5460硬件图.jpg)
#include<reg52.h>
#include<intrins.h>
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
unsigned char read;//功率暂存器
uchar code table[]= "I=";
//lcd管脚定义
#define LCDIO P0 //P0口LCD数据线
sbit rs=P2^7;
sbit rd=P2^6;
sbit lcden=P2^5;
//以下是cs5460的管脚定义:
sbit INT=P3^2;
sbit Cs5460_cs=P1^7;
sbit Cs5460_RET=P1^3;
sbit Cs5460_sdo=P1^2;
sbit Cs5460_clk=P1^1;
sbit Cs5460_sdi=P1^0;
//以下是cs5460的函数声明
void Write_Cs5460_Byte(unsigned char temp);
void Write_Cs5460(unsigned char *write,unsigned char n);
unsigned char Read_Cs5460_Byte();
void Read_Cs5460(unsigned char address,unsigned char *read1);
/******************************
原型:void delay(uint n)
行参:uint n
返回值:无
功能:延时n ms
*****************************/
void _delay(uint n)
{
uint x,y;
for(x=n;x>0;x--)
for(y=115;y>0;y--);//12Mhz时延时1MS//
}
void delay1(uint n)
{
uint x,y;
for(x=n;x>0;x--)
for(y=2;y>0;y--);//12Mhz时延时1uS//
}
//LCD函数声明
void write_com(uchar com) //lcd写命令函数
{
rs=0;
rd=0;
lcden=0;
P0=com;
_delay(2);
lcden=1;
_delay(2);
lcden=0;
}
void write_date(uchar date) //lcd写命数据函数
{
rs=1;
rd=0;
lcden=0;
P0=date;
_delay(2);
lcden=1;
_delay(2);
lcden=0;
}
void initLCD() //lcd初始化函数
{
uint num;
lcden=0;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
_delay(5);
write_com(0x80); //lcd在第一行第一个位置开始显示
for(num=0;num<2;num++)
{
write_date(table); //显示‘I=’
_delay(1);
}
}
void display(uchar *x_date) //参数显示
{
uchar t=0x82,a,i;
uchar temp1,temp2;
for(i=0;i<3;i++)
{
a=x_date;
temp1=a; //temp1为待显示的十六进制数 @@@@这里buff只是高两位的电流值@@@@//
temp1 = (temp1 >>4) & 0x0F;//先显示高4位
if(temp1 < 0x0A) //0-9时
{
temp1 = temp1 + 0x30;
}
else temp1 = temp1 + 0x37;//a-f时
write_com(t);
write_date(temp1);
_delay(50);
temp2=a; //temp1为待显示的十六进制数
temp2 = temp2 & 0x0F;//显示低4位
if(temp2 < 0x0A) //0-9时
{
temp2 = temp2 + 0x30;
}
else temp2 = temp2 + 0x37;//a-f时
write_com(t+1);
write_date(temp2);
_delay(500);
t=t+3;
}
}
////////////CS5460声明//////////////////////
void Write_Cs5460_Byte(unsigned char temp) //写入一个字节
{
unsigned char i;
Cs5460_clk=0;
for(i=0;i<8;i++) //循环8次 写入数据
{
Cs5460_clk=0;
Cs5460_sdi=(bit)(temp&0x80); //每次传输高字节
Cs5460_clk=1;
temp<<=1;
}
Cs5460_clk=0;
}
//******可选择写入一个命令字或者读寄存器名后加三个字节的内容****//
void Write_Cs5460(unsigned char *write,unsigned char n)
{
unsigned char i;
Cs5460_cs=1;
delay1(2);
Cs5460_clk=0;
delay1(2);
Cs5460_cs=0;
for(i=0;i<n;i++)
{
Write_Cs5460_Byte(*(write+i));
}
Cs5460_clk=0;
delay1(2);
Cs5460_cs=1;
}
//**********读出一个字节***********//@@@@@@@@@有问题@@@@@@@@@@@//
unsigned char Read_Cs5460_Byte()
{
unsigned char i,tmp,read_data;
bit c_temp,a;
tmp = 0xfe;
Cs5460_clk=0;
for(i=0;i<8;i++) //循环8次 写入数据
{
Cs5460_clk=0;
Cs5460_sdi=(bit)(tmp&0x80);
a=Cs5460_sdi;
c_temp = Cs5460_sdo;
read_data = read_data|c_temp;
tmp = tmp<<1;
if(i!=7)
{
read_data = read_data<<1;
}
Cs5460_clk=1;
}
Cs5460_clk=0;
return(read_data);
}
//上一段改为
//**************************************************************//
/*unsigned char Read_Cs5460_Byte()
{
unsigned int i,tmp=0;
for(i=0;i<7;i++) //循环8次 写入数据
{
Cs5460_clk=0;
_delay(2);
Cs5460_sdi=1; //发送SYS0同步命令0xFE高7位
Cs5460_clk=1;
if(Cs5460_sdo) tmp|=0x80>>i;
}
i=7;
Cs5460_clk=0;
_delay(2);
Cs5460_sdi=0; //发送SYS0同步命令0xFE最低位
Cs5460_clk=1;
if(Cs5460_sdo) tmp|=0x80>>i;
return(tmp);
}
*/
//************************************************************//
void Read_Cs5460(unsigned char address,unsigned char *read1)
{
unsigned char i;
Cs5460_cs=1;
delay1(2);
Cs5460_clk=0;
delay1(2);
Cs5460_cs=0;
//static unsigned char tmp,k=0;
Write_Cs5460_Byte(address);
for(i=0;i<3;i++)
{
*(read1+i)=Read_Cs5460_Byte();
}
Cs5460_clk=0;
delay1(2);
Cs5460_cs=1;
}
//*************CS5460初始化函数*********//
void Init_Cs5460()
{
unsigned char buff1;
Cs5460_cs=0;
delay1(2);
Cs5460_RET=0;
_delay(30); //复位30ms
Cs5460_RET=1;
_delay(50);
buff1=0xff;//SYNC1
buff1=0xff;//SYNC1
buff1=0xff;//SYNC1
buff1=0xff;//SYNC0
Write_Cs5460(buff1,4);//写串口初始化//
buff1=0xff;//SYNC1
buff1=0xff;//SYNC1
buff1=0xff;//SYNC1
buff1=0xfe;//SYNC0
Write_Cs5460(buff1,4);//写串口初始化//
buff1=0x40;//写配置寄存器
buff1=0x00;//GI=0电流通道增益=10
buff1=0x18;//中断形式:00-高电平08-低电平10-下降沿18-上升沿
buff1=0xe1;//DLCK=MCLK/1
Write_Cs5460(buff1,4);
buff1=0x5e;
buff1=0xff;
buff1=0xff;
buff1=0xff;
Write_Cs5460(buff1,4);//清状态寄存器
buff1=0x74;
buff1=0x00;
buff1=0x00;
buff1=0x00;
Write_Cs5460(buff1,4);//写屏蔽中断寄存器
buff1=0x78;
buff1=0x00;
buff1=0x00;
buff1=0x00;
Write_Cs5460(buff1,4);//写控制寄存器
/*
buff1=0x4c;
buff1=0x00;
buff1=0x34;
buff1=0x9c;
Write_Cs5460(buff1,4);//写EOUT脉冲输出寄存器
_delay(50);
*/
buff1=0x4A;
buff1=0x00;
buff1=0x0F;
buff1=0xA0; //每秒计算1次,N=4000
Write_Cs5460(buff1,4);//写CYCLE COUNT寄存器
buff1=0x44;
buff1=0x40;//增益1
buff1=0x00;
buff1=0x00;
Write_Cs5460(buff1,4);//写电流增益寄存器
buff1=0x48;
buff1=0x40;//增益1
buff1=0x00;
buff1=0x00;
Write_Cs5460(buff1,4);//写电压增益寄存器
Read_Cs5460(0x1e,read);//读状态寄存器
//_delay(50);
buff1=read;
buff1=read;
buff1=read;
buff1=0x5e;
Write_Cs5460(buff1,4);//写状态寄存器
buff1=0xe8;
Write_Cs5460(buff1,1);//启动Cs5460,执行连续周期计算
}
void main()
{
//long I;//U,P;
//unsigned char ret6,ret5,ret4,ret3,ret2,ret1;//定义位的值
initLCD();
_delay(70);
Init_Cs5460();
//Read_Cs5460(0x12,buff);//读取上次功率值
//Read_Cs5460(0x14,buff);//读取上次能量值
//Read_Cs5460(0x16,buff);//读取上次电流有效值
//Read_Cs5460(0x18,buff);//读取上次电压有效值
/******************************************************此处老师看一下转化有没有问题
I=0; //后面的乘10取整还没有写
I=buff;
I=I<<8;
I=I+buff;
I=I<<8;
I=I+buff;//六位十六进制数
ret6=I/0x100000; //取出十万位的值,注意0x100000是个十六进制数
I=I<<4; //I变量左移四位
ret5=I/0x100000; //取出位的值
I=I<<4; //I变量左移四位
ret4=I/0x100000; //取出位的值
I=I<<4; //I变量左移四位
ret3=I/0x100000;
I=I<<4; //I变量左移四位
ret2=I/0x100000; //取出位的值
I=I<<4; //I变量左移四位
ret1=I/0x100000; //取出位的值
I=ret6*pow(16,-1)+ret5*pow(16,-2)+ret4*pow(16,-3)+ret3*pow(16,-4)+ret2*pow(16,-5)+ret1*pow(16,-6);
//各位的值乘以位权,完成十六转十进制
**********************************************************************************/
while(1)
{
Read_Cs5460(0x0E,read);//读取上次电流值
_delay(50);
display(read);
}
/*
Read_Cs5460(0x10,buff);//读取上次电压值
*/
} 上面是连接图和程序,希望各位大侠指点~
忙了半个月了,找不出错误!!!./emotion/em101.gif 问题已经解决了,程序没错,是硬件有点小问题
数据都可以读出来,但不知道怎么转成实际值,求高人指点~ 你好,能否请教下,你最后查出来的问题是什么。我也遇到同样的问题,一直读出来数据为0. 怎么判断读出的数据是否正确,求各位大神解答 qsm627421059 发表于 2011-8-4 12:00 static/image/common/back.gif
问题已经解决了,程序没错,是硬件有点小问题
数据都可以读出来,但不知道怎么转成实际值,求高人指点~ ...
大侠,请问你后来是怎么解决CS5460A的问题的?我现在也是CS5460A读取回来的数据全是0 楼主,你后来调出CS5460A了吗?遇到同样问题,求援助…… xylslss 发表于 2013-5-12 11:09
楼主,你后来调出CS5460A了吗?遇到同样问题,求援助……
你好,读数一直为0,解决了吗?怎么解决的啊?
页:
[1]