#include "hal_sy6970.h" #define READ_SDA4 GPIO_ReadInputPins(GPIO_PORT_A,GPIO_PIN_12) #define IIC_SDA4(n) (n?GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12):GPIO_ResetPins(GPIO_PORT_A, GPIO_PIN_12)) #define IIC_SCL4(n) (n?GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_11):GPIO_ResetPins(GPIO_PORT_A, GPIO_PIN_11)) #define sy6970_speed 5 //需要示波器调1us的时间 static void delay_us(uint16_t time) { uint16_t i; for(i=time;i>0;i--) { __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); } } static void iic4_init(void) { stc_gpio_init_t pstcGpioInit1; GPIO_StructInit(&pstcGpioInit1); pstcGpioInit1.u16PinDir = PIN_DIR_OUT; pstcGpioInit1.u16PinState = PIN_STAT_RST; GPIO_Init(GPIO_PORT_A, GPIO_PIN_11,&pstcGpioInit1); GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit1); GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_11); GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12); } void sy6970_init(void) { iic4_init(); } static void SDA_IN4(void) { stc_gpio_init_t pstcGpioInit3;//iic的引脚 pstcGpioInit3.u16PinDir = PIN_DIR_IN; //pstcGpioInit3.u16PinInputType = PIN_PU_ON; GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3); } static void SDA_OUT4(void) { stc_gpio_init_t pstcGpioInit3; pstcGpioInit3.u16PinDir = PIN_DIR_OUT; pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS; GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3); } static void iic_start(void) { SDA_OUT4(); IIC_SDA4(1); IIC_SCL4(1); delay_us(sy6970_speed); IIC_SDA4(0); delay_us(sy6970_speed); IIC_SCL4(0); } static void iic_stop(void) { SDA_OUT4(); IIC_SCL4(0); IIC_SDA4(0); delay_us(sy6970_speed); IIC_SCL4(1); IIC_SDA4(1); delay_us(sy6970_speed); } static void iic_ack(void) { SDA_OUT4(); IIC_SCL4(0); IIC_SDA4(0); delay_us(sy6970_speed); IIC_SCL4(1); delay_us(sy6970_speed); IIC_SCL4(0); } static void iic_nack(void) { SDA_OUT4(); IIC_SCL4(0); IIC_SDA4(1); delay_us(sy6970_speed); IIC_SCL4(1); delay_us(sy6970_speed); IIC_SCL4(0); } static uint8_t iic_wait_ack(void) { uint16_t t =200; SDA_OUT4(); IIC_SDA4(1);delay_us(1); IIC_SCL4(1);delay_us(1); SDA_IN4(); while(READ_SDA4) { t--; if(t==0) { iic_stop(); return 1; } delay_us(1); } IIC_SCL4(0); return 0; } static void iic_send_byte(uint8_t byte) { uint8_t bit_cnt; SDA_OUT4(); IIC_SCL4(0); for(bit_cnt=0;bit_cnt<8;bit_cnt++) { if(byte&0x80) IIC_SDA4(1); else IIC_SDA4(0); byte<<=1; delay_us(sy6970_speed); IIC_SCL4(1); delay_us(sy6970_speed); IIC_SCL4(0); } } static uint8_t iic_recive_byte(unsigned char ack) { uint8_t retc = 0; uint8_t bit_cnt; SDA_IN4(); delay_us(1); for(bit_cnt=0;bit_cnt<8;bit_cnt++) { IIC_SCL4(0); delay_us(sy6970_speed); IIC_SCL4(1); retc=retc<<1; if(READ_SDA4) retc++; delay_us(sy6970_speed); } return(retc); } static void sy6970_write_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t WData) { iic_start(); iic_send_byte(dev_addr); iic_wait_ack(); iic_send_byte(RAddr); iic_wait_ack(); iic_send_byte(WData); iic_wait_ack(); iic_stop(); } static void sy6970_read_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t *RData) { iic_start(); iic_send_byte(dev_addr); iic_wait_ack(); iic_send_byte(RAddr); iic_wait_ack(); iic_start(); iic_send_byte(dev_addr|0x01); iic_wait_ack(); *RData = iic_recive_byte(0); iic_stop(); } _Bool sy6970_write_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num ) { iic_start(); //起始信号 //发送设备地址(写) iic_send_byte ( SlaveAddr ); //等待应答 iic_wait_ack(); //发送寄存器地址 iic_send_byte ( RegAddr ) ; //等待应答 iic_wait_ack(); while ( Num-- ) //循环写入数据 { //发送数据 iic_send_byte ( *Buf ); //等待应答 iic_wait_ack(); Buf++; //数据指针偏移到下一个 delay_us(10); } iic_stop(); //停止信号 return 0; } _Bool sy6970_read_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num ) { iic_start(); //起始信号 //发送设备地址(写) iic_send_byte ( SlaveAddr ); //等待应答 iic_wait_ack(); //发送寄存器地址 iic_send_byte ( RegAddr ); //等待应答 iic_wait_ack(); iic_start(); //重启信号 //发送设备地址(读) iic_send_byte ( SlaveAddr + 1 ); //等待应答 iic_wait_ack(); while ( Num-- ) { //偏移到下一个数据存储地址 if ( Num == 0 ) { *Buf = iic_recive_byte ( 0 ); //最后一个数据需要回NOACK } else { *Buf = iic_recive_byte ( 1 ); //回应ACK } Buf++; } iic_stop(); return 0; } /**********************************************SY6970 操作函数****************************************************/ /* * 设置sy6970输入电流的大小 * * set_val 需要操作的从机设备 Fast Charge Current Limit: ICHG=[ICHG]*64mA Range:0mA(0000000)-5056mA(1001111) 0000000=0mA(Disable Charge) 0000001=64mA … 0100000=2048mA(Default) … 1001111~1111111=5056mA * * 返回值:void * */ void sy6970_set_input_current_limit(uint8_t set_val) { set_val&= 0x7F; sy6970_write_byte(SY6970_ADDR,0x04,set_val); } /* * 设置sy6970输入电压的大小 * * set_val 需要操作的从机设备 Charge Voltage Limit: VREG=3.840V+[VREG]*16mV Range:3.840V-4.608V(110000) 000000=3.840V 000001=3.856V … 010111=4.208V(Default) … 110000~111111=4.608V * * 返回值:void * */ void sy6970_set_input_voltage_limit(uint8_t set_val) { set_val&= 0xFC; sy6970_write_byte(SY6970_ADDR,0x06,set_val); } /*充电使能*/ void sy6970_charge_enable(void) { uint8_t set_val = 0x00; set_val&= 0x01<<4; sy6970_write_byte(SY6970_ADDR,0x03,set_val); } /*充电不使能*/ void sy6970_charge_disable(void) { uint8_t set_val = 0x00; set_val&= 0x00<<4; sy6970_write_byte(SY6970_ADDR,0x03,set_val); } /*充电状态查询 返回值: 00-Not Charging 01-Pre-charge (VBAT >=3; status &=0x03; return status; } uint8_t statusx = 0; #include "FreeRTOS.h" #include "task.h" void sy6970_task(void *argv) { while(1) { statusx = sy6970_charge_status(); vTaskDelay(500); } }