实验五 Flash在线编程实验 您所在的位置:网站首页 flash广告设计实验结果及分析怎么写 实验五 Flash在线编程实验

实验五 Flash在线编程实验

2024-03-24 06:06| 来源: 网络整理| 查看: 265

一.实验目的

(1)掌握 Flash 存储器在线编程的基本概念。。

(2)熟悉 Flash 存储器的在线编程擦除和写入的步骤。

(3)进一步深入理解 MCU 和 C#串口通信的编程方法。

二.实验内容

1.验证性实验

1)验证样例程序(ch09-Flash)中(Flash),主要功能是实现通过串口输入命令 “?”可获得帮助; E:擦除第 50 扇区;R:从 50 扇区 0 字节开始的地址读取 30 字节长度字符串;A:从全局变量 watchGlobalVar 地址直接读取该变量;W:向 50 扇区 0 字节开始的地址写入 30 字节长度字符串;P:保护 50 扇区(实际保护 48,49,50,51 四个对齐扇区)。

实验步骤如下:

(1)将样例 Flash 程序下载至目标板;

(2)将“TTL-USB 串口线”的“USB 端口”接 PC 机的 USB 口,串口线的串口接开发板上的串口 2(3 根,RX 接蓝线,TX 接白线,GND 接黑线);

(3)打开串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”进行串口通信测试,观察实验现象。

(4)分析理解 main.c 程序和中断服务例程 isr.c。

2.设计性实验

(1)复制样例程序(ch09-Flash)中(Flash),利用该程序框架实现:通过串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”发送擦除、写入、读取命令及其参数,参数能够设置扇区号(0-127)、写入/读取扇区内部偏移地址(0~1020,要求为 0,4,8,12,......);写入/读取字节数目(4~1024,要求为 4,8,12,......)和数据。

请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句。

(2)复制样例程序(ch09-Flash)中(Flash),利用该程序框架实现:通过串口调试工具或 ch06-UART 文件夹中的“C#2010 串口测试程序”发送查询 Flash 相应扇区的数据串,(如:50 100 Hello,查找扇区 50 至扇区 100 中的字符串 Hello),如果找到发送 Found 给串口,如果未找到发送 Not Found 给串口。

请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句。

3.进阶实验★

(1)复制样例程序(ch09-Flash)中(Flash),利用该程序框架实现:通过 C#程序发送擦除、写入、读取命令及其参数,参数能够设置扇区号(0-127)、写入/读取扇区内部偏移地址(0~1020,要求为 0,4,8,12,......);写入/读取字节数目(4~1024,要求为 4,8,12,......)和数据。C#界面设计如如图 1 所示。

请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句和 C#方主要程序段。

图 1 C#界面设计

(2)复制样例程序(ch09-Flash)中(Flash),利用该程序框架实现:通过 C#程序访问数据库中的表,读取表中存放的数据列表并显示(表中字段如:学号,姓名,成绩),通过发送按钮将数据列表保存至 Flash 中;通过 C#程序界面输入读取的数据列表的条数,从 Flash中读取相应的数据后显示。

请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句和 C#方主要程序段。

(3)复制样例程序(ch09-Flash)中(Flash),利用该程序框架实现:通过 C#程序打开一副图片(比如自己的一寸电子照片),通过串口将图片数据发送至 MCU 并保存 Flash 中;通过 C#程序可以将 MCU 的 Flash 中保存的图片读取并显示。

请在实验报告中给出 MCU 端程序 main.c 和 isr.c 流程图及程序语句和 C#方主要程序段。

三.实验步骤和结果

1.验证性实验

组帧格式分析:

组帧:[0]P+[1]数据字节数n+数据+[n+2]C

数据部分:[2]握手或数据命令(C-握手/D-flash操作)+[3]flash操作类型(R:按逻辑地址读取;A:按物理地址读取;W:写入操作;E:擦除操作;P:保护操作;)+该操作类型的数据

R:[4]扇区号+[5]偏移量高字节+[6]偏移量低字节+[7]读取字节数

A:[4]地址高位+[5]地址第二高位+[6]地址第二低位+[7]地址低位+[8]读取字节数

W:[4]扇区号+[5]偏移量高字节+[6]偏移量低字节+[7]写入字节数m+写入数据

E:[4]扇区号

P:[4]保护区域号

2.设计性实验

(1)通过串口调试助手,向flash发送擦除、写入、读取命令及参数:

思路分析:

通过C#串口调试工具向串口发送擦除指令:50 03 44 45 32 43(擦除50号扇区),正确返回结果:4D 21 43 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 55。通过C#串口调试工具向串口发送写入指令:

50,0C,44,57,32,00,00,06,41,42,43,44,45,46,43(向50号扇区00偏移量写ABCDEF),正确返回结果:4D 07 43 41 42 43 44 45 46 55

      3.通过C#串口调试工具向串口发送读出指令:50 06 44 52 32 00 00 0A 43(从50号扇区00偏移量读ABCDEF),正确返回结果:4D 07 43 41 42 43 44 45 46 55 。

流程图:

串口流程图

 

Main函数流程图:

 

具体代码如下:

串口程序:

void UART2_IRQHandler(void) {     uint_8 i,flag;     DISABLE_INTERRUPTS;                //关总中断     //-----------------------------------------------------------------------     i=uart_re1(UART_2, &flag);             //接收一个字节     if (1 == flag)        {            uart_send1(UART_2, i);        }     //调用内部函数CreateFrame进行组帧     if(CreateFrame(i,g_uart_recvBuf)!=0)    //组帧成功     {         //g_uart_recvBuf[2]是命令字节         if(g_uart_recvBuf[2] == 'C')    //握手命令         {             g_uart_sentBuf[0]=(uint_8)'M';     //             g_uart_sentBuf[1]=5;               //             g_uart_sentBuf[2]  = (uint_8)'C';  //             g_uart_sentBuf[3]  = (uint_8)'K';  //"PCNode"             g_uart_sentBuf[4]  = (uint_8)'L';             g_uart_sentBuf[5]  = (uint_8)'2';             g_uart_sentBuf[6]  = (uint_8)'5';             g_uart_sentBuf[7]  = (uint_8)'U';  //             uart_sendN(UART_2,8,g_uart_sentBuf);             framestate=1;//握手命令帧         }         //         else   //其他情况,置“串口0接收完整数据帧事件位(EVENT_UART0_RE)”,触发task_uart0_re任务处理         {             framestate=0;//非握手命令帧         }     }     //-----------------------------------------------------------------------     ENABLE_INTERRUPTS;                //开总中断 }

(2)在flash查找存入数据,如果找到想串口发送FOUND,否则发送NOTFOUND

思路分析:

查询数据传的位置的本质,其实就是给组帧添加一种查找的格式。查找算法:先获取起始扇区,并将其值存到sect变量中,当其值小于结束扇区号时,初始化偏移量为0,偏移量从0开始增加到1024-count(待查询字节数),然后在循环中将字符串与查找到的字符串进行一一对比,如果相同则向串口发送FOUND,否则发送NOTFOUNDR:[4]查询起始扇区号+[5]查询结束扇区号+[6]查询字节数m+[7]~[(6+m)]查询字符串内容设计Q的数据格式:根据钱一个实验已经明确了原程序的组帧格式,我将帧格式的第4位,即[3]flash操作类型增加一种查询类型Q

流程图:

 

具体代码如下:

case 'Q': offset = 0; //偏移地址 uint_8 sect = g_uart_recvBuf[4]; uint_8 i = 0; count = g_uart_recvBuf[6];                    //存取字节数 uint_8 g_query[count]; uint_8 flag = 0; while (sect < g_uart_recvBuf[5]) { offset = 0; //偏移地址 for (offset; offset < 1024 - count; offset++) { flash_read_logic(&g_query[0], sect, offset, count); for (; i < count; i++) { if (g_query[i] == g_uart_recvBuf[i + 7]) { if (i >= count - 1) { g_uart_sentBuf[0] = (uint_8) 'M';   //帧头 g_uart_sentBuf[1] = 7; //内容数(内容count+C) g_uart_sentBuf[2] = (uint_8) 'C'; //内容起始帧 g_uart_sentBuf[3] = (uint_8) 'F'; g_uart_sentBuf[4] = (uint_8) 'O'; g_uart_sentBuf[5] = (uint_8) 'U'; g_uart_sentBuf[6] = (uint_8) 'N'; g_uart_sentBuf[7] = (uint_8) 'D'; g_uart_sentBuf[8] = (uint_8) 'U';   //帧尾 uart_sendN(UART_2, 9,&g_uart_sentBuf[0]); flag = 1; } } else { i = 0; break; } } if (flag) break; } if (flag) break; sect++; } if (!flag) { g_uart_sentBuf[0] = (uint_8) 'M';           //帧头 g_uart_sentBuf[1] = 9;  //内容数(内容count+C) g_uart_sentBuf[2] = (uint_8) 'C';        //内容起始帧 g_uart_sentBuf[3] = (uint_8) 'N'; g_uart_sentBuf[4] = (uint_8) 'O'; g_uart_sentBuf[5] = (uint_8) 'T'; g_uart_sentBuf[6] = (uint_8) 'F'; g_uart_sentBuf[7] = (uint_8) 'O'; g_uart_sentBuf[8] = (uint_8) 'U'; g_uart_sentBuf[9] = (uint_8) 'N'; g_uart_sentBuf[10] = (uint_8) 'D'; g_uart_sentBuf[11] = (uint_8) 'U';    //帧尾 uart_sendN(UART_2, 12, &g_uart_sentBuf[0]); } break;

3.进阶实验★

(1)通过C#程序实现对flash的存、取和擦除等功能

由于已有完整的C#程序,我便通过此程序实验了一些flash基本操作,并且仔细阅读同时理解了具体实现代码。

(2)通过C#程序访问数据库中的表,读取表中的存放的数据并显示通过发送按钮发送并保存到flash中,通过C#程序读取数据并显示。

由于此次实验过程并不是很顺利,将数据库中的数据以字符串的形式存入flash,取出之后,解析字符串没有成功,所以这里只写出分析思路和部分实现代码。

思路分析:

连接数据库之后,点击按钮,将数据库的数据获取之后,存到DataSet;将DataSet中的数据显示在dataGridView1上;点击存入按钮,获取数据,将DataSet数据转化为json格式的字符串,将该字符串分为若干份,分别发送至flash并存到flash相邻的扇区,并想C#程序返回字符串长度;在C#界面输入查询的起始扇区和字符串长度,点击查询按钮,从先前存放数据的几个扇区中取出json数据,并将json转换为DataSet数据,并显示到dataGridView2上。

主要代码:

C#端:

//读取数据库         private void button1_Click(object sender, EventArgs e)         {             // sql a = new sql();             //a.Select();             MySqlConnection myconn = null;             MySqlCommand mycom = null;            // MySqlDataAdapter myrec = null;             myconn = new MySqlConnection("server=localhost;user id=root;password=admin;database=armcortex");             // Host =localhost;Database=student;Username=lemon;Password=123             myconn.Open();             mycom = myconn.CreateCommand();             mycom.CommandText = "SELECT *FROM stuinfo";             MySqlDataAdapter adap = new MySqlDataAdapter(mycom);             DataSet ds = new DataSet();             adap.Fill(ds);             dataGridView1.DataSource = ds.Tables[0].DefaultView;                   myconn.Close();         }         //将数据库存入flash         private void button2_Click(object sender, EventArgs e)         {             // 1. 临时变量声明             byte sector;        //扇区号             int offset;         //偏移量             byte n;             //写入字节数             int i;             byte len;             //获取数据库数据             MySqlConnection myconn = null;             MySqlCommand mycom = null;             //MySqlDataAdapter myrec = null;             myconn = new MySqlConnection("server=localhost;user id=root;password=admin;database=armcortex");             // Host =localhost;Database=student;Username=lemon;Password=123             myconn.Open();             mycom = myconn.CreateCommand();             mycom.CommandText = "SELECT *FROM stuinfo";             MySqlDataAdapter adap = new MySqlDataAdapter(mycom);             DataSet ds = new DataSet();             adap.Fill(ds);             //dataGridView1.DataSource = ds.Tables[0].DefaultView;             byte[] writeDataArray = System.Text.Encoding.Default.GetBytes(DatasetToJson(ds)); //String转化为Byte[]             // 2. 临时变量赋值             sector = Convert.ToByte(tbSector2.Text);  // 将TextBox中的Text转换为Byte类型             offset = Convert.ToInt32(tbOffset2.Text);   // 将TextBox中的Text转换为Byte类型             n = (byte)writeDataArray.Length;             byte j = 0,k=0,l=0,m=0;             if (n > 56)             {                 if (n % 56 != 0)                 {                     l = (byte)(n % 56);                     j = (byte)(n / 56 + 1);                 }                 else                 {                     j = (byte)(n / 56);                     l = 56;                 }                 //n = (byte)(n + 6);                 for (; k < j; k++)                 {                     if (k == j - 1)                     {                         len = (byte)(l + 6);                         m = l;                     }                     else                     {                         len = (byte)(56 + 6);                         m = 56;                     }                                          byte[] SendByteArray = new byte[len + 3];                     this.Txt_recv1.Text = "";                     this.Txt_recv2.Text = "";                     this.Txt_recv1.Refresh();                     this.Txt_recv2.Refresh();                     this.tb_statue.Text = "运行状态:" + "单击“KL25 Flash 写测试”按钮...";                     this.tb_statue.Refresh();                     try                     {                         SendByteArray[0] = (byte)'P';      //帧头                         SendByteArray[1] = len;           //帧长                         SendByteArray[2] = (byte)'D';     //FLASH操作命令                         SendByteArray[3] = (byte)'W';      //FLASH写操作                         SendByteArray[4] = (byte)(sector+(byte)k);         //扇区号                        SendByteArray[5] = (byte)(offset / 256);    //偏移量高字节                         SendByteArray[6] = (byte)(offset % 256);    //偏移量低字节                         SendByteArray[7] = m;              //字节数                         for (i = 8; i > 8);             byte j = 0, k = 0, l = 0, m = 0;             if (count > 56)             {                 if (count % 56 != 0)                 {                     l = (byte)(count % 56);                     j = (byte)(count / 56 + 1);                 }                 else                 {                     j = (byte)(count / 56);                     l = 56;                 }                 //n = (byte)(n + 6);                 for (; k < j; k++)                 {                     if (k == j - 1)                     {                         m = l;                     }                     else                     {                         m = 56;                     }                     this.Txt_recv1.Text = "";                     this.Txt_recv2.Text = "";                     this.Txt_recv1.Refresh();                     this.Txt_recv2.Refresh();                     this.tb_statue.Text = "运行状态:" + "单击“KL25 Flash 按逻辑地址读测试”按钮...";                     this.tb_statue.Refresh();                     try                     {                         SendByteArray[0] = (byte)'P';     //帧头                         SendByteArray[1] = 0x06;          //帧长                         SendByteArray[2] = (byte)'D';     //FLASH操作命令                         SendByteArray[3] = (byte)'R';      //FLASH读操作                         SendByteArray[4] = (byte)(sector + (byte)k);         //第几页                         SendByteArray[5] = offset_high;    //偏移量高字节                         SendByteArray[6] = offset_low;     //偏移量低字节                         SendByteArray[7] = m;          //读取字节数                         SendByteArray[8] = (byte)'C';      //帧尾                         //发送、接收、显示                         //str += sendRecvDB(SendByteArray, 2, 100);                         sb.Append(sendRecvDB(SendByteArray, 2, 100));                     }                     catch                     {                         this.Txt_recv1.Text = "KL25 Flash第"+(k+1)+"读取操作失败!";                     }                 }                if (sb != null&& !sb.Equals(""))                 {                     DataSet ds = (DataSet)JsonToDataSet(sb.ToString());                     dataGridView2.DataSource = ds.Tables[0].DefaultView;                                    }else                 {                     this.Txt_recv1.Text = "KL25 Flash读取操作失败!";                 }                         }             else             {             }               } 四.实验总结(需加入心得体会)

通过本次实验,我掌握了flash在线编程的基本概念,熟悉了flash擦除、写入和读取的基本操作。但是在具体实验的过程中还是遇到许多难题,其中有一些解决了,但是还有一些没有得到完全解决。在后面的时间,我会继续寻找这些问题的解决方法,让自己获得更大的提升。

嵌入式技术基础与实践(第4版)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有