STM32USB虚拟COM刷新W25XXX数据

STM32USB虚拟COM刷新W25XXX数据

单片机需要显示多张图片,以及显示中文,但数据量太大,单片机内部的ROM不够,只能存在外部flash中,所以需要将大量的数据写入flash中。最近一直在查阅资料,怎么更新外部flash中的数据。

方法一:将数据存入ROM中,程序执行时,读取ROM中的数据,写入flash。这种方法一次性写入的数据比较少,若是下载一次程序,写入一次,再改动flash地址,再下载程序,再写入~~~~~说不下去了。

方法二:使用串口调试助手,将图片数据制作成bin文件,发送给单片机,单片机在串口中断中写入flash。当STM32的串口总线被其他设备占用时,这种方法就行不通了。

方法三:使用USB模拟串口,再如方法二的步骤刷新flash数据。

本次内容讲述的就是串口总线被其他设备占用,使用方法三刷新flash数据。我也会简单介绍一下怎么使用USB模拟串口回显数据。

W25XXX写入数据

flash内部只能由1变为0,所以每次写入数据时,需要先将flash擦除。

扇区擦除:每个扇区4K大小,擦除的最小单位。
块擦除:每个块64K大小。
片擦除:将整个flash擦除。

步骤如下

1.打开cube软件

2.配置USB
在这里插入图片描述

3.配置USB_DEVICE
在这里插入图片描述

4.时钟那些不作介绍,直接生成文件。

打开工程

1.打开usbs_cdc_if.c文件
在这里插入图片描述

2.在接收函数里加上发送数据函数,贴上代码

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
  /* USER CODE BEGIN 6 */
  USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
  USBD_CDC_ReceivePacket(&hUsbDeviceFS);
	

  USBD_CDC_SetTxBuffer(&hUsbDeviceFS, &Buf[0], *Len);   
  USBD_CDC_TransmitPacket(&hUsbDeviceFS);
  return (USBD_OK);
  /* USER CODE END 6 */
}

3.如果使用串口回显,就不需要更改其他的了,下载程序。打开串口调试助手发送数据,结果如下图
在这里插入图片描述
64字节以内,发送什么数据,返回的也是什么数据。因为USB一次性只能接收64字节数据,所以我发送70字节的数据,只返回了64字节。发送一大串数据,也会返回,只不过我没有仔细核对。

改动程序,可以返回大量数据

1.改动接收缓冲区大小

#define APP_RX_DATA_SIZE  256     //将1000改为256
#define APP_TX_DATA_SIZE  1000

2.修改CDC_Receive_FS函数

uint16_t Data_Len, temp, timeout;      //定义的全局变量

static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
	Data_Len +=*Len;
	if(Data_Len<APP_RX_DATA_SIZE)
	{
		USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + Data_Len);	   //设置下一次接收数据的位置
		USBD_CDC_ReceivePacket(&hUsbDeviceFS);                             //准备接收数据
	}
	else  //接收缓冲区已满
	{
		timeout = 0xffff;
		temp = !(Data_Len%64);  //判断长度是否为64整数倍
		while( CDC_Transmit_FS(UserRxBufferFS, Data_Len - temp) != USBD_OK && timeout--);
		 
		if(temp)  //当发送数据为64整数倍时,无法发送成功,故分成2次发送
		{
			 while( CDC_Transmit_FS(UserRxBufferFS + Data_Len -1, temp) != USBD_OK && timeout--);
		}
		

		//发送完毕,再次设置
		Data_Len = 0;
		USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + Data_Len);	   //设置下一次接收数据的位置
		USBD_CDC_ReceivePacket(&hUsbDeviceFS);                             //准备接收数据
	}
  return (USBD_OK);
  /* USER CODE END 6 */
}

当发送的数据为64的整数倍时,需要将数据分为两次发送(经其他博主验证)

3.下载程序,查看结果
在这里插入图片描述
设置的缓冲区大小为256,当缓冲区存满了数据,才会输出。

步入正题,使用USB虚拟串口刷新flash数据

1.每次上电,初始化时,就将flash整片擦除。

2.每满256字节时,就写入一次数据。

3.修改CDC_Receive_FS函数

uint32_t FlashAdd = 0x00000;
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
	//将已接收数据长度赋值给USB_S.ReLen
    USB_S.ReLen += *Len;
	//判断是否有结束标志以及接收数据长度是否达到UserRxBufferFS长度上限
		if( USB_S.ReLen<APP_RX_DATA_SIZE)
		{
		  //设置下一次接收数据的位置
	        USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS + USB_S.ReLen);
	        USBD_CDC_ReceivePacket(&hUsbDeviceFS);   //准备接收数据
		}
		else  //长度达到,或者检测到标志位,触发数据输出
		{
			  SPI_FLASH_PageWrite(UserRxBufferFS, FlashAdd, 256);		

				FlashAdd += 256;
				USB_S.ReLen = 0;

			 
				USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
				USBD_CDC_ReceivePacket(&hUsbDeviceFS);
		}
    return (USBD_OK);
}

4.打开Image2LCD制作bin文件
在这里插入图片描述

5.打开串口调试助手,写入数据
在这里插入图片描述
换了个串口调试助手,这个是正点原子的,这一个串口调试助手末尾会发0X0D,0X0A,如有需要可以以这两个数据写协议,或者自己写一个协议,并在程序中进行校验数据是否写入正确。

flash驱动文件在上一篇文章,也可以直接找野火的例程。

结尾

发送数据时,有时候开头的数据写不进flash,暂未找到原因。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值