#include "MC95FG308.h"
#include <intrins.h>
#define SDA_IN P1IO &=~(1<<3)
#define SDA_OUT P1IO |=(1<<3)
#define SCL_OUT P1IO |=(1<<4)
#define SDA P13
#define SCL P14
#define u8 unsigned char
#define u16 unsigned int
#define uint u16
#define uchar u8
//全局变量
u8 crc,crc_bq3050,buf[3];
void delay(uint ms);
void I2C_Delay()
{
u16 i;
for(i=20;i>0;i--);
}
void iic_init()
{
SDA_OUT;
SCL_OUT;
SDA=0;
SCL=0;
}
void iic_start()
{
SDA=1;
I2C_Delay();
SCL=1;
I2C_Delay();
SDA=0;
I2C_Delay();
SCL=0;
}
void iic_stop()
{
SDA=0;
I2C_Delay();
SCL=1;
I2C_Delay();
SDA=1;
I2C_Delay();
}
unsigned char write_byte(u8 c)
{
unsigned char i, ack=1;
SDA_OUT ; //设置SDA数据口方向
SCL_OUT;
for(i=0;i<8;i++)
{
if(c&0x80)
SDA=1;
else
SDA=0;
_nop_();
_nop_();
SCL=1;
// I2C_Delay(); 改
I2C_Delay();
SCL=0;
I2C_Delay();
_nop_();
_nop_();
c<<=1;
_nop_();
}
SDA=0;
I2C_Delay();
// SDA_IN; //设置SDA数据口方向
SCL=1;
I2C_Delay();
if(SDA)
ack=0; //失败
else
ack=1;
SCL=0;
// SDA_OUT ;//设置SDA数据口方向
I2C_Delay();
return ack;
}
//读一个字节 ack :1 时应答 ,0时不应答
u8 read_iic(u8 ack)
{
unsigned char i , ret;
// SDA=1;
SCL_OUT ;
SDA_IN; //设置SDA数据口方向
I2C_Delay();
for(i=0;i<8;i++)
{
SCL=0;
I2C_Delay();
I2C_Delay();
SCL=1;
ret<<=1;
if(SDA)
ret++;
I2C_Delay();
}
SCL=0;
I2C_Delay();
SDA_OUT;
I2C_Delay();
if(ack)
SDA=0;
else
SDA=1;
I2C_Delay();
I2C_Delay();
SCL=1;
I2C_Delay();
I2C_Delay();
SCL=0;
I2C_Delay();
I2C_Delay();
return(ret);
}
unsigned int read_bq3050(void)
{
unsigned char x,y;
iic_start();
write_byte(0x16);
delay(1);
write_byte(0x09);
delay(1); //适当延迟下
iic_start();
write_byte(0x17);
delay(1);
x=read_iic(1);
y=read_iic(1);
crc=read_iic(0);
iic_stop();
return(y*256+x);
}
void write_bq3050(u8 romadrr,u8 firstbyte,u8 secondbyte)
{
iic_start();
write_byte(0x16);
delay(1);
write_byte(romadrr);
delay(1);
write_byte(firstbyte);
delay(1);
write_byte(secondbyte);
delay(1);
write_byte(crc_bq3050); //这里的crc效验是全局的变量
iic_stop();
}
void delay(uint ms)
{
uchar t;
while(ms--)
{
for(t = 0; t < 50; t++);
}
}
//串口函数
void uart_init()
{
UCTRL1=0x06;// 00000110
UCTRL2=0xee;// 11101110
UCTRL3=0x00;
UBAUD=51;
}
void uputch(char ch) //发送数据
{
while( !(USTAT & 0x80));
UDATA = ch;
}
char ugetch(void) // 单捞磐 罐阑锭 鳖瘤 措扁
{
char ch;
while( (USTAT&0x20) != 0x20);
ch=UDATA;
return ch;
}
void send_string(uchar *pt,uchar len) //发送字符串
{
uchar k=0;
do
{
uputch(*(pt+k));k++;
}while(k<len);
}
void send_decimal(u16 temp)
{
uputch(temp%100000/10000+0x30);
uputch(temp%10000/1000+0x30);
uputch(temp%1000/100+0x30);
uputch(temp%100/10+0x30);
uputch(temp%10/1+0x30);
uputch(0x0a);
}
//crc效验程序
unsigned char cal_crc(unsigned char *ptr, unsigned char len)
{
unsigned char i;
unsigned char crc=0;
while(len--!=0) //5次循环
{
for(i=0x80; i!=0; i/=2) //8次for循环
{
if((crc&0x80)!=0) //判断最高位是否是1
{crc*=2; crc^=0x07;} /* 余式CRC乘以2再求CRC */
else
crc*=2;
if((*ptr&i)!=0)
crc^=0x07; /* 再加上本位的CRC */
}
ptr++;
}
return(crc);
}
void main()
{
u16 temp;
u8 *pcrc;
iic_init();
uart_init();
send_string("串口初始化成功",14);
uputch(0x0a);
while(1);
/* {
temp=read_bq3050();
delay(10000);
send_decimal(temp);
buf[0]=0x16;
buf[1]=0x46;
buf[2]=0x04;
buf[3]=0x00;
delay(20000);
} */
}
//*在接受中断服务程序中把数据保存在数据中buf[4]
void RX_interutpt(void) interrupt 7
{
u8 i;
USTAT&=~(1<<5); //清除标志位
//这里是对数据进行处理
for(i=0;i<3;i++)
{
buf[i]=ugetch(); //全局变量保存,然后发给iic电量计
}
crc_bq3050=cal_crc(buf,4);//这里写的是全局crc效验位
if((buf[0]==0x46)&&(buf[1]==0x02)&&(buf[2]==0x00))
write_bq3050(buf[0],buf[1],buf[2]);
delay(20000);
}
评论0