生活随笔
收集整理的這篇文章主要介紹了
BQ27510 电量计的校准 的 C语言实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
點擊打開鏈接
根據TI官方MSP430平臺移植修改過來的,在Omap37xx(wince)平臺測試,理論上和平臺無關,伸手黨,趕緊復制粘貼代碼吧。如果這篇文章幫助了你,給了好評也無妨。
[cpp]?view plaincopyprint?
? ? ? ? ? ? ? ? ? ?? ?? ?? ?? ?? #include?<windows.h>?? #include?<stdio.h>?? #include?<stdlib.h>?? #include?<string.h>?? #include?<i2cproxy.h>?? #include?"bq27500.h"?? ?? #define?CMD_MAX_DATA_SIZE???512?? #define?MAX_LINE_LEN????????((CMD_MAX_DATA_SIZE?+?4)?*?3)?? #define?CMD_RETRY_DELAY?????100?/*?in?ms?*/?? #define?RETRY_LIMIT?????3?? ?? typedef?enum?{?? ????CMD_INVALID?=?0,?? ????CMD_R,???? ????CMD_W,???? ????CMD_C,???? ????CMD_X,???? }?cmd_type_t;?? ?? ? ? ? ?? typedef?struct?{?? ????cmd_type_t?cmd_type;?? ????unsigned?char?addr;?? ????unsigned?char?reg;?? ????union?{?? ????????unsigned?char?bytes[CMD_MAX_DATA_SIZE?+?1];?? ????????UINT?delay;?? ????}?data;?? ????unsigned?char?data_len;?? ????UINT32?line_num;?? ????CHAR????*line;?? }cmd_t;?? ?? static?UINT32?line_num;?? ?? ? ? ? ? ? ? ? ? ? ???? static?char?*strtok_r(char?*s,?const?char?*delim,?char?**save_ptr)?{???? ????char?*token;?? ???? ????if?(s?==?NULL)?s?=?*save_ptr;?? ???? ???????? ????s?+=?strspn(s,?delim);???? ????if?(*s?==?'\0')????? ????????return?NULL;???? ???? ???????? ????token?=?s;???? ????s?=?strpbrk(token,?delim);???? ????if?(s?==?NULL)???? ???????????? ????????*save_ptr?=?strchr(token,?'\0');???? ????else?{???? ???????????? ????????*s?=?'\0';???? ????????*save_ptr?=?s?+?1;???? ????}???? ???? ????return?token;???? }?? ?? static?char?*strtok(char?*s,?const?char?*delim)???? {???? ????static?char?*last;???? ?? ????return?strtok_r(s,?delim,?&last);?? }?? ?? ?? static?BOOL?i2c_write(HANDLE?hI2C,?cmd_t?*cmd)?? {?? ????int?ret;?? ????DWORD?udwTemp;?? ?????? ????if(hI2C)?? ????{?? ????????udwTemp=cmd->addr?>>1;?? ????????DeviceIoControl(hI2C,?IOCTL_I2C_SET_SLAVE_ADDRESS,?&udwTemp,?sizeof(udwTemp),?NULL,?0,?NULL,?NULL);?? ?? ????????SetFilePointer(hI2C,LOWORD(cmd->reg),NULL,FILE_BEGIN);?? ????????if(!WriteFile(hI2C,?cmd->data.bytes,?cmd->data_len,?&udwTemp,?NULL))?? ????????{?? ????????????RETAILMSG(1,(TEXT("ERROR:?i2c_write:?I2c?WriteFile?failed.\r\n")));?? ????????}?? ????}?? ????return?TRUE;?? }?? ?? ?? static?BOOL?i2c_Read(HANDLE?hI2C,?cmd_t?*cmd)?? {?? ????int?ret;?? ????DWORD?udwTemp;?? ?????? ????if(hI2C)?? ????{?? ????????udwTemp=cmd->addr?>>1;?? ????????DeviceIoControl(hI2C,?IOCTL_I2C_SET_SLAVE_ADDRESS,?&udwTemp,?sizeof(udwTemp),?NULL,?0,?NULL,?NULL);?? ?????? ????????SetFilePointer(hI2C,LOWORD(cmd->reg),NULL,FILE_BEGIN);?? ????????if(!ReadFile(hI2C,?cmd->data.bytes,?cmd->data_len,&udwTemp,?NULL))?? ????????{?? ????????????RETAILMSG(1,(TEXT("ERROR:?i2c_Read:?I2c?ReadFile?failed.\r\n")));?? ????????????return?FALSE;?? ????????}else?? ????????{?? ????????????cmd->data_len=udwTemp;?? ????????}?? ????}?? ?? ????return?TRUE;?? }?? ?? static?BOOL?do_exec_cmd(HANDLE?i2c_file,?cmd_t?*cmd)?? {?? ????unsigned?char?tmp_buf[CMD_MAX_DATA_SIZE];?? ????int?j=0;?? ?? ????switch?(cmd->cmd_type)?{?? ????case?CMD_R:?? ????????return?i2c_Read(i2c_file,?cmd);?? ?? ????case?CMD_W:?? ????????return?i2c_write(i2c_file,?cmd);?? ?? ????case?CMD_C:?? ????????memcpy(tmp_buf,?cmd->data.bytes,?cmd->data_len);?? ????????if?(!i2c_Read(i2c_file,?cmd))?? ????????????return?FALSE;?? ????????if?(memcmp(tmp_buf,?cmd->data.bytes,?cmd->data_len))?{?? ????????????RETAILMSG(1,?(TEXT("Command?C?failed?at?line?%d\r\n"),cmd->line_num));?? ????????????return?FALSE;?? ????????}?? ????????return?TRUE;?? ?? ????case?CMD_X:?? ????????Sleep(cmd->data.delay);?? ????????return?TRUE;?? ?? ????default:?? ????????RETAILMSG(1,?(TEXT("Unsupported?command?at?line?%d\r\n"),cmd->line_num));?? ????????return?FALSE;?? ????}?? }?? ?? static?BOOL?execute_cmd(HANDLE?i2c_file,?cmd_t?*cmd)?? {?? ????int?i?=?1,j=0;?? ????BOOL?ret;?? ?? ????RETAILMSG(0,(TEXT("cmd:cmd_type=%d;addr=%02x,reg=%02x,cmd->data_len=%d,"),cmd->cmd_type,cmd->addr,cmd->reg,cmd->data_len));?? #if?0???//only?for?debug?TODO:delete?? ????RETAILMSG(1,(TEXT("line=%d:"),cmd->line_num));?? ????for(j=0;j<cmd->data_len;j++)?? ????{?? ????????RETAILMSG(1,(TEXT("%02x?"),cmd->data.bytes[j]));?? ????}?? ????RETAILMSG(1,(TEXT("\r\n")));?? #endif?? ?? ????ret?=?do_exec_cmd(i2c_file,?cmd);?? ?? ?????? ????while?(!ret?&&?i?<?RETRY_LIMIT)?{?? ????????Sleep(CMD_RETRY_DELAY);?? ????????ret?=?do_exec_cmd(i2c_file,?cmd);?? ????????i++;?? ????}?? ?? ????if?(!ret)?{?? ????????RETAILMSG(1,?(TEXT("Command?execution?failed?at?line?%d?addr=0x%02x?reg=0x%02x\r\n"),cmd->line_num,?cmd->addr,?cmd->reg));?? ????}?? ?? ????return?ret;?? }?? ?? static?BOOL?get_delay(UINT?*delay)?? {?? ????char?*tok;?? ????UINT?temp;?? ?? ????tok?=?strtok(NULL,?"?");?? ????if?(!tok)?? ????????return?FALSE;??? ?? ????if?(1?!=?sscanf(tok,?"%u",?&temp))?{?? ????????RETAILMSG(1,?(TEXT("Syntax?error?while?parsing?delay?at?line?%d\r\n"),line_num));?? ????????return?FALSE;??? ????}?? ?????? ????*delay?=?(UINT)temp;?? ????return?TRUE;?? }?? ?? ? ? ? ? ? ?? static?int?get_byte(unsigned?char?*byte)?? {?? ????char?*tok;?? ????unsigned?char?temp;?? ?? ????tok?=?strtok(NULL,?"?");?? ????if?(!tok)?? ????????return?1;??? ?? ????if?((strlen(tok)?!=?2)?||?(sscanf(tok,?"%2x",?&temp)?!=?1))?{?? ????????????RETAILMSG(1,?(TEXT("Syntax?error?at?line?%d\r\n"),?line_num));?? ????????????return?-1;??? ????}?? ?? ????*byte?=?(unsigned?char)temp;?? ?? ????return?0;????? }?? ?? static?BOOL?get_addr_n_reg(cmd_t?*cmd)?? {?? ????if?(get_byte(&cmd->addr))?? ????????return?FALSE;?? ?? ????if?(get_byte(&cmd->reg))?? ????????return?FALSE;?? ?? ????return?TRUE;?? }?? ?? static?BOOL?get_data_bytes(cmd_t?*cmd)?? {?? ????int?ret,?i?=?0;?? ????cmd->data_len?=?0;?? ?? ????do?{?? ????????ret?=?get_byte(&cmd->data.bytes[i++]);?? ????}?while?((ret?==?0)?&&?(i?<=?CMD_MAX_DATA_SIZE));?? ?? ????if?(ret?==?0)?{?? ????????RETAILMSG(1,?(TEXT("More?than?allowed?number?of?data?bytes?at?line?%d,?data_len?%d,?i?%d\r\n"),?cmd->line_num,cmd->data_len,?i));?? ????????return?FALSE;?? ????}?? ?? ????cmd->data_len?=?i?-?1;?? ?? ????return?TRUE;?? }?? ?? static?BOOL?get_line(FILE?*bqfs_file,?char?**buffer)?? {?? ????int?c;?? ????int?i?=?0;?? ????BOOL?ret?=?TRUE;?? ????char?*buf;?? ?? ????buf?=?malloc(MAX_LINE_LEN);?? ????line_num++;?? ?? ????while?(1)?{?? ????????c?=?fgetc(bqfs_file);?? ?? ????????if?(feof(bqfs_file))?{?? ????????????break;?? ????????}?else?if?(ferror(bqfs_file))?{?? ????????????RETAILMSG(1,?(TEXT("File?read?error\r\n")));?? ????????????ret?=?FALSE;?? ????????????break;?? ????????}?? ?? ????????if?(((c?==?'\r')?||?(c?==?'\n')?||?(c?==?'\t')?? ????????????||?(c?==?'?'))?&&?(i?==?0))?{?? ????????????? ? ? ?? ????????????RETAILMSG(1,?(TEXT("Leading?whitespace?at?line?%d\r\n"),line_num));?? ????????????if?(c?==?'\n')?? ????????????????line_num++;?? ????????????continue;????? ????????}?else?if?(c?==?'\n')?{?? ?????????????? ????????????break;?? ????????}?? ?? ????????buf[i++]?=?c;?? ?? ????????if?(i?==?MAX_LINE_LEN)?{?? ????????????? ? ? ?? ????????????buf?=?realloc(buf,?MAX_LINE_LEN?*?2);?? ????????????RETAILMSG(1,?(TEXT("Line?%d?longer?than?expected,reallocating..\r\n"),?line_num));?? ????????}?else?if?(i?==?MAX_LINE_LEN?*?2)?{?? ????????????? ? ? ?? ????????????RETAILMSG(1,?(TEXT("Line?%d?too?long,?abort?parsing..\r\n"),line_num));?? ????????????ret?=?FALSE;?? ????????????break;?? ????????}?? ????}?? ?? ????*buffer?=?buf;?? ????buf[i]?=?'\0';?? ?? ????if?(i?<?1)?? ????????ret?=?FALSE;?? ?? ????return?ret;?? }?? ?? ?? static?BOOL?get_cmd(FILE?*bqfs_file,?cmd_t?*cmd)?? {?? ????char?*res;?? ????char?*tok;?? ????char?*buf?=?NULL;?? ????BOOL?ret;?? ?? ????while?((ret?=?get_line(bqfs_file,?&buf)))?{?? ????????if?(buf[0]?==?';')?{?? ????????????? ? ? ?? ????????????RETAILMSG(0,?(TEXT("Comment?line,line_num=%d\r\n"),line_num));?? ????????????free(buf);?? ????????}?else?{?? ????????????break;?? ????????}?? ????}?? ?? ????if?(!ret)?? ????????goto?error;?? ?? ????cmd->line_num?=?line_num;?? ????tok?=?strtok(buf,?":");?? ????if?(!tok?||?(strlen(tok)?!=?1))?{?? ????????RETAILMSG(1,?(TEXT("Error?parsing?command?at?line?%d\r\n"),line_num));?? ????????goto?error;?? ????}?? ?? ????switch?(tok[0])?{?? ????case?'R':?? ????case?'r':?? ????????cmd->cmd_type?=?CMD_R;?? ????????if?(!get_addr_n_reg(cmd))?? ????????????goto?error;?? ????????break;?? ????case?'W':?? ????case?'w':?? ????????cmd->cmd_type?=?CMD_W;?? ????????if?(!get_addr_n_reg(cmd))?? ????????????goto?error;?? ????????if?(!get_data_bytes(cmd))?? ????????????goto?error;?? ????????break;?? ????case?'C':?? ????case?'c':?? ????????cmd->cmd_type?=?CMD_C;?? ????????if?(!get_addr_n_reg(cmd))?? ????????????goto?error;?? ????????if?(!get_data_bytes(cmd))?? ????????????goto?error;?? ????????break;?? ????case?'X':?? ????case?'x':?? ????????cmd->cmd_type?=?CMD_X;?? ????????cmd->data_len?=?1;????????? ????????if?(!get_delay(&cmd->data.delay))?? ????????????goto?error;?? ????????break;?? ????default:?? ????????RETAILMSG(1,?(TEXT("No?command?or?unexpected?command?at?line?%d.\r\n"),line_num));?? ????????goto?error;?? ????}?? ?? ????if(buf)?? ????{?? ????????free(buf);?? ????}?? ????return?TRUE;?? ?? error:?? ????RETAILMSG(1,?(TEXT("get_line?error,line_num=%d\r\n"),line_num));?? ????cmd->cmd_type?=?CMD_INVALID;?? ????free(buf);?? ????return?FALSE;?? }?? ?? ?? ?? ?? ?? int?bqfs_flash(char?*fname)?? {?? ????FILE?*bqfs_file?=?NULL;?? ????cmd_t?*cmd?=?NULL;?? ????int?ret?=?0;?? ????DWORD?udwTemp;?? ????HANDLE?hI2C=NULL;????? ?? ????RETAILMSG(0,(TEXT("bqfs_flush?beging...\r\n")));?? ?? ????bqfs_file?=?fopen(fname,?"r");?? ????if?(!bqfs_file)?{?? ????????RETAILMSG(1,(TEXT("bqfs_flush?fopen?failed.\r\n")));?? ????????ret?=?-1;?? ????????goto?end;?? ????}?? ?? ????hI2C=CreateFile(BATT_I2C_PORT,?GENERIC_READ?|?GENERIC_WRITE,?0,NULL,?OPEN_EXISTING,?0,?NULL);?? ????if(!hI2C)?? ????{?? ????????RETAILMSG(1,(TEXT("bqfs_flash:?I2c?CreateFile?failed.\r\n")));?? ????????ret?=?-1;?? ????????goto?end;?? ????}?? ?? ?????? ?????? ????udwTemp=I2CSLAVEADDR;?? ????DeviceIoControl(hI2C,?IOCTL_I2C_SET_SLAVE_ADDRESS,?&udwTemp,?sizeof(udwTemp),?NULL,?0,?NULL,?NULL);?? ?? ?????? ????udwTemp=I2C_SUBADDRESS_MODE_8;?? ????DeviceIoControl(hI2C,?IOCTL_I2C_SET_SUBADDRESS_MODE,?&udwTemp,?sizeof(udwTemp),?NULL,?0,?NULL,?NULL);?? ?? ?????? ????udwTemp=SLOWSPEED_MODE;?? ????DeviceIoControl(hI2C,?IOCTL_I2C_SET_BAUD_INDEX,?&udwTemp,?sizeof(udwTemp),?NULL,?0,?NULL,?NULL);?? ?? ????cmd?=?malloc(sizeof(cmd_t));?? ????if(!cmd)?? ????{?? ????????RETAILMSG(1,?(TEXT("bqfs_flash?malloc?failed.\r\n")));?? ????????ret=-1;?? ????????goto?end;?? ????}?? ?? ????while?(get_cmd(bqfs_file,?cmd)?&&?execute_cmd(hI2C,?cmd));?? ?? ????if?(feof(bqfs_file))?{?? ????????RETAILMSG(1,?(TEXT("programmed?successfully!\r\n")));?? ????????ret?=?0;?? ????}?else?{?? ????????RETAILMSG(1,?(TEXT("programming?failed!!\r\n")));?? ????????ret?=?-1;?? ????}?? ?? end:?? ?? ????if?(cmd)?? ????????free(cmd);?? ?? ????if(hI2C)?? ????{?? ????????CloseHandle(hI2C);?? ????????hI2C=NULL;?? ????}?? ?? ????if?(bqfs_file)?? ????????fclose(bqfs_file);?? ?? ????return?ret;?? }??
總結
以上是生活随笔為你收集整理的BQ27510 电量计的校准 的 C语言实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。