[MM32硬件]【灵动微电子MM32F5330测评】3.通过USART和上位机通信,向SPI_FLASH写入接收的数据

前言
MM32F5330评估板上搭载有25q80是一个1M BYTE的flash,还有多个UART、USART、LPUART资源。所以可以实现串口和PC机通讯,然后将获得的信息写入FLASH。用框图示意如下: 



所有示例中printf重定向到UART1(PB6),所以UART1做DEBUG UART再好不过。USART1中用到了RX(PA10)。

PYTHON上位机

复制
import serial

import struct

import time

  

# 串口配置  

SERIAL_PORT = 'COM14'  # 或者 '/dev/ttyUSB0' 在Linux/Mac上  

BAUDRATE = 115200  

  

# 创建串口连接  

ser = serial.Serial(SERIAL_PORT, BAUDRATE, timeout=1)  

  

# 固定的4位字符  

fixed_header = bytes([0xAA, 0x55, 0xAA, 0x55])



fixed_tailer = bytes([0x0D, 0x0A])



#发送批次 

transmission_count=0

#发送长度

data_length=0







# 打开二进制文件  

with open('gb2312_80.bin', 'rb') as file:  

    # 读取并发送数据,直到文件结束  

    while True:  

        # 读取128字节(如果文件末尾不足128字节,则读取剩余部分)  

        data = file.read(128)

        data_length=len(data)

        # 如果没有数据可读(文件结束),则退出循环  

        if not data:  

            break  

          

        # 拼装message

        message = struct.pack('!4sHH128s2s', fixed_header, transmission_count, data_length, data,fixed_tailer)

          

        # 通过串口发送数据

        print(data)

        ser.write(message)  

        transmission_count+=1

        # 休眠0.1秒  

        time.sleep(0.1)  

  

# 关闭串口连接  

ser.close()  

file.close()

print("Data sending completed.")

PYTHON程序读取gb2312_80.bin文件,按照自定义报文格式发送给MCU。
1、报文格式
 



2、用了struct.pack进行打包
3、import serial,用serial负责串口


MCU端程序
0、接收数据结构体

复制
typedef struct

{

    uint8_t Buffer[138];        //4+2+2+128+2

    uint16_t Length;

    uint16_t CurrentCount;

    uint8_t CompleteFlag;

} USART_RxTx_TypeDef;


1、USART阻塞式接收上位机信息

复制
void USART_Polling_Sample(void)

{

    uint8_t Data = 0;

    uint16_t i = 0;

    uint8_t offset;

    uint8_t buff[128];

    memset(buff,0,128);



    //printf("\r\nTest %s", __FUNCTION__);



    USART_Configure(115200);



    while (1)

    {

        if (SET == USART_GetFlagStatus(USART1, USART_FLAG_RXNE))

        {

            Data = USART_ReceiveData(USART1);



            USART_RxStruct.Buffer[USART_RxStruct.CurrentCount++] = Data;



            if(USART_RxStruct.Buffer[USART_RxStruct.CurrentCount-2]=='\xd'&&  \

            USART_RxStruct.Buffer[USART_RxStruct.CurrentCount-1]=='\xa')

             {



                   if(strncmp((char*)USART_RxStruct.Buffer,"test",4)==0){

                     printf("received test\r\n");

                     SPI_Master_FLASH_Polling_Sample();

                   }

                   else if(strncmp((char*)USART_RxStruct.Buffer,"help",4)==0){

                     //向UART1输出

                     printf("help command list\r\n");

                      printf("1.abc\r\n");

                   }

                   else if(strncmp((char*)USART_RxStruct.Buffer,"\xAA\x55\xAA\x55",4)==0){

                      //输入为0xAA55AA55时,为写flash命令

                      processFlashCommand((uint8_t*)(USART_RxStruct.Buffer+4));                //传递第5个字节指针地址

                   }

                   else if(strncmp((char*)USART_RxStruct.Buffer,"read",4)==0){

                       offset=USART_RxStruct.Buffer[4]-48;        //ASCII->数字

                       memset(buff,0,128);

                                                                

                      SPI_FLASH_FastRead(offset*128,buff,128);

                      for(i=0;i<128;i++)

                      {

                           if (0 == (i % 8))

                          {

                                printf("\r\n");

                          }

                          printf("0x%02x ",buff[i]);

                       }

                     }

                     else{

                          //向UART1输出

                          printf("Not Command! you can send help\r\n");

                     }

                                                        

                          USART_RxStruct.CurrentCount=0;

                          USART_RxStruct_ClearBuffer();

                  }

          }



     }

}


接收的信息如果末尾是0x0D,0x0A(回车换行),判断是否带有命令字段:test、help、\xAA\x55\xAA\x55、read
如果头4个字符为0xAA,0x55,0xAA,0x55,即为PYTHON上位机发来的信息,跳转到processFlashCommand处理


2、processFlashCommand处理程序

复制
void processFlashCommand(uint8_t* rxData)

{

        uint16_t offset,length;

        uint16_t i=0;

        

        uint8_t *pBuff=rxData;

        offset=pBuff[0];

        offset=offset<<8;

        offset|=pBuff[1];

        

        length=pBuff[2];

        length=length<<8;

        length|=pBuff[3];



        //每次发送128个字节,发送32次为4k,1个扇区4k,需要先擦除扇区在写入

        if(offset%32==0) SPI_FLASH_SectorErase(offset/32);        

        //写flash

        SPI_FLASH_PageProgram(offset*128,pBuff+4,length);

        printf("write flash:offset:%d,length:%d\r\n",offset*128,length);



}



写flash用了SPI_FLASH_PageProgram函数,在SPI例程里有这个函数。
注意写之前一定要先对扇区做擦除操作,由于一个扇区是4k,而每次传过来的数据是128,所以每32次接收执行一次擦除扇区。


总结
1、还提供了接收串口"read"命令,格式是:
read0:可以显示flash中0-127地址的数据;
read1:可以显示flash中128-255地址的数据;
以此类推,用来查看写的数据是否正确。下面演示的是PC通过USART1发送read0,通过UART1接收read命令的返回结果,通过结果与原文件比对,可知写flash是否成功。
 


2、前面所做,相当于在FLASH中烧录了一个字库文件gb2312_80.bin,为以后用LCD显示汉字做好准备。:
---------------------
作者:sujingliang
链接:https://bbs.21ic.com/icview-3385598-1-1.html
来源:21ic.com
此文章已获得原创/原创奖标签,著作权归21ic所有,任何人未经允许禁止转载。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值