在我们使用 STM32 或者 FPGA 采集数据的时候,需要将数据存储到SD卡中,因为数据是按照地址存储的,并且没有文件结构,所以不能直接用电脑的文件管理器读取,下面是一种读取数据的办法
0. 实验平台
正点原子STM32F407ZG探索者
1. Python生成写入的数据
# %%
# 定义生成文件的大小(字节数)
file_size = 512
# 递增数据的起始值
start_value = 1
# 打开文件并写入递增数据
with open('output.bin', 'wb') as file:
    # 递增循环直到达到文件大小
    for i in range(file_size):
        # 将递增数据写入文件(使用小端字节序)
        file.write(start_value.to_bytes(1, byteorder='little'))
        # 递增起始值
        start_value += 1
        # 如果起始值超过255,则回绕到0
        if start_value > 10:
            start_value = 0
 
运行完此代码后,将会在当前文件夹里面生成一个output.bin的二进制文件,我们可以使用16进制的文本阅读器打开查看里面的内容
 
2. STM32源码
注意:数据需要以0x66aa结尾,这里是自定义的,具体的结尾标志可以自己设定。完整代码可以查看本文章顶部的资源
2.1 接收串口中断函数
void USART_UX_IRQHandler(void)
{
    uint8_t rxdata;
#if SYS_SUPPORT_OS  /* 如果SYS_SUPPORT_OS为真,则需要支持OS. */
    OSIntEnter();
#endif
    if (USART_UX->SR & (1 << 5))                /* 接收到数据 */
    {
        rxdata = USART_UX->DR;
        if ((g_usart_rx_sta & 0x8000) == 0)     /* 接收未完成? */
        {
            if (g_usart_rx_sta & 0x4000)        /* 接收到了0x66? */
            {
                if (rxdata != 0xaa)             /* 接收到了0xaa? (必须先接收到到0x66,才检查0xaa) */
                {
                    g_usart_rx_sta &= ~0x4000;
                    g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = 0x66;   /* 存储数据到 g_usart_rx_buf */
                    g_usart_rx_sta++;
                    
                    if (rxdata == 0x66)
                    {
                        g_usart_rx_sta |= 0x4000;   /* 标记接收到了 0x66 */
                    }
                    else
                    {
                        g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = rxdata;   /* 存储数据到 g_usart_rx_buf */
                        g_usart_rx_sta++;
                        if (g_usart_rx_sta > (USART_REC_LEN - 1))g_usart_rx_sta = 0;/* 接收数据溢出, 重新开始接收 */
                    }
                }
                else
                {
                    g_usart_rx_sta |= 0x8000;   /* 收到了0x0a,标记接收完成了 */
                }
            }
            else      /* 还没收到0x0d */
            {
                if (rxdata == 0x66)
                {
                    g_usart_rx_sta |= 0x4000;   /* 标记接收到了 0x66 */
                }
                else
                {
                    g_usart_rx_buf[g_usart_rx_sta & 0X3FFF] = rxdata;   /* 存储数据到 g_usart_rx_buf */
                    g_usart_rx_sta++;
                    if (g_usart_rx_sta > (USART_REC_LEN - 1))g_usart_rx_sta = 0;/* 接收数据溢出, 重新开始接收 */
                }
            }
        }
    }
    #if SYS_SUPPORT_OS  /* 如果SYS_SUPPORT_OS为真,则需要支持OS. */
    OSIntExit();
#endif
}
 
2.2 主函数
int main(void)
{
    uint8_t key;
    uint16_t t = 0;
    sys_stm32_clock_init(336, 8, 2, 7);         /* 设置时钟,168Mhz */
    delay_init(168);                            /* 延时初始化 */
    usart_init(84, 115200);                     /* 串口初始化为115200 */
    led_init();                                 /* 初始化LED */
    key_init();                                 /* 初始化按键 */
    while (sd_init())    /* 检测不到SD卡 */
    {
    }
    /* 打印SD卡相关信息 */
    show_sdcard_info(); 
    
    uint8_t k=0;
    uint8_t i=0;
    state[i] = sd_write_disk(data,0,10);
    uint16_t len;
    len = 0;
    while (1)
    {
        key = key_scan(0);
        if (key == KEY0_PRES)       /* KEY0按下了 */
        {
            sd_test_read(0,1);  /* 从0扇区读取1*512字节的内容 */
        }
        
        if (g_usart_rx_sta & 0x8000)        /* 接收到了数据? */
        {
            len = g_usart_rx_sta & 0x3fff;  /* 得到此次接收到的数据长度 */
            for (t = 0; t < len; t++)
            {
                USART_UX->DR = g_usart_rx_buf[t];
                while ((USART_UX->SR & 0X40) == 0); /* 等待发送结束 */
            }
            state[0] = sd_write_disk(g_usart_rx_buf,0,1);
            if (state[0] == 0)
            {
                printf("\r\n%d\r\n",len);
                printf("Write over!\r\n");
            }
            printf("\r\n\r\n"); /* 插入换行 */
            g_usart_rx_sta = 0;
        }
    }
}
 
3. Python读取SD卡代码
使用读卡器将 SD 卡连接到电脑上,
 如果弹出磁盘已损坏之类的千万不要管!!!
 如果弹出磁盘已损坏之类的千万不要管!!!
 如果弹出磁盘已损坏之类的千万不要管!!!
 继续往下看!
import struct
disk = open(r"\\.\PhysicalDrive1","rb") # 打开磁盘0,PhysicalDrive不区分大小写
# 读取第一个扇区, 也就是磁盘主引导记录, 1扇区为512字节
data = disk.read(512)
data = struct.unpack(len(data)*'B',data)
print(data)
 
然后注意上方代码中的PhysicalDrive1这里的1对应电脑的硬盘序号,可以此电脑(右键)->管理->磁盘管理中看到,这里的序号就是 PhysicalDrive 后面要跟的数字,我的电脑显示是磁盘 1,所以写的是 1。
 
 
4. 验证结果
运行上面的程序即可得到结果,这里是没有解包的结果
 
这一段代码是解包的过程,详细的可以查看这一篇博客:Python Struct 库之 pack 和 unpack 详解
 取消注释下列代码后的结果
data = struct.unpack(len(data)*'B',data)
 




















