跨界程序员の一 中文GB2312字库下载

上位机  C#  

下位机 STM32F407

实现目标 将.bin文件下载到片外flash中

实现原理 上位机一次性将.bin读入buf  然后分包串口下载 等待下位机返回继续下一包

下位机部分代码

/*
************************************
*GB2312中文字库下载 下位机部分   
*描述  通过串口接收上位机发送的字库数据校验通过后写入外置flash
***********************************
*/

#include "fontsLoad.h"
#include "delay.h"
#include "w25qxx.h" 
#include "GUI.h"
#include "led.h"
#include "usart.h"
#include "USART6.h"
#include "EmWinHZFont.h"
#include "str.h"
#include "ExtRamConfig.h"
//字库存放起始地址 
#define FONT_INFO_ADDR 	1024*1024*12 
//#define  FONTS_BUF_SIZE   4096
//uint8_t  FontsRXBuf0[FONTS_BUF_SIZE];
//uint8_t  FontsRXBuf1[FONTS_BUF_SIZE];

static uint8_t  buf_select=0;
static uint8_t  err=0;

static uint32_t  buf0data_size=0;
static uint32_t  buf0Start=0;
static uint32_t  buf0p=0;
static uint32_t  buf0End=0;

static uint32_t  buf1data_size=0;
static uint32_t  buf1Start=0;
static uint32_t  buf1p=0;
static uint32_t  buf1End=0;
/*串口接收中断中调用*/
void FontsDataInBuf(uint8_t data)
{
	if(buf_select==0)
	{
		if(0==buf0Start)
		{
			if(data==0xfe)
			{
				buf0Start = 1;
				buf0p = 0;
				FontsRXBuf0[buf0p++] = data;
			}
		}
		else
		{
			if(buf0data_size==0)
			{
				buf0data_size = 1;
				FontsRXBuf0[buf0p++] = data;
			}
			else if(buf0data_size==1)
			{
				FontsRXBuf0[buf0p++] = data;
				buf0data_size = FontsRXBuf0[2]<<8| FontsRXBuf0[1];		
			}
			else
			{
				if(buf0p<buf0data_size)
				{
					FontsRXBuf0[buf0p++] = data;
				}
				if(buf0p>=buf0data_size)
				{
					buf0End = 1;
					buf_select = 1;
					if(err==0)
					{
						USART6_sendonebyte(0x55);
					}
					else
					{
						USART6_sendonebyte(0xAA);
					}
				}
				
			}
		}
	}
	else
	{
		if(0==buf1Start)
		{
			if(data==0xfe)
			{
				buf1Start = 1;
				buf1p = 0;
				FontsRXBuf1[buf1p++] = data;
			}
		}
		else
		{
			if(buf1data_size==0)
			{
				buf1data_size = 1;
				FontsRXBuf1[buf1p++] = data;
			}
			else if(buf1data_size==1)
			{
				FontsRXBuf1[buf1p++] = data;
				buf1data_size = FontsRXBuf1[2]<<8| FontsRXBuf1[1];;				
			}
			else
			{
				if(buf1p<buf1data_size)
				{
					FontsRXBuf1[buf1p++] = data;
				}
				if(buf1p>=buf1data_size)
				{
					buf1End = 1;
					buf_select = 0;
					if(err==0)
					{
						USART6_sendonebyte(0x55);
					}
					else
					{
						USART6_sendonebyte(0xaa);
					}
				}
				
			}
		}
	}	
}
/*擦除外部flash准备保存字库的区域*/
void ClearFontFlashRoom()
{
	u16 i,j;
	u8 percent=0;
	u32 FontSecSize=0;
	FontSecSize = (ftinfo.ugbksize+ftinfo.gbk12size+ftinfo.gbk16size+ftinfo.gbk24size)/4096+1;	
	for(i=0;i<FontSecSize;i++)	//先擦除字库区域,提高写入速度
	{

		W25QXX_Read(FontsRXBuf0,((FONT_INFO_ADDR/4096)+i)*4096,4096);
		for(j=0;j<4096;j++)
		{
			if(FontsRXBuf0[j]!=0XFF)break; 	  
		}
		if(j!=4096)W25QXX_Erase_Sector((FONT_INFO_ADDR/4096)+i);
		
		percent = 100*i/FontSecSize+1;
		GUI_DispDecAt(percent,10,40,3);
		
	}
}
u8 font_init(void)
{		
	u8 t=0;
	//W25QXX_Init();  
	while(t<10)
	{
		t++;
		W25QXX_Read((u8*)&ftinfo,FONT_INFO_ADDR,sizeof(ftinfo));
		if(ftinfo.fontok==0XAA)break;
		delay_ms(20);
	}
	if(ftinfo.fontok!=0XAA)return 1;
	return 0;		    
}
u32 flashaddr = 0;
u32 offx=0;
_font_info ftinfo;
uint8_t FontUpdata()
{
	u8  LoadEnd=0;
	u32 allbtyes=0;
	usart6_init(115200);
	Usart6CallBack  = FontsDataInBuf;
	
	GUI_SetFont(&GUI_Font20_ASCII);
	GUI_SetColor(GUI_WHITE);
	GUI_SetBkColor(GUI_BLUE);
	GUI_SetTextMode(GUI_TEXTMODE_NORMAL);
	GUI_Clear();
	ftinfo.ugbksize = 174344;
	ftinfo.gbk12size = 574560;
	ftinfo.gbk16size = 766080;
	ftinfo.gbk24size = 1723680;
	ftinfo.ugbkaddr=FONT_INFO_ADDR+sizeof(ftinfo);
	flashaddr = ftinfo.ugbkaddr;
	ftinfo.f12addr=ftinfo.ugbkaddr+ftinfo.ugbksize;	
	ftinfo.f16addr=ftinfo.f12addr+ftinfo.gbk12size;
	ftinfo.f24addr=ftinfo.f16addr+ftinfo.gbk16size;
	allbtyes = ftinfo.ugbksize+ftinfo.gbk12size+ftinfo.gbk16size +ftinfo.gbk24size;
	GUI_DispStringAt("%",50,40);
	GUI_DispStringAt("ClearFlash...",10,10);
	
	ClearFontFlashRoom();
	GUI_DispStringAt("Clear End ,Now You Can Start the Load APP!",10,70);
	GUI_DispStringAt("%",50,130);
	
	buf0data_size=0;
	buf0Start=0;
	buf0p=0;
	buf0End=0;
	
	buf1data_size=0;
	buf1Start=0;
	buf1p=0;
	buf1End=0;
	offx = 0;
	buf_select = 0;
	while(1)
	{
		delay_ms(10);
		if(LoadEnd==0&&err==0)
		{
			if(buf0End==1)
			{
				if(0==Crc16_Modbus(FontsRXBuf0,buf0data_size))//CRC16校验 modbus
				{
					switch(FontsRXBuf0[3])
					{
						case 0x01:
							W25QXX_Write(FontsRXBuf0+4,offx+flashaddr,buf0data_size-6);
							offx +=buf0data_size-6;
							buf0data_size=0;
							buf0Start=0;
							buf0p=0;
							buf0End=0;	
						break;
						
						case 0x02:
							LoadEnd = 1;
						break;
					}
						
					GUI_DispDecAt(100*offx/allbtyes,10,130,3);	
					
				}
				else
				{
					err = 1;				
				}			
			}
			if(buf1End==1)
			{
				if(0==Crc16_Modbus(FontsRXBuf1,buf1data_size))
				{
					switch(FontsRXBuf1[3])
					{
						case 0x01:
							W25QXX_Write(FontsRXBuf1+4,offx+flashaddr,buf1data_size-6);
							offx +=buf1data_size-6;
							buf1data_size=0;
							buf1Start=0;
							buf1p=0;
							buf1End=0;	
						break;
						
						case 0x02:
							LoadEnd = 1;
						break;
					}
					GUI_DispDecAt(100*offx/allbtyes,10,130,3);
				}
				else
				{
					err = 1;
				}		
			}
		}
		else
		{
				if(err==0)
				{
					ftinfo.fontok=0XAA;
					W25QXX_Write((u8*)&ftinfo,FONT_INFO_ADDR,sizeof(ftinfo));	//保存字库信息
					
					delay_ms(200);				
					GUI_SetBkColor(GUI_BLUE);
					GUI_Clear();
					GUI_SetColor(GUI_YELLOW);
					GUI_SetFont(&GUI_FontHZ12);
					GUI_DispStringAt("hello word",10,10);
					GUI_DispStringAt("落霞与孤鹜齐飞",10,22);
					GUI_DispStringAt("秋水共长天一色",10,34);	
					GUI_SetFont(&GUI_FontHZ16);
					GUI_DispStringAt("hello word",10,50);
					GUI_DispStringAt("中智胜安",10,66);
					GUI_DispStringAt("娃哈哈哈哈",10,82);
					GUI_SetFont(&GUI_FontHZ24);
					GUI_DispStringAt("hello word",10,106);
					GUI_DispStringAt("显示正常",10,130);
					GUI_DispStringAt("康熙字典",10,154);
					return 0;
				}
				else
				{
					GUI_DispStringAt("error!! please restart",10,150);
					while(1);
				}	
		}
	}
}

上位机部分

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;
using System.Text.RegularExpressions;
using System.Threading;

namespace FontDownload
{
    public partial class Form1 : Form
    {
        private string PortName = "";
        private int Baud = 9600;
        private bool portStatus = true;
        private byte[] SendBuffer = new byte[4096];
        private byte[] ReciveBuffer = new byte[1024];
        private int ReciveDataLen = 0;
        /*CRC校验*/
        public UInt32 crc16(byte[] data, int len)
        {
            UInt32 i = 0;
            UInt32 j = 0;
            UInt32 crc16 = 0xFFFF;
            for (i = 0; i < len; i++)
            {
                crc16 ^= data[i];//CRC = BYTE xor CRC
                for (j = 0; j < 8; j++)
                {
                    //如果CRC最后一位为1,右移一位后carry=1,则将CRC右移一位后,再与POLY16=0xA001进行xor预算
                    if ((crc16 & 0x01) == 1)
                    {
                        crc16 = (crc16 >> 1) ^ 0xA001;
                    }
                    else//如果CRC最后一位为0,则只将CRC右移一位
                    {
                        crc16 = crc16 >> 1;
                    }
                }
            }
            return crc16;
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void comboBox1_Click(object sender, EventArgs e)
        {
            comboBox1.Items.Clear();
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames());
        }
        /*串口号*/
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            PortName = comboBox1.Text;
        }
        /*波特率*/
        private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
        {
            Baud =  Convert.ToInt32( comboBox2.Text);
        }
        /*打开关闭串口*/
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (portStatus)
                {
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.Close();
                    }

                    serialPort1.BaudRate = Baud;
                    serialPort1.PortName = PortName;
                    serialPort1.StopBits = StopBits.One;
                    serialPort1.Parity = Parity.None;
                    serialPort1.DataBits = 8;
                    serialPort1.Open();
                    portStatus = false;
                    button2.Enabled = true;
                }
                else
                {
                    serialPort1.Close();
                    portStatus = true;
                }

                if (portStatus)
                {
                    button1.Text = "打开串口";
                    button1.ForeColor = Color.Black;
                }
                else
                {
                    button1.Text = "关闭串口";
                    button1.ForeColor = Color.Red;
                }
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }  
        }
        /*串口接收*/
        bool next = true;
        bool loadstatus = false;
        bool loadover = false;
        bool err = true;
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            byte[] _data = new byte[serialPort1.BytesToRead];
            serialPort1.Read(_data, 0, _data.Length);
            for (int i = 0; i < _data.Length; i++)
            {
                ReciveBuffer[i] = _data[i];
            }
            ReciveDataLen = _data.Length;
            if (_data[0] == 0x55)
            {
                next = true;
                err = true;
            }
            else
            {
                next = false;
                err = false;
            }
        }


        /****************************************************        
         * 
         * 
         * 
         * ***********************************************/
        private void Form1_Load(object sender, EventArgs e)
        {
        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (loadstatus)
            {
                if (offx > 1000)
                {
                    progressBar1.Value = (int)((long)toffset * 1000 / offx);
                    label4.Text = toffset.ToString();
                }
            }
            if (loadover == true)
            {
                loadover = false;
                button2.Text = "开始下载";
                button1.Enabled = true;
                comboBox1.Enabled = true;
                comboBox2.Enabled = true;
                label4.Text = "";
                loadstatus = false;
                label4.Text = "下载完成 观察显示结果";
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                if (loadstatus)
                {
                    loadstatus = false;

                    button2.Text = "开始下载";
                    button1.Enabled = true;
                    comboBox1.Enabled = true;
                    comboBox2.Enabled = true;
                    label4.Text = "";
                   
                }
                else
                {
                    loadstatus = true;
                    loadover = false;
                    button2.Text = "停止下载";
                    button1.Enabled = false;
                    comboBox1.Enabled = false;
                    comboBox2.Enabled = false;
                    label4.Text = "开始进行中...";
                    Thread t = new Thread(new ThreadStart(FontUrtLoad));
                    t.Start();
                    timer1.Enabled = true;
                }
            }
            else 
            {
                MessageBox.Show("串口未打开");
            }
        }

        private  byte[] bytes = new byte[3500000];
        private byte[] tbyte = new byte[2048];
        private int toffset = 0;
        private int offx = 0;
        private void FontUrtLoad()
        {
            int len = 0;      
            UInt32 crcvalue = 0;
            toffset = 0;
            offx = 0;
            FileStream stream0 = new FileStream("UN", FileMode.Open);
            if (null != stream0)
            {
                int size = Convert.ToInt32(stream0.Length);
                len = stream0.Read(bytes, offx, size);
                offx += len;
            }
            FileStream stream1 = new FileStream("12", FileMode.Open);
            if (null != stream1)
            {
                int size = Convert.ToInt32(stream1.Length);
                len = stream1.Read(bytes, offx, size);
                offx += len;
            }
            FileStream stream2 = new FileStream("16", FileMode.Open);
            if (null != stream2)
            {
                int size = Convert.ToInt32(stream2.Length);
                len = stream2.Read(bytes, offx, size);
                offx += len;
            }
            FileStream stream3 = new FileStream("24", FileMode.Open);
            if (null != stream3)
            {
                int size = Convert.ToInt32(stream3.Length);
                len = stream3.Read(bytes, offx, size);
                offx += len;
            }
            serialPort1.DiscardInBuffer();
            serialPort1.DiscardOutBuffer();
            
            while (toffset != offx)
            {
                if (toffset + 2042 < offx)
                {
                    tbyte[0] = 0xfe;
                    tbyte[1] = Convert.ToByte(2048 & 0xff);
                    tbyte[2] = Convert.ToByte(2048>>8);
                    tbyte[3] = 0x01;
                    for (int i = 0; i < 2042; i++)
                    {
                        tbyte[i+4] = bytes[toffset + i];
                    }
                    crcvalue = crc16(tbyte, 2046);
                    tbyte[2046] = Convert.ToByte(crcvalue & 0xff);
                    tbyte[2047] = Convert.ToByte(crcvalue>>8);
                    serialPort1.Write(tbyte, 0, 2048);
                    toffset += 2042;
                    next = false;
                    while (!next)
                    {
                        if (!loadstatus)
                        {
                            loadover = true;
                            stream0.Close();
                            stream1.Close();
                            stream2.Close();
                            stream3.Close();
                            return;
                        }
                        Thread.Sleep(10);
                    }
                }
                else
                {
                    int lse = offx - toffset;
                    tbyte[0] = 0xfe;
                    tbyte[1] =  Convert.ToByte((lse+6)&0xff);
                    tbyte[2] = Convert.ToByte((lse+6)>>8);
                    tbyte[3] = 0x01;
                    for (int i = 0; i < lse; i++)
                    {
                        tbyte[i+4] = bytes[toffset + i];
                    }
                    crcvalue = crc16(tbyte, lse + 4);
                    tbyte[lse+4] = Convert.ToByte(crcvalue & 0xff);
                    tbyte[lse+5] = Convert.ToByte(crcvalue>> 8);
                    serialPort1.Write(tbyte, 0, lse + 6);
                    next = false;
                    while (!next)
                    {
                        if (!loadstatus)
                        {
                            loadover = true;
                            stream0.Close();
                            stream1.Close();
                            stream2.Close();
                            stream3.Close();
                            return;
                        }
                        Thread.Sleep(10);
                    }
                    toffset = offx;
                    //结束消息
                    Thread.Sleep(100);
                    tbyte[0] = 0xfe;
                    tbyte[1] = 6;
                    tbyte[2] = 0;
                    tbyte[3] = 0x02;
                    crcvalue = crc16(tbyte,4);
                    tbyte[4] = Convert.ToByte(crcvalue & 0xff);
                    tbyte[5] = Convert.ToByte(crcvalue >> 8);
                    serialPort1.Write(tbyte, 0, 6);
                    while (!next)
                    {
                        if (!loadstatus)
                        {
                            loadover = true;
                            stream0.Close();
                            stream1.Close();
                            stream2.Close();
                            stream3.Close();
                            return;
                        }
                        Thread.Sleep(10);
                    }

                    loadover = true;
                }
            }
            stream0.Close();
            stream1.Close();
            stream2.Close();
            stream3.Close();
        }

       
    }
}
代码包https://download.csdn.net/download/suxingtian/10408699
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值