迪文屏有自带的串口更新程序,目前要使用单片机实现使用can更新时发现更新超过两包数据会会导致迪文屏黑屏,但是使用官方自带的更新程序就不会,写一个简单的串口上位机分析下问题。
1.首先了解mfc activex控件,网上安装方法,我使用的vs2010,应该差不多,嘿嘿VS2017 MFC添加串口控件_白变黑的博客-CSDN博客_mfc串口控件
2.
拖入一些按钮
首先下拉框实现函数
波特率选择函数,
串口波特率选择,打开,发送,接收的方法实现参考了下面的程序
vs2010进行MFC的串口通信_xian0-666的博客-CSDN博客_vs2010mfc串口通信
的方法:
波特率选择的实现方法,此函数要放入OnInitDialog函数中,在串口创建时会会执行此函数,在下拉框中出现波特率300,600,1200等选择。
CString str1[]={_T("300"),_T("600"),_T("1200"),_T("2400"),_T("4800"),_T("9600"),
_T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200")};
for(int i=0;i<12;i++)
{
int judge_tf = e_combo2.AddString(str1[i]);
if((judge_tf == CB_ERR) || (judge_tf == CB_ERRSPACE))
MessageBox(_T("build baud error!"));
}
e_combo2.SetCurSel(11);
在确定此电脑有几个可用串口时,使用遍历的方法实现
调用下列函数时,会检查当前电脑空闲的串口,填入下拉框,实现原理:逐个去打开串口,占用的或者没有插入的串口肯定会失败,失败就不加入下拉框中了,成功的就是可用串口。
void Cuart123Dlg::get_vaild()
{
char i;
char j = 0;
//CString str;
//HANDLE hCom;
//DWORD dwError;
//BOOL bResult;
//e_combo1.RemoveAll();
for(i=0;i<15;i++)
{
//str.Format(_T("COM%d"),i+1);
str.Format(_T("COM%d"),i+1);
hCom = CreateFile(str, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if (hCom == INVALID_HANDLE_VALUE)
{
dwError = GetLastError();
if (dwError == ERROR_ACCESS_DENIED)
{
bResult = TRUE;
e_combo1.InsertString(i,str);
}
}
else
{
bResult = TRUE;
//str.Format(_T("com %d"),i+1);
e_combo1.InsertString(j,str);
order[j] = i+1;
j++;
CloseHandle(hCom);
}
//e_combo1.InsertString(i,str);
}
}
串口打开函数
void Cuart123Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString str,str1,n;
GetDlgItemText(IDC_BUTTON_Open,str);
CWnd *h1;
h1 = GetDlgItem(IDC_BUTTON_Open); //指向控件的caption
if(!e_mscomm1.get_PortOpen())
{
//e_combo2.GetLBText(order[e_combo1.GetCurSel()],str1); //取得所选字符串放在str1里面
//e_combo2.GetLBText(3,str1); //取得所选字符串放在str1里面
UpdateData(0);
e_combo2.GetLBText(e_combo2.GetCurSel(),str1); //取得所选字符串放在str1里面
str1 = str1+','+'n'+','+'8'+','+'1'; //
//str1 = "115200,n,8,1";
//e_mscomm1.put_CommPort(e_combo1.GetCurSel()+1); //选择串口
e_mscomm1.put_CommPort(order[e_combo1.GetCurSel()]); //选择串口
e_mscomm1.put_InputMode(1); //二进制
e_mscomm1.put_Settings(str1); //参数“波特率,n,8,1”
e_mscomm1.put_InputLen(1024); //设置并返回Input属性从接收缓冲区读取的1024个字符
e_mscomm1.put_RThreshold(1); //接收缓冲区收到一个字符就会使得CMSComm控件产生OnComm消息
e_mscomm1.put_RTSEnable(1); //确定RTS是否有效,请示允许发送数据
e_mscomm1.put_PortOpen(true);
if(e_mscomm1.get_PortOpen())
{
str = _T("关闭串口");
UpdateData(true);
h1->SetWindowText(str);
}
else
{
e_mscomm1.put_PortOpen(false);
if(str != _T("打开串口"))
{
str = _T("打开串口");
UpdateData(true);
h1->SetWindowText(str);
}
}
printf("打开串口");
}
else
{
str = _T("打开串口");
UpdateData(true);
h1->SetWindowText(str);
e_mscomm1.put_PortOpen(false);
}
}
串口接收函数:
::GetLocalTime(&sysTime);
此函数可以获得当前电脑的时间,精确度在ms级别。可以明确知道接收时间的时间
下列函数可以接收串口收到的字符:注意:波特率没有选对时,接收的可能为0xfe等错误数据
下列函数会对迪文屏发来的数据进行确认,交由发送函数处理
void Cuart123Dlg::OnCommMscomm1()
{
// TODO: 在此处添加消息处理程序代码
int j = 1;
int i;
CString str1,str2;
if(e_mscomm1.get_CommEvent()==2)
{
char str[1024]={0};
char str_1[1024]={0};
char str_2[1024]={0};
long k;
int len = 0;
VARIANT InputData=e_mscomm1.get_Input();
COleSafeArray fs;
fs = InputData;
len = fs.GetOneDimSize();
for(k=0;k<len;k++)
fs.GetElement(&k,str+k);
//肯定响应处理
T5L::respon = T5L::respone((unsigned char*)str,len);//因为
T5L::respon_valid = 1;
int i;
for(i = 0;i<len;i++)
{
printf("%x_",str[i]);
}
printf("\n");
//SYSTEMTIME sysTime;
::GetLocalTime(&sysTime);
sprintf(str_2,"[%d:%d:%d:%3d]",sysTime.wHour,sysTime.wMinute,sysTime.wSecond,sysTime.wMilliseconds);
ShowInfo((CString)str_2,0);
ShowInfo2((CString)str_2,0);
//list_box.InsertString(list_box.GetCount(),(CString)"接收数据:");
str1.Empty();
str2.Empty();
#if 0
for(i = 0;i <len;i++)
{
BYTE bt = *(char *)(str+i);
str1.Format(_T("%x"),bt);
str2 += str1;
}
ShowInfo((CString)str2,0);
#endif
i =0;
//---------------显示函数--------------------
#if 1
while(j)
{
if((i+dis_length) < k)
{
change::num_sring((unsigned char*)str_1,(unsigned char*)(str+i),dis_length);
i += dis_length;
}
else
{
change::num_sring((unsigned char*)str_1,(unsigned char*)(str+i),k-i);
j = 0;
}
//list_box.InsertString(list_box.GetCount(),(CString)str_1);
//list_box.SetCurSel(list_box.GetCount()-1);
ShowInfo((CString)str_1,0);
ShowInfo2((CString)str_1,0);
}
#define fail_count 40
if((T5L::stop_timer == t5l.t5l_update_step)||(t5l.respon_no_count >fail_count))
{
KillTimer(timer1);
t5l.clear_reg();
if(t5l.respon_no_count >fail_count)
{
ShowInfo((CString)"刷写失败",0);
//list_box.InsertString(list_box.GetCount(),(CString)"刷写失败");
//list_box.SetCurSel(list_box.GetCount()-1);
}
}
//else if(T5L::send_stop== t5l.t5l_update_step_now)||()
else if(!T5L::respon) //应答失败,等一会再进去
{
SetTimer(timer1,1000,NULL);//10ms进去1次,开启定时器1
}
else if((T5L::send_stop == t5l.t5l_update_step)||(T5L::save_data == t5l.t5l_update_step))
{
SetTimer(timer1,100,NULL);//10ms进去1次,开启定时器1
}
else
{
SetTimer(timer1,50,NULL);//10ms进去1次,开启定时器1
//PostMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON3, BN_CLICKED), NULL);
//SendMessage(WM_COMMAND, MAKEWPARAM(IDC_BUTTON3, BN_CLICKED), NULL);
}
printf("\n");
printf("失败次数%d\n",t5l.respon_no_count);
UpdateData(false);
#endif
}
}
串口发送函数:
此函数实现了打开文件,读取icl文件,读取文件名最前段数字,因为迪文资源更新文件前的数字代表了在flash排列位置,仿照迪文串口更新时先传后面数据,再传前面的数据,排除差异。
void Cuart123Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
CString send_date;
int i;
UpdateData(true);
#if !hl_test
KillTimer(timer1);//
#endif
#if 0
//显示函数
send_date = "";//变成空字符
for(i = 0;i<dis_length;i++)
{
send_date.AppendChar(e_editSend.GetAt(i));
}
list_box.InsertString(list_box.GetCount(),(CString)"发送:");
//list_box.InsertString(list_box.GetCount(),send_date);
//list_box.SetCurSel(list_box.GetCount()-1);
#endif
unsigned int j;
unsigned char temp = 0;
unsigned char buffer_2[30];//显示数字
if(T5L::stop_timer == t5l.t5l_update_step)
return ;
{
if(T5L::net_default == t5l.t5l_net_step)//网络层空闲才能去取值
{
if(T5L::t5l_default == t5l.t5l_update_step)
{
t5l.t5l_can_num = 0;//初始化要发送的值
//t5l.t5l_can_Sum = 0;//要发送的总长度,此变量赋值在打开函数处
t5l.t5l_update_step = T5L::send_start;
//t5l.t5l_can_xia = 0;
t5l.t5l_can_xia = t5l.t5l_sub[--t5l.t5l_sub_sub];
t5l.t5l_flash_addr = t5l.t5l_flash_addr*8+t5l.t5l_sub_sub;//预设为23
}
if((T5L::send_start == t5l.t5l_update_step))
{
t5l.t5l_update_step_now = T5L::send_start;
#if 0
if(t5l.t5l_can_xia < ((T5L_Ram_Stopt - T5L_Ram_Start)*2))//因为ram为两个字节
t5l.t5l_can_num = ((T5L_Ram_Stopt - T5L_Ram_Start)*2) - t5l.t5l_can_xia;//计算要发送的长度
else
t5l.t5l_can_num = t5l.t5l_can_Sum - t5l.t5l_can_xia;//计算要发送的长度
#endif
t5l.t5l_can_num = t5l.t5l_can_Sum - t5l.t5l_can_xia;//计算要发送的长度
#if 0
//此处ram最大最小变化后会有变化
if((t5l.t5l_ram_addr == 0xBFC0)&&(t5l.t5l_can_num > 0x80))//最后一帧特殊
{
t5l.t5l_can_num = 0x80;
t5l.t5l_update_step = T5L::send_end;//结束,
}
else if(t5l.t5l_can_num > max_ram_num)//防止超过最大ram
{
t5l.t5l_can_num = max_ram_num;
}
else
{
t5l.t5l_update_step = T5L::send_end_all;//传送完成结束,
}
#endif
//此处ram最大最小变化后会有变化
if((t5l.t5l_ram_addr == 0xBFC0))//最后一帧特殊
{
if(t5l.t5l_can_num > 0x80)
t5l.t5l_can_num = 0x80;
if(t5l.t5l_sub_sub)
{
if(t5l.is_no_get_statue)
{
t5l.t5l_update_step = T5L::pre_send_end;//结束,
}
else
{
t5l.t5l_update_step = T5L::send_end;//结束,
}
}
else
{
if(t5l.is_no_get_statue)
{
t5l.t5l_update_step = T5L::pre_send_end_all;//全部结束,
}
else
{
t5l.t5l_update_step = T5L::send_end_all;//全部结束,
}
}
}
else if(t5l.t5l_can_num > max_ram_num)//防止超过最大ram
{
t5l.t5l_can_num = max_ram_num;
}
else
{
if(t5l.t5l_sub_sub)
{
if(t5l.is_no_get_statue)
{
t5l.t5l_update_step = T5L::pre_send_end;//结束,
}
else
{
t5l.t5l_update_step = T5L::send_end;//结束,
}
}
else
{
if(t5l.is_no_get_statue)
{
t5l.t5l_update_step = T5L::pre_send_end_all;//全部结束,
}
else
{
t5l.t5l_update_step = T5L::send_end_all;//全部结束,
}
}
}
//下面函数会t5l.t5l_ram_addr加上去
t5l.real_count = t5l.send_handle(t5l.net_date,s19+t5l.t5l_can_xia,t5l.t5l_can_num);//发送函数
t5l.t5l_can_xia += t5l.t5l_can_num;
if((T5L::send_end == t5l.t5l_update_step)||(T5L::pre_send_end == t5l.t5l_update_step))
{
t5l.t5l_can_xia = t5l.t5l_sub[--t5l.t5l_sub_sub];//进入第二包的位置
}
t5l.t5l_net_step = T5L::net_init;
}
else if((T5L::pre_send_end == t5l.t5l_update_step)||(T5L::pre_send_end_all == t5l.t5l_update_step))
{
if(T5L::pre_send_end == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::pre_send_end;
t5l.t5l_update_step = T5L::send_end;
}
else if(T5L::pre_send_end_all == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::pre_send_end_all;
t5l.t5l_update_step = T5L::send_end_all;
}
t5l.real_count = t5l.confire_handle(t5l.net_date);
t5l.t5l_net_step = T5L::net_init;
}
else if((T5L::send_end == t5l.t5l_update_step)||(T5L::send_end_all == t5l.t5l_update_step))//写入flas指令
{
t5l.real_count = t5l.save_handle(t5l.net_date,t5l.t5l_flash_addr);
//清除相关变量
t5l.t5l_ram_addr = T5L_Ram_Start;
if(T5L::send_end == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::send_end ;
t5l.t5l_update_step = T5L::save_data;//进入保存状态
}
else if(T5L::send_end_all == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::send_end_all;
t5l.t5l_update_step = T5L::send_stop;//stop
}
t5l.t5l_net_step = T5L::net_init;//网络层处理
}
else if((T5L::send_stop == t5l.t5l_update_step)||(T5L::save_data == t5l.t5l_update_step))
{
t5l.real_count = t5l.confire_handle(t5l.net_date);
t5l.t5l_net_step = T5L::net_init;//网络层处理
if(T5L::send_stop == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::send_stop;
t5l.t5l_update_step = T5L::reset_t5l;
}
else if(T5L::save_data == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::save_data;
t5l.t5l_update_step = T5L::send_start;
}
}
else if(T5L::reset_t5l == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::reset_t5l;
t5l.real_count = t5l.power_handle(t5l.net_date);
t5l.t5l_update_step = T5L::reset_t5l_end;
t5l.t5l_net_step = T5L::net_init;//网络层处理
}
else if(T5L::reset_t5l_end == t5l.t5l_update_step)
{
t5l.t5l_update_step_now = T5L::reset_t5l_end;
t5l.t5l_update_step = T5L::stop_timer;
}
}
printf("当前数据层%d\n",t5l.t5l_update_step_now);
//网络层,已经初步验证正常
if(T5L::net_init == t5l.t5l_net_step)
{
t5l.t5l_net_sub = 0;//变量初始化
t5l.t5l_net_num = t5l.real_count;
t5l.t5l_net_step = T5L::net_start;
}
if(T5L::net_start == t5l.t5l_net_step)
{
unsigned char stop = 1;
//ShowInfo((CString)" 发送开始:",0);
::GetLocalTime(&sysTime);
char str_2[40];
sprintf(str_2,"发送:%d:%d:%d:%3d",sysTime.wHour,sysTime.wMinute,sysTime.wSecond,sysTime.wMilliseconds);
ShowInfo((CString)str_2,0);
#if 0
e_editSend = "";//清空数据
e_editSend += ;
#endif
t5l.net_date[t5l.real_count] = 0;//加入结束符号
CByteArray HexDataBuf;
HexDataBuf.RemoveAll(); //清空数组
HexDataBuf.SetSize(t5l.real_count); //设置数组大小为帧长度
for(i = 0;i< t5l.real_count;i++)
{
HexDataBuf.SetAt(i,t5l.net_date[i]);
}
#if !hl_test
e_mscomm1.put_Output(COleVariant(HexDataBuf));//发送函数
#endif
while(stop)
{
#if 0
memcpy(frameinfo.Data,t5l.net_date+t5l.t5l_net_sub,8);
t5l.t5l_net_sub += 8;
if(t5l.t5l_net_sub >= t5l.t5l_net_num)//代表已经发送完成
{
t5l.t5l_net_step = T5L::net_end;
frameinfo.DataLen = t5l.t5l_net_num - (t5l.t5l_net_sub-8);
stop = 0;
}
else
{
frameinfo.DataLen = 8;
}
#endif
memcpy(frameinfo.Data,t5l.net_date+t5l.t5l_net_sub,dis_length);
t5l.t5l_net_sub += dis_length;
ceshi = t5l.t5l_net_sub;
if(t5l.t5l_net_sub >= t5l.t5l_net_num)//代表已经发送完成
{
t5l.t5l_net_step = T5L::net_end;
frameinfo.DataLen = t5l.t5l_net_num - (t5l.t5l_net_sub-dis_length);
ceshi = frameinfo.DataLen;
stop = 0;
}
else
{
frameinfo.DataLen = dis_length;
}
//----------------显示函数---------------------
unsigned char buffer_1[100];//显示最终字符
{
change::num_sring(buffer_1,&frameinfo.Data[0],frameinfo.DataLen);
ShowInfo((CString)buffer_1,0);
}
}
//ShowInfo((CString)"发送结束:",0);
#if 0
memcpy(frameinfo.Data,t5l.net_date+t5l.t5l_net_sub,8);
t5l.t5l_net_sub += 8;
if(t5l.t5l_net_sub >= t5l.t5l_net_num)//代表已经发送完成
{
t5l.t5l_net_step = T5L::net_end;
frameinfo.DataLen = t5l.t5l_net_num - (t5l.t5l_net_sub-8);
}
else
{
frameinfo.DataLen = 8;
}
//----------------发送+显示函数---------------------
unsigned char buffer_1[30];//显示最终字符
#if hl_test
if(1) //测试为发送成功
#else
if(Transmit(m_devtype,0,0,&frameinfo,1)==1)
#endif
{
change::num_sring(buffer_1,&frameinfo.Data[0],frameinfo.DataLen);
ShowInfo(buffer_1,0);
}
else
{
change::num_sring(buffer_1,&frameinfo.Data[0],frameinfo.DataLen);
ShowInfo(buffer_1,0);
ShowInfo("写入失败",2);
}
#endif
//-------------------------------------
}
else if(T5L::net_end == t5l.t5l_net_step)
{
#if hl_test
T5L::respon_valid = 1;
T5L::respon = 1;
#endif
if((T5L::respon_valid))//等待应答
{
T5L::respon_valid = 0;
if(T5L::respon)
{
t5l.t5l_net_step = T5L::net_default;//释放网络层,交给数据层
ShowInfo((CString)"一包ram写入完成",0);
t5l.respon_no_count = 0;
SetTimer(timer1,0,NULL);//应答成功,从数据层找数据
}
else //重返回网络层重新发送
{
t5l.t5l_net_step = T5L::net_init;
ShowInfo((CString)"应答失败",0);
t5l.respon_no_count++;
SetTimer(timer1,0,NULL);//应答失败从新点击按钮发送一次指令
}
}
else //重返回网络层重新发送
{
//t5l.t5l_net_step = T5L::net_init;
//ShowInfo("应答失败",0);
}
}
#if hl_test
if(T5L::stop_timer == t5l.t5l_update_step)
{
KillTimer(timer1);
t5l.clear_reg();
}
else
{
t5l.respon_no_count = 0;
SetTimer(timer1,20,NULL);//10ms进去1次,开启定时器1
}
#endif
#if 0
//决定----延时用法,后期可能抛弃
if(T5L::net_start == t5l.t5l_net_step)
{
t5l.t5l_time = T5L::t5l_send_time;//
}
else if(T5L::net_end == t5l.t5l_net_step)
{
if(T5L::send_stop == t5l.t5l_update_step)//决定是否结束传送
{
t5l.t5l_time = T5L::t5l_stop_time;//
}
else if(T5L::save_data == t5l.t5l_update_step)
{
t5l.t5l_time = T5L::t5l_save_time;
}
else
{
t5l.t5l_time = T5L::t5l_send_time;//
}
}
//决定----延时用法,后期可能抛弃
#endif
#if 0
//----------------下次发送等待时间---------------------
if(T5L::t5l_stop_time == t5l.t5l_time)
{
KillTimer(timer1);
}
else if(T5L::t5l_save_time == t5l.t5l_time)//写入延时
{
SetTimer(timer1,100,NULL);//10ms进去1次,开启定时器
}
else if(T5L::t5l_send_time == t5l.t5l_time)
{
#if hl_test
SetTimer(timer1,1,NULL);//10ms进去1次,开启定时器
#else
SetTimer(timer1,5,NULL);//10ms进去1次,开启定时器
#endif
}
#endif
//仅供调试用
#if 0
if(T5L::net_default == t5l.t5l_net_step)//释放网络层导致写入写一次
{
ShowInfo("一包ram写入完成",0);
if((T5L::save_data == t5l.t5l_update_step)||(T5L::send_end_all == t5l.t5l_update_step))
{
ShowInfo("flash写入完成",0);
#if hl_test
KillTimer(timer1);
#endif
}
}
#endif
#if 0
if(0 == uds_duo_state)//一条多帧发送完成,写入
ShowInfo("一条多帧写入完成",2);
#endif
}
#if 0
char buffer_name[50];
change::int_to_char(buffer_name,ceshi++);
VALUE.SetWindowText((LPCTSTR)(buffer_name));
change::int_to_char(buffer_name,uds_send_info.length);
VALUE2.SetWindowText((LPCTSTR)(buffer_name));
change::int_to_char(buffer_name,ceshi);
VALUE3.SetWindowText((LPCTSTR)(buffer_name));
change::inttohex((unsigned char *)buffer_name,send_address);
VALUE4.SetWindowText((LPCTSTR)(buffer_name));
change::int_to_char(buffer_name,block_num);
VALUE5.SetWindowText((LPCTSTR)(buffer_name));
#endif
#if 0
if((addr >= handle_num))
{
addr = 0;
uds_duo_state = 0;//恢复原状
ShowInfo(_T("写入完成"),0);//在对话框中写入提示
KillTimer(timer1);
}
else
{
}
#endif
#if 0
CString jindu;
//显示进度条,暂时不处理
if(sum_date)
jindu.Format("%d",addr*100/sum_date);
else
jindu.Format("%d",0);
#endif
//GetDlgItem(IDC_EDIT1)->SetWindowText((jindu));//写数值
//GetDlgItem(IDC_STATIC)->SetTextColor(RGB(255, 0, 0));
}
在开发过程中,怀疑函数发送数据有错误,可以点击复制按钮,写list_box的内容写入txt文件,方便使用对比软件对比数据,要不眼睛都瞪瞎了
实现函数
void Cuart123Dlg::OnBnClickedButtonCopy()//复制list行的内容
{
// TODO: 在此添加控件通知处理程序代码
char state = 0;
CString str;
long length = list_box.GetCount();
long i = 0;
CWnd *h1;
CFile destFile ;//合并文件的写入句柄
char err;
//-------------
file_ope::file_creat(destFile,(CString)"刷写信息.txt",err);
for(i = 0;i<length;i++)
{
CString string1 ;
list_box.GetText(i,string1);
file_ope::file_add(destFile,string1,err);
}
file_ope::file_close(destFile,err);
//-------------
#if 1
file_ope::file_creat(destFile,(CString)"ram地址.txt",err);
file_ope::file_add(destFile,_T("ram地址"),err);
for(i = 0;i<length;i++)
{
CString string1 ;
CString string2 = _T("5A A5");
list_box.GetText(i,string1);
if(string1.Left(5) == string2)
{
if(string1.GetAt(12) >=_T('8'))
{
file_ope::file_add(destFile,string1.Mid(12,5),err);
}
}
}
file_ope::file_close(destFile,err);
#endif
h1 = GetDlgItem(IDC_BUTTON_COPY); //指向控件的caption
state = 1;
if(state)
{
str = _T("复制成功");
UpdateData(true);
h1->SetWindowText(str);
}
else
{
str = _T("复制");
UpdateData(true);
h1->SetWindowText(str);
}
}
在读取到当使用迪文屏写入到flash的指令时,发现一直失败,前前后后检查了数据好几回,没有发现问题,和迪文屏串口数据一样,加入发送和接收时间后,发现自己的函数比官方例程慢了许多,可能时因为,使用定时器来触发按钮的重发,导致时间边长,然后在写入flash指令时修改和时间相关的参数,完美解决问题