日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实验五 Flash在线编程实验

發布時間:2024/8/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实验五 Flash在线编程实验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一.實驗目的

(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,否則發送NOTFOUND
  • R:[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=123myconn.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();}//將數據庫存入flashprivate 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=123myconn.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 <= 7 + m; i++){SendByteArray[i] = writeDataArray[k* 56 + i - 8];}SendByteArray[len + 2] = (byte)'C'; ??????//幀尾//發送、接收、顯示sendRecv(SendByteArray, 2, 100);}catch{this.Txt_recv1.Text = "KL25 Flash第"+(k+1)+"次寫入操作失敗!";}}}this.textBox4.Text = n + "字節";?????????}//修改讀出程序private string sendRecvDB(byte[] SendByteArray, int cnt, int time){string result="";// string str="";byte[] recvData;int i;this.tb_statue.Text += "正在發送...";this.tb_statue.Refresh();recvData = pcNode1.PCNodeSendReturn(SendByteArray, cnt, time);if (recvData.Length <= 0){this.tb_statue.Text += "無數據返回";this.tb_statue.Refresh();}else{this.tb_statue.Text += "有數據返回";this.tb_statue.Refresh();this.Txt_recv1.Text = string.Empty;for (i = 0; i < recvData.Length; i++)this.Txt_recv1.Text += recvData[i].ToString("X2").ToUpper() + " ";this.tbhead.Text = "" + (char)recvData[0];//幀頭this.tblen.Text = "" + ((char)recvData[1] - 1);//長度-1(內容起始幀C)this.tbfirst.Text = "" + (char)recvData[2];//內容起始幀C//this.Txt_recv2.Text = "幀頭:" + (char)recvData[0] + " 接收長度:" + (recvData[1]-1) + " 接收起始字符幀:" + (char)recvData[2] + " 接收內容:";for (i = 3; i < recvData.Length - 1; i++){//可顯示字符予以顯示,不可顯示的ASCII碼顯示為空if (recvData[i] > 31 && recvData[i] < 127){this.Txt_recv2.Text += (char)recvData[i];}else{this.Txt_recv2.Text += " ";}}this.tbtail.Text = "" + (char)recvData[i];//幀尾result = System.Text.Encoding.Default.GetString (recvData);result = result.Substring(1, result.Length - 1);result = result.Substring(1, result.Length - 1);result = result.Substring(1, result.Length - 1);return result.Substring(0, result.Length - 2);// str = result;//return result;}return result;???????????}//查詢獲取flash中數據庫的數據private void button3_Click(object sender, EventArgs e){??????????// 1. 臨時變量聲明byte sector; ??????????// 扇區號int offset; ???????????// 偏移量byte count; ???????????// 讀取字節數StringBuilder sb = new StringBuilder();byte[] SendByteArray = new byte[9]; ????????// 定義發送緩沖區byte offset_high, offset_low; ??????????????// 定義偏移地址的高低字節// 2. 臨時變量賦值sector = Convert.ToByte(tbSector1.Text); ???// 將TextBox中的Text轉換為Byte類型offset = Convert.ToInt32(tbOffset1.Text); ?// 將TextBox中的Text轉換為Byte類型count = Convert.ToByte(tbCount1.Text);// 計算偏移地址高低位offset_low = (byte)(0xff & offset);offset_high = (byte)((0xff00 & offset) >> 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版)

    總結

    以上是生活随笔為你收集整理的实验五 Flash在线编程实验的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。