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
#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; */
}
}
一周热门 更多>