#include "hal_sy6970.h" #include "hal_adapter.h" #define __nop() __asm__("NOP") #define GPIO_SDA DioConf_DioChannel_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA #define GPIO_SCL DioConf_DioChannel_PTC5_GPIO_IN_OUT_MCU_BATT_IIC_SCK #define READ_SDA4 Dio_ReadChannel(GPIO_SDA) #define GPIO_SETPIN(channel) Dio_WriteChannel(channel,1) #define GPIO_RESETPIN(channel) Dio_WriteChannel(channel,0) #define IIC_SDA4(n) (n?GPIO_SETPIN(GPIO_SDA):GPIO_RESETPIN(GPIO_SDA)) #define IIC_SCL4(n) (n?GPIO_SETPIN(GPIO_SCL):GPIO_RESETPIN(GPIO_SCL)) #define sy6970_speed 4 //需要示波器调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); Port_SetPinDirection(PortConfigSet_PortContainer_GPIO_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA,PORT_CI_PORT_PIN_IN); //????Port_SetPinDirection(GPIO_SDA,PORT_CI_PORT_PIN_IN); } 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); Port_SetPinDirection(PortConfigSet_PortContainer_GPIO_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA,PORT_CI_PORT_PIN_OUT); //????Port_SetPinDirection(GPIO_SDA,PORT_CI_PORT_PIN_OUT); } static void iic_start(void) { SDA_OUT4(); IIC_SDA4(1); IIC_SCL4(1); Dio_FlipChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2); delay_us(sy6970_speed); Dio_FlipChannel(DioConf_DioChannel_PTE1_GPIO_OUT_MCU_LED2); 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); } // IIC_SDA4(1); // IIC_SCL4(1); // iic_ack();//add ack test } 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(); } 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); } }