c8051f340读取智能锂电池信息

2020-01-23 14:35发布

我用C8051f340模拟的smbus总线时序读取智能锂电池信息,但是每次读出的数据都是FFFF这是为什么呢,还有就是每个确认都是高电平,有点搞不懂啊,时序图如下:

(原文件名:TEK00001.PNG)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
15条回答
afei8856
1楼-- · 2020-01-23 17:17
而我读取LTC4100时读取的数据是正确的,时序图也是正确的,就是直接读取锂电池时不正确,读取LTC4100的时序图如下:

(原文件名:TEK00000.PNG)
afei8856
2楼-- · 2020-01-23 19:25
整个程序如下:有些乱

#include <absacc.h>
#include <intrins.h>
#include <C8051F320.h>


#define   SYSTEMCLOCK 12000000           // SYSCLK frequency in Hz

sbit  SMBC=P1^4;//                   SCL
sbit  SMBD=P1^5; //                SDA




unsigned char com_ChSpecInfo=0x11;          //读LTC4100的信息ChargerSpecInfo
unsigned char com_LTC0=0x3C;          //读LTC4100的信息版本信息
unsigned char com_ChStatus=0x13;   //读4100的状态

unsigned char Command_RC=0x0f;     //读剩余电量的指令
signed char Command_C=0x0a;     //读电流的指令
signed char Command_V=0x09;     //读电压的指令
unsigned char Command_BS=0x16;     //读电池状态
signed char Command_ChC=0x14;     //读充电电流的指令
signed char Command_ChV=0x15;     //读充电电压的指令
signed char Command_T=0x11;     //读电流的指令

unsigned char ReceiveData_L,ReceiveData_H,Current_H_7,BatteryStatus_L_6,BatteryStatus_L_5;
  //接收数据的低位,高位,电流正负位(正表示充电,负表示放电),电池状态充放电判断(0表示充电,0x40表示放电),电池状态满充判断(0表示未充满,0x20表示充满)
//unsigned char ack;      用于判断接收确认是否超时,超时为1,未超时为0



void Delay(void)   //延时子程序
{
  _nop_();
  _nop_();
  _nop_();
  _nop_();
_nop_();
   _nop_();
  _nop_();
  _nop_();
_nop_();
  _nop_();
_nop_();
  _nop_();
  _nop_();
  _nop_();
}

//以下函数详见SMbus原理
void Star(void)  //开始子程序      当SMBC为高电平时,SMBD上出现一个下降沿。该条件启动一次传输过程
{

  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  SMBD=0;
  Delay();
  SMBC=0;
}


void Stop(void)  //停止子程序      当SMBC为高电平时,SMBD上出现一个上升沿。该条件停止一次传输过程
{
  SMBC=0;
  Delay();
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
  SMBD=1;

}


bit Ackw(void)  //ACKNOWLEDGE写子程序     SMBC为高时,采样到SMBD为低电平
{
  unsigned char a=255;

  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  while(SMBD)
  {
   
        a--;
        if(!a)
          return 0;

  }
  SMBC=0;

  return 1;
}

void Ackr(void) //ACKNOWLEDGE读子程序   发送应答ACK  SMBC为高时,采样到SMBD为低电平
{
  
  SMBD=0;
  Delay();
  SMBC=1;
  Delay();
  SMBC=0;
  Delay();
}


void Nack(void)  //NOT ACKNOWLEDGE子程序    SMBC为高电平时,采样到SMBD为高电平
{
   
  SMBD=1;
  Delay();
  SMBC=1;
  Delay();
  SMBC=0;
  Delay();
}



void Send(unsigned char sbyte)
{
    unsigned char i = 8;

    while(i--)
    {
        SMBC = 0;
        _nop_();
        SMBD = (bit)(sbyte&0x80);
        sbyte <<= 1;    //时钟保持低可以发送数据
        Delay();
        SMBC = 1;
       Delay();
    }

    SMBC=0;
}


unsigned char Receive(void)
{
    unsigned char i=8;
    unsigned char ddata=0;

    SMBD=1;
    while(i--)
    {
        ddata <<= 1;
        SMBC=0;
        Delay();
        SMBC=1;
        Delay(); //时钟发生一次从高到低的跳变,可以接收数据
        ddata |= SMBD;
    }
    SMBC=0;
    return ddata;
}



void Read(unsigned char addr,unsigned char Command)   //读剩余电量子程序
{
  unsigned int a;//b;
  Star();      //开始                 
  
  a=addr|0x00;                //0x12为锂电池充电器SBC的地址 0x16为SB锂电池的地址
  Send(a);    //发送器件地址0x16  
  
  Ackw();     //发送确认,接收确认指令
                 

  Send(Command);  //发送读剩余电量指令
  

  Ackw();     //发送确认


  Star();                                  //重新开始发送过程
  a=addr|0x01;    //发送器件地址0x17,0x13为锂电池充电器SBC的地址        0x17为SB锂电池的地址
  Send(a);
  
  
  Ackw();    //发送确认


  ReceiveData_L = Receive();  //接收低8位数据
  Ackr();    //接收确认
  ReceiveData_H = Receive();  //接收高8位数据
  Nack();    //非确认
  Stop();    //结束

}





void Delay2(void)   //4s显示延时
{
  unsigned char i,j,k;
  for(i=0;i<255;i++)
   for(j=0;j<255;j++)
    for(k=0;k<200;k++);
}






void Port_IO_Init (void)
{
   P0MDIN |= 0xFF;                     //  pins on P0 are digital
  P1MDIN |= 0xFF;                     //  pins on P1 are digital
  P2MDIN |= 0xFF;                     //  pins on P2 are digital

  
   P0MDOUT |= 0x10;                    // Enable UTX as push-pull output    p0.4 为推免方式         
                                       // Enable URX  and other pins are open-drain


  // P1MDOUT |= 0x30;
  // P1SKIP|=0x30;
  //P2MDOUT |= 0x04;                     // p2.2为推免输出
   XBR0      = 0x01;
   XBR1      = 0x40;

        P0=0xFF;
//        P1=0xff;
}


void UART0_Init (void)
{
   SCON0 = 0x10;                       // SCON0: 8-bit variable bit rate
                                       //        level of STOP bit is ignored
                                       //        RX enabled
                                       //        ninth bits are zeros
                                       //        clear RI0 and TI0 bits
  
   CKCON     = 0x01;                         //系统时钟/4
        TH1       = 0x64;                        //波特率为9600
   TL1 = TH1;                          // init Timer1
   TMOD &= ~0xf0;                      // TMOD: timer 1 in 8-bit autoreload
   TMOD |=  0x20;
   TR1 = 1;                            // START Timer1
   IP |= 0x10;                         // Make UART high priority
   ES0 = 1;                            // Enable UART0 interrupts
   
}



main()
{

   
  unsigned char Current_H,Current_H1,Current_L1,RemainingCapacity_H,RemainingCapacity_L,BatteryStatus_L;

        PCA0MD &= ~0x40;                //PCA方式寄存器,关闭看门狗定时器
       
        OSCICN |= 0x03;                        //内部12M晶振
        CLKSEL = 0x20;
    RSTSRC  = 0x04;                     // Enable missing clock detector

        Port_IO_Init();                        //端口初始化

    UART0_Init();
  


  while(1)
  {
            Read(0x16,0x09);
    //   向串口发送剩余电量,利用串口助手可以看到
   

      RemainingCapacity_H=ReceiveData_H;
      RemainingCapacity_L=ReceiveData_L;
      
       
   SBUF0=0x11;
   while(!TI0);
   TI0=0;

   SBUF0=RemainingCapacity_H;
   while(!TI0);
   TI0=0;
   SBUF0=RemainingCapacity_L;
   while(!TI0);
   TI0=0;         
            
         Delay2();

          
  /* Read(0x16,0x09);        //   向串口发送当前电流,利用串口助手可以看到
   
   
   //if(ack==0)   //读数据成功,则执行赋值
    //{
         Current_H1=ReceiveData_H;
           Current_L1=ReceiveData_L;// }
   
   SBUF0=0x09;
   while(!TI0);
   TI0=0;

   SBUF0=Current_H1;
   while(!TI0);
   TI0=0;
   SBUF0=Current_L1;
   while(!TI0);
   TI0=0;

/*        Read(0x12,com_ChSpecInfo);
   
   if(ack==0)   //读数据成功,则执行赋值
     Current_H=ReceiveData_H;
   
   SBUF0=com_ChSpecInfo;  
   while(!TI0);
   TI0=0;       

   SBUF0=Current_H;
   while(!TI0);
   TI0=0;
   SBUF0=ReceiveData_L;
   while(!TI0);
   TI0=0;            */
  
/*  Read(0x12,com_ChStatus);
   
   if(ack==0)   //读数据成功,则执行赋值
     Current_L1=ReceiveData_L;
   
   SBUF0=com_ChStatus;  
   while(!TI0);
   TI0=0;       

   SBUF0=ReceiveData_H;
   while(!TI0);
   TI0=0;
   SBUF0=ReceiveData_L;
   while(!TI0);
   TI0=0;                 

  

/*    Current_H_7=Current_H&0x80;         //最高位正负判断          

         Delay2();

   Read(0x16,Command_BS);
   //   向串口发送电池状态,利用串口助手可以看到
   
   if(ack==0)   //读数据成功,则执行赋值
     BatteryStatus_L=ReceiveData_L;

   SBUF0=Command_BS;
   while(!TI0);
   TI0=0;

   SBUF0=ReceiveData_H;
   while(!TI0);
   TI0=0;
   SBUF0=BatteryStatus_L;
   while(!TI0);
   TI0=0;
   
    BatteryStatus_L_6=BatteryStatus_L&0x40;
    BatteryStatus_L_5=BatteryStatus_L&0x20;        */
                                                                                                  
   
   
          

        }
  
}
afei8856
3楼-- · 2020-01-23 22:14
后来改了程序 时序没有问题 但是读电池的数据每个都是FF 很是郁闷啊
afei8856
4楼-- · 2020-01-24 02:25
现在还是FF啊 是不是我的时序的问题啊 但是为什么读取LTC4100可以读出来呢 有人给回答一下吗
sdyxd123
5楼-- · 2020-01-24 04:29
 精彩回答 2  元偷偷看……
254501635
6楼-- · 2020-01-24 06:54
你看看延时程序


每个IC芯片的延时要求不一样


delay的时间不足 或者过长 都会产生这样的问题

一周热门 更多>