在一些测试程序中,有时需要通过一个循环发送数据来查看反馈结果,才能取得适合的正确参数。比如I2C写某数据的时候,如果有调试工具可以通过调节写入参数得到准确的某个寄存器值;如果没有调试工具,可以通过一个循环写数据来观察反馈值来获得准确值。
如下:
int cm3623_write_ps() { u8 buf = 0x01,i; //假设最低位必须写1,所以以0x02为增量,以奇数记 int ret = 0; for(i = 0;i <128;i ++){ ret = mt6573_i2c_polling_write(0,0xF0,buf,1); //buf赋值给unsigned char* if(ret == 0){ printf("cm3623_write_ps value is 0x%x \r\n",buf); } buf +=0x02; mdelay(5000); //留5S的时间观察反馈示波器结果。在内核中可以用msleep。这个值必须短,否则易引起I2C总线错误并系统重启 } printf("cm3623_write_ps result is %s \r\n",(ret == 0)?("OK"):("FAIL")); if(ret > 0){ return -1; } return 0; }
============================================================================================================================
在烧录某些器件的固件时,需要以版本号作为判断依据,判断双方一方是从芯片读出的版本号,另一方是新固件中取出的版本号。比如读出芯片的固件是0XF3,而固件中对应的是0x0F,0x03。前者是BCD数值,后者是两个ASCII码值,其实它们是标识相同的版本号。则ASCII转BCD数值的过程如下:
static unsigned char ms6000_GetLibVer(void) { unsigned char a,b; if(MS6000CTPM_FW[156]<'A') //固件数组中的156元素是'F'的ASCII码 a = (MS6000CTPM_FW[156]-'0'); //'0'到'9'的处理 else a = (MS6000CTPM_FW[156]-'A'+10); //'A'到'F'的处理 if(MS6000CTPM_FW[157]<'A') ////固件数组中的157元素是'3'的ASCII码 b = (MS6000CTPM_FW[157]-'0'); else b = (MS6000CTPM_FW[157]-'A'+10); return ((a<<4)+b); //a<<4这个一定要加括号,因为移位运算符优先级低于+ }
以上返回243,恰好跟0xF3的值243是相符的。需要对0-9和A-F的值分开处理的原因是0x46-0x30,它的值不是16,而是0x16。
=======================================================================================================
fgets函数是Linux的ANSIC 的一个一次读取一行字符的I/O库函数,原型是char *fgets(char *s, int n, FILE *stream);用来从流文件中读取(n-1)个字符串,读取完毕后会在最后一个字符后写入一个NULL作结束符。比如文件sss.i的内容是ubcdaag,则执行如下程序:
int _tmain(int argc, _TCHAR* argv[]) { char s[5]; FILE *fp; fp = fopen("sss.i","r"); if (fp == NULL) { puts("open file fail."); } fgets(s,3,fp); printf("data from is %s \r\n",s); fclose(fp); return 1; }
屏幕回显是ub。这个很好理解,问题在于在linux中读取一个变量属性时,之前该变量赋值是0xF4,那么实际读取时是按它的十进制244作字符串来读的;也就是要完整的读取这个变量属性,fgets的第二个参数要是4才行,如果是3的话,读出的始终只有24。