分类: LINUX
2011-02-26 17:39:21
自己定义的协议
配置方发送"cfg0" + 0x1234 + 3字节,表示要配置参数0为0x1234。
发送"cfg7" + 2字节 + 3字节,表示要读回已经配置好的参数。
下面是STC12C5628AD的配置部分代码
struct uart_buf{
char has_pack; //有配置包,需要处理标志,1:有包
unsigned char *index; //缓冲区指针
unsigned char uart_rd_buf[200]; //xdata扩展RAM区共512字节
};
/*
//参数在eeprom扇区里的位置定义
#define IAP_ADDRESS 0x6e00 //第56个扇区逻辑上(0-55)
#define VOL_REF (IAP_ADDRESS) //浮充电压参考(25度时) 占2个字节
#define VOL_CO (VOL_REF + 2) //AD电压通道系数 占2个字节
#define AMP_CO (VOL_CO + 2) //AD电流通道系数 占2个字节
#define MAX_AMP (AMP_CO + 2) //最大充电电流 占2个字节
#define SHORT_TIME (MAX_AMP + 2) //短路限流电阻时间 占1个字节
*/
//保存串口配置的参数到eeprom,处理配置包
void eeprom_save(void) _task_ eeprom
{
int xdata i;
char xdata n; //接收到的配置包个数
unsigned int xdata tmp = 0;
char xdata need_save = 0; //不需要保存参数标志
// printf("\n process cfg\n"); //处理配置
/*
EA =0;
//IAP_erase_sector(IAP_ADDRESS);
EA =1;
for(i=0;i<512;i++){
dat = IAP_read_byte(IAP_ADDRESS+i);
os_wait(K_TMO, 1, 1);
printf("%d: %d\t",i,dat);
}
*/
//63 66 67 30 0a c9 63 66 67
//如果有配置包
if(p_uart->has_pack)
{
n = (p_uart->index - p_uart->uart_rd_buf)/9; //一共多少个配置包 一个包9字节
while(n--){
// printf("%d\n",(int)n);
if(strncmp("cfg",&p_uart->uart_rd_buf[n*9],3)) //从最后一个配置包比较
continue;
// printf("cfg");
memcpy(&tmp, &(p_uart->uart_rd_buf[n*9+4]), 2); //将参数拷贝到tmp
switch(p_uart->uart_rd_buf[n*9+3]){
case '0': //配置第一个参数 浮充电压
if((tmp > 2760+240) || (tmp < 2760-240)){ //如果参数不合法
charge_vol_ref = 2760; //默认27.6V
}else{
charge_vol_ref = tmp;
need_save = 1; //一旦更新参数就需要保存到eeprom
}
// printf("your data: %d\t",tmp);
break;
case '1': //配置第二个参数 ad通道 电压系数
if((tmp > 1000+1000) || (tmp < 1000-900)){ //如果参数不合法
vol_co = 1000; //默认1000
}else{
vol_co = tmp;
need_save = 1;
}
break;
case '2': //配置第3个参数 ad通道 电流系数
if((tmp > 1000+1000) || (tmp < 1000-900)){ //如果参数不合法
amp_co = 1000; //默认1000
}else{
amp_co = tmp;
need_save = 1;
}
break;
case '3': //配置最大充电电流
if((tmp > 100) || (tmp < 30)){ //如果参数不合法 大于10A或者小于3A
max_charge_amp = 40; //默认4A
}else{
max_charge_amp = tmp;
need_save = 1;
}
break;
case '4': //配置短路限流电阻时间
if((tmp > 254) || (tmp < 100)){ //如果参数不合法
short_time = 100; //默认100
}else{
short_time = tmp;
need_save = 1;
}
break;
case '5':printf("parameter5 not using\t");break;
case '6':printf("parameter6 not using\t");break;
case '7': //读取配置信息
printf("\nbegain cfg0:%d cfg1:%d cfg2:%d cfg3:%d cfg4:%d end\n",charge_vol_ref, vol_co,
amp_co, max_charge_amp, (int)short_time);
break;
default:break;
}
}
//如果有参数被更改,保存参数到eeprom
if(need_save){
for(i=0;i<3;i++){ //写入eeprom,如果三次都不成功,说明eeprom有问题
printf("saving ");
IAP_erase_sector(IAP_ADDRESS); //先擦除
write_eeprom((unsigned char *)&charge_vol_ref, VOL_REF, 2);
write_eeprom((unsigned char *)&vol_co, VOL_CO, 2);
write_eeprom((unsigned char *)&_co, AMP_CO, 2);
write_eeprom((unsigned char *)&max_charge_amp, MAX_AMP, 2);
write_eeprom((unsigned char *)&short_time, SHORT_TIME, 1);
read_eeprom((unsigned char *)&tmp, VOL_REF, 2);
if(tmp != charge_vol_ref){ //如果写入的参数不正确,从新擦除扇区 写入参数
continue;
my_err = EEPROM_WRITE_ERR;
}
read_eeprom((unsigned char *)&tmp, VOL_CO, 2);
if(tmp != vol_co){ //如果写入的参数不正确,从新擦除扇区 写入参数
continue;
my_err = EEPROM_WRITE_ERR;
}
read_eeprom((unsigned char *)&tmp, AMP_CO, 2);
if(tmp != amp_co){ //如果写入的参数不正确,从新擦除扇区 写入参数
continue;
my_err = EEPROM_WRITE_ERR;
}
read_eeprom((unsigned char *)&tmp, MAX_AMP, 2);
if(tmp != max_charge_amp){ //如果写入的参数不正确,从新擦除扇区 写入参数
continue;
my_err = EEPROM_WRITE_ERR;
}
read_eeprom((unsigned char *)&tmp, SHORT_TIME, 1);
tmp >>=8;
if(tmp != short_time){ //如果写入的参数不正确,从新擦除扇区 写入参数
continue;
my_err = EEPROM_WRITE_ERR;
}
break; //如果写入成功,退出三次尝试
}
if(!my_err) printf("ok\n"); //保存成功,回应ok
else printf("err\n");
}
p_uart->index = p_uart->uart_rd_buf; //指向读缓冲区第一个字节
p_uart->has_pack = 0;
REN = 1; //可以接收串口数据
}else{
// printf("\t no pack\n");
}
os_delete_task(eeprom);
}
协议可以更好,可以把所有参数放在数组里,就不用一个一个参数的去处理了。
chinaunix网友2011-03-06 13:30:08
很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com