`求教:使用DS2781读取序列码,电压电流等信息均为ff(示波器波形如图),如果有前辈使用过,还请帮忙指点一下
/********************************************************************
module func
tion :electric power manage
Author:罗黛心言
Creation date:2019.08.27
Modification content and date:
********************************************************************/
//#include "sysconfig.h"
#include "PowerDS2781.h"
#include "delay.h"
#include "sys.h"
/********************************************************************
pin41 PA8
********************************************************************/
uint8_t DS_IO_READ() {return(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_5));}
/********************************************************************
function name: void DS_Rset()
function performance: reset pulse
suction parameter:
outlet parameters:
remark: 标准
********************************************************************/
void DS_Init()
{
DS_OUT_High();
DS_IO_OUT();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
__HAL_RCC_GPIOA_CLK_ENABLE();
}
void DS_Rset()
{
DS_IO_OUT();
DS_OUT_Low();
delay_us(T_RSTL);//
DS_OUT_High();
delay_us(T_PDH);//
//delay_us(T_RSTL-T_PDH-T_PDL/2);
}
/********************************************************************
function name: uint8_t DS_Check(void)
function performance: Power Meter chip detection
suction parameter:
outlet parameters: return 1:no sensor; return 0:a sensor;
remark:
********************************************************************/
uint8_t DS_Check(void)
{
uint8_t retry = 0;
DS_IO_IN();
// while(DS_IO_READ()&&retry<200)
// {
// retry++;
// delay_us(1);
// }
// if(retry>=200)
// return(1);
// retry = 0;
while(!DS_IO_READ()&&retry<24) //脉冲响应 低电平8~24us
{
retry++;
delay_us(1);
}
if(retry>=24)
return(1);
if (retry<15)
delay_us(T_SLOT -retry);
return(0);
// delay_us(T_PDL/2);
// retry = DS_IO_READ();
// //delay_us(T_RSTL-T_PDH-T_PDL/2);
// return (retry);
}
/********************************************************************
function name: uint8_t DS_Readbit(void)
function performance: read data of bit
suction parameter:
outlet parameters: return data
remark:
********************************************************************/
uint8_t DS_ReadBit(void)
{
uint8_t data = 0;
DS_IO_OUT();
DS_OUT_Low();
delay_us(2);
//DS_OUT_High();
DS_IO_IN();
delay_us(T_RDV);
data = DS_IO_READ();
delay_us(T_SLOT-T_RDV-2);
return (data);
}
/********************************************************************
function name: uint8_t DS_ReadByte(void)
function performance: read data of byte
suction parameter:
outlet parameters: return data
remark:
********************************************************************/
uint8_t DS_ReadByte(void)
{
uint8_t i = 0,j = 0,data = 0;
for(i=0;i<8;i++)
{
data>>=1;
if( DS_ReadBit())
data |= 0x80;
}
return (data);
}
/********************************************************************
function name: void DS_Write_Byte(uint8_t data)
function performance:
suction parameter: data: waiting to be written
outlet parameters:
remark:
********************************************************************/
void DS_Write_Byte(uint8_t data)
{
uint8_t i = 0,test = 0;
DS_IO_OUT();
for(i=0;i<8;i++)
{
if(data&0x01)
{
DS_OUT_Low();
delay_us(T_LOW1);
DS_OUT_High();
delay_us(T_SLOT-T_LOW1);
}
else
{
DS_OUT_Low();
delay_us(T_LOW0);
DS_OUT_High();
delay_us(T_SLOT-T_LOW0);
}
data =data >> 1;
}
}
uint16_t Read_byte_data(uint8_t start_address)
{
uint8_t one_byte_data1 = 0;
uint8_t one_byte_data2 = 0;
uint16_t one_word_data = 0;
Write_DS_cmd(Read_Data,start_address);
DS_OUT_Low();
one_byte_data1 = DS_ReadByte(); //LSB
one_byte_data2 = DS_ReadByte(); //MSB
one_word_data = (one_byte_data1<<8)|one_byte_data2;
return(one_word_data);
}
uint8_t Write_data(uint8_t write_address,uint8_t dat)
{
uint8_t i;
uint8_t one_byte_data;
uint8_t pres;
Write_DS_cmd(Write_Data,write_address);
DS_Write_Byte(dat);//写入数据
//osDelay(10);
}
void Write_DS_cmd(uint8_t cmd,uint8_t address)
{
uint8_t pres;
restart:
DS_Rset();
pres = DS_Check();
if(pres) //return fause; // 如果没有器件,返回0
{
delay_us(100);
goto restart;
}
DS_Write_Byte(DS_Just_one); //主机发出Skip Net Address命令
DS_Write_Byte(cmd); // 主机发出xx命令
DS_Write_Byte(address); // 主机发出地址命令
//return ture;
}
void copy_data_ds2780(void)
{
}
uint16_t Get_Voltage(void)
{
uint8_t H = 0,L = 0;
uint8_t state = 0;
uint16_t volat = 0;
DS_Rset();
state = DS_Check();
volat= Read_byte_data(VOLT_RMSB);
return (volat);
}
uint16_t Get_Temp(void)
{
uint8_t H = 0,L = 0;
uint8_t state = 0;
uint16_t tmp = 0;
DS_Rset();
state = DS_Check();
tmp= Read_byte_data(TEMP_RMSB);
return (tmp);
}
uint16_t Get_Current(void)
{
uint8_t H = 0,L = 0;
uint8_t state = 0;
uint16_t volat = 0;
DS_Rset();
state = DS_Check();
volat= Read_byte_data(IREA_RMSB);
return (volat);
}
uint16_t Get_NET(void)
{
uint8_t H = 0,L = 0;
uint8_t state = 0;
uint16_t volat = 0;
DS_Rset();
state = DS_Check();
volat= Read_byte_data(WRAR_AGEO);
volat =volat+1;
volat =volat-1;
return (volat);
}
void write_age()
{
Write_data(WRAR_AGEO,0x13);
}
uint16_t Get_SIGNAL(void)
{
uint8_t H = 0,L = 0,i=0;
uint8_t si[8] = {0};
uint8_t state = 0;
uint16_t volat = 0;
uint8_t pres;
DS_Rset();
state = DS_Check();
restart:
DS_Rset();
pres = DS_Check();
if(pres) //return fause; // 如果没有器件,返回0
{
delay_us(100);
goto restart;
}
DS_Write_Byte(DS_Just_one); //主机发出Skip Net Address命令
DS_Write_Byte(Read_Data); // 主机发出xx命令
DS_Write_Byte(ACRL_SIGN); // 主机发出地址命令
//Write_DS_cmd(Read_Data,ACRL_SIGN);
for(i=0;i<8;i++)
si
= DS_ReadByte(); //LSB
volat = si[0];
return (volat);
}
void Set_register_ds2780()
{
}
#ifndef _POWERDS2781_H
#define _POWERDS2781_H
#include "STM32f4xx_hal.h"
#define DS_IO_OUT() {GPIOA->MODER&=~(3<<(5*2));GPIOA->MODER|=1<<5*2;}
#define DS_IO_IN() {GPIOA->MODER&=~(3<<(5*2));GPIOA->MODER|=0<<5*2;}
#define DS_OUT_High() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_SET)
#define DS_OUT_Low() HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,GPIO_PIN_RESET)
/*******************************电量计芯片EEPROM寄存器定义*************************************/
#define CPRT_RMSB 0X00 //
#define IAVG_RMSB 0X08 //平均电流
#define TEMP_RMSB 0X0A //温度
#define VOLT_RMSB 0X0C //电压
#define IREA_RMSB 0X0E //当前电流
#define ACRN_RMSB 0X10 //累计电流
#define ACRL_RMSB 0X12 //低电流累计
#define WRAR_AGEO 0X14 //年龄
#define ACRL_SIGN 0X3D //低电流累计
#define ACRL_ADDN 0X60 //低电流累计
/*******************************电量计芯片功能寄存器定义*************************************/
#define Read_Data 0X69
#define Write_Data 0X6C
#define Copy_Data 0X48
#define Recall_Data 0XB8
#define Lock_EEPR 0X6A
#define DS_Just_one 0XCC //只有一个电量计芯片时,可不用指定从机地址命令
/*******************************部分常数定义*************************************/
#define Type_Current 0x01
#define Type_Volatage 0x02
#define Type_Temperature 0x03
#define T_RSTL 75
#define T_PDH 5
#define T_PDL 24
#define T_RDV 2
#define T_SLOT 15
#define T_LOW1 1
#define T_LOW0 13
#define Current_Constant 0.00488
/*******************************电池特性参数*************************************/
#define Set_VCHG 0XCF //存储充电电压门限值用来判断检测是否充满电;范围0~9.956V,步长39.04mV 当前设置为8.1V (255/9.956)*8.1 =207
#define Set_VAE 0X00 //有效空电压用于检测空电池电量点,同上
#define Set_TMIN 0XF0 //存储最小充电电流用来检测完全充满状态;范围 0~12.75mV,步长50uV,若RSNS = 20mΩ,则范围0mA~637.5mA (255/637.5)*600=240
#define Set_IAE 0X0E //有效空电流用于检测有效工作时的空电池电量点,同上
uint16_t Get_Data_From_DS_Word(uint8_t slave,uint8_t commend,uint8_t address,uint8_t type);
void MX_GPIO_Init(void);
void DS_Init();
void DS_Rset();
uint8_t DS_Check(void);
void Write_DS_cmd(uint8_t cmd,uint8_t address);
uint16_t Get_Voltage(void);
uint16_t Get_Current(void);
uint16_t Get_SIGNAL(void);
uint16_t Get_NET(void);
uint16_t Get_Temp(void);
void write_age();
#endif
`
0