OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4282|回复: 0

从串口发.BIN文件数据,写入SPI 做个记录

[复制链接]

3

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2018-7-27
在线时间
19 小时
发表于 2021-2-3 16:01:06 | 显示全部楼层 |阅读模式
本帖最后由 hezhenghedao 于 2021-2-3 16:46 编辑

最近想整个串口发BIN文件到SPI 的 W25Q64上去,手上有个路由器的芯片W25Q128的,就改一下ID就行,读写都一样,想当个烧录器,从电脑写BIN文件到SPI,自带的测试程序没有问题,写入也没有问题,后来又买了烧录器到了,读取数据对比了一下,写入的没有问题。 有需要的可以研究一下。

先运行开发板指南者103等串口发BIN文件数据下来,然后运行上位机,sProt2 的控件,点打开串口(串口号要按自己的改),点发送数据(文件路径要自己改一下),就等写入完成,有提示写入状态,每次写入256个字节,一次一次分开发。

上位机软件 C# VS2010 打开串口,发送数据,显示,有用,其它的功能没用
C:\Users\Administrator\AppData\Local\YNote\data\weixinobU7VjijR6WBMkz4FBm8B-epvwQU\31c62763ba79492ab339123cdc44f749\clipboard.png
        //打开串口
        private void button1_Click(object sender, EventArgs e)
        {
            //sPort2.PortName = "COM2";//串口的portname 要根据实际改
            if (!sPort2.IsOpen)
                  sPort2.Open();        
            MessageBox.Show("已打开");           
        }

        //发送数据
        private void button1_Click_1(object sender, EventArgs e)
        {
             //要下载的BIN文件放到D盘,改文件名为:test.bin,或者下面路径改为你的BIN文件就行。
            string filename = "d:\\test.bin";
            FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read);
            int imageSize = (int)fs.Length;
            //把BIN内容读取到字节数据中。
            Gbyte = new byte[imageSize];
            fs.Read(Gbyte, 0, imageSize);
            GimageSize = imageSize;
            byte[] Txbyte = new byte[270];
            //           S                P                I        文件头
            Txbyte[0] = 0x53; Txbyte[1] = 0x50; Txbyte[2] = 0x49;
            //                  高地址                               低地址    写入地址
            Txbyte[3] = (byte)((Gaddress >> 8) & 0xFF); Txbyte[4] = (byte)(Gaddress & 0xFF);
            //存发送数据
     for (int i = 0; i < 256; i++)            
            {
                Txbyte[i + 5] = Gbyte;
            }

            if (sPort2.IsOpen)
            {  //一次发256个字节到串口。
                sPort2.Write(Txbyte, 0, 261);
            }
            else
            {
                MessageBox.Show("串口还没有打开哦。");
            }


//100毫秒定时查询,如果开发板接收到并写入,且校准完成就会回个5个字节的数据,即回
// S  P  I   + 地址两位。上位机收到后说明写入256个字节完成,就开始下后面的,一次一次的传256,直到写入完成。  文本框会显示写入情况。
// 如果出错 开发板回err字符。

private void timer1_Tick_1(object sender, EventArgs e)
        {   int a = 0;
            if (sPort2.IsOpen)
             a =sPort2.BytesToRead;
            if (a > 0)
            {
                byte[] data;
                data = new byte[a];
                textBox2.Text = textBox2.Text + "\r\n";
                if (sPort2.Read(data, 0, a) > 0)
                {
                    if (data[0] == 0x53 && data[1] == 0x50 && data[2] == 0x49)
                    {
                        textBox2.Text = textBox2.Text + "写入" + data[3] + " " + data[4] +  " 地址:"+ Gaddress + " OK,\r\n"; 
                        byte[] Txbyte = new byte[270];
                        //           S                P                I
                        Txbyte[0] = 0x53; Txbyte[1] = 0x50; Txbyte[2] = 0x49;
                        Gaddress++;
                        //                  高地址                               低地址
                        Txbyte[3] = (byte)((Gaddress >> 8) & 0xFF); Txbyte[4] = (byte)(Gaddress & 0xFF);
                        int abc =0;
                        if ((Gaddress * 256) > (GimageSize - 256) )
                        {
                            for (int i = 0; i < GimageSize - (Gaddress * 256); i++)
                            {
                                Txbyte[i + 5] = Gbyte[Gaddress * 256 + i];
                                 abc =i;
                            }
                            abc++;
                            //后面的数据补写入0xff
                            for (int j = abc ; j < 256; j++)
                            {
                                Txbyte[j + 5] = 0xff;
                            }
                        }
                        else
                        {
                            for (int i = 0; i < 256; i++)
                            {
                                Txbyte[i + 5] = Gbyte[Gaddress * 256 + i];
                            }
                        }

                        if (sPort2.IsOpen)
                        {
                            sPort2.Write(Txbyte, 0, 261);
                            if ((Gaddress * 256) >= (GimageSize - 256))//写入完成就关定时器
                            {
                                timer1.Enabled = false;
                                MessageBox.Show("写入完成");
                            }
                        }
                        else
                        {
                            MessageBox.Show("串口还没有打开哦。");
                        }
                    }
                }              
            }



开发板程序
/* **************SPI Flash W25Q64 测试函数开始******************************/
void SPI1_Test()
{
  /* 获取 Flash Device ID */
        DeviceID = SPI_FLASH_ReadDeviceID();        
        U_Delay(10);        
        /* 获取 SPI Flash ID */
        FlashID = SPI_FLASH_ReadID();
        int16_t chandu=0;
        uint32_t Gaddress = 0;
        /* 检验 SPI Flash ID */
        if (FlashID == sFLASH_ID)
        {        
                //整片擦除  我是写入时擦除了,所以有点慢,
                //SPI_FLASH_BulkErase();
              //擦除完我没加提示,最好加个提示从串口发出,擦完,才打开上机机软件下载。
                //擦除第一块4K。
                //SPI_FLASH_SectorErase(0);        
                while(1)
    {
                        //处理串口程序  当大于0 即缓冲区有数据
                        chandu = U_Uart_Pro();
                        if( chandu > 0)
                        { //启始位是否为 S P I
                          if( U_Uart1_Rx_Buffer[0] == 0x53 && U_Uart1_Rx_Buffer[1] == 0x50 && U_Uart1_Rx_Buffer[2] == 0x49)
        { //数据格式 SPI 2 位地址 +256个字节内容,一次收261个数据
                                        if(chandu == 261)
                                        {
                                                //地址
                                                if(U_Uart1_Rx_Buffer[3] > 0)
                                                {
                                                 Gaddress =        (U_Uart1_Rx_Buffer[3] * 256) * 256 + U_Uart1_Rx_Buffer[4] * 256;
                                                }
                                                else
            {
                                                 Gaddress =        U_Uart1_Rx_Buffer[4] * 256;
                                                }        

                                                //4K 擦除一个扇区
                                                if(Gaddress % 4096 == 0)
                                                {
                                                        SPI_FLASH_SectorErase(Gaddress);
                                                }                        
                                                //printf("\r\n 检测到串行flash W25Q64 !\r\n");
                                                //HAL_UART_Transmit_IT(&huart1, OK, 2);U_Delay(1);               
                                                /* 擦除将要写入的 SPI FLASH 扇区,FLASH写入前要先擦除 */
                                                // 这里擦除4K,即一个扇区,擦除的最小单位是扇区
                                                //SPI_FLASH_SectorErase(Gaddress);//        FLASH_SectorToErase  
                                                /* 将发送缓冲区的数据写到flash中 */
                                                // 这里写一页,一页的大小为256个字节
                                                //把数据写入指定扇区
                                                SPI_FLASH_BufferWrite(&U_Uart1_Rx_Buffer[5], Gaddress, 256);        
                                                U_Delay(10);                                                
                                                /* 将刚刚写入的数据读出来放到接收缓冲区中 */
                                                SPI_FLASH_BufferRead(U_Uart1_Tx_Buffer, Gaddress, 256);                                                
                                                TransferStatus1 = Buffercmp(&U_Uart1_Rx_Buffer[5], U_Uart1_Tx_Buffer, 256);

                                                if( PASSED == TransferStatus1 )
                                                {
                                                        //8M串行flash(W25Q64)测试成功!;
                                                        //while(HAL_UART_GetState(&huart1)==HAL_UART_STATE_BUSY);        
//while(HAL_UART_Transmit_IT(&huart1, OK, 2)==HAL_BUSY);                                                        
                                                        U_Uart_Tx_IT(&huart1, U_Uart1_Rx_Buffer, 5);                                                        
                                                        U_Delay(10);                                                        
                                                }
                                                else
                                                {
                                                        //8M串行flash(W25Q64)测试失败!
                                                        //HAL_GPIO_WritePin(LEDB_GPIO_Port,LEDB_Pin, GPIO_PIN_RESET);
                                                        HAL_UART_Transmit_IT(&huart1, err, 3);U_Delay(10);
                                                }               
                                        }                                                                        
                                }                                       
                        }
                        U_Delay(5);
                }
        }// if (FlashID == sFLASH_ID)        
}
/* **************SPI Flash W25Qxxx 测试函数结束******************************/        


BINTOSPI 上位机.rar (64.08 KB, 下载次数: 1)
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-14 03:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表