读取W25Q64数据并显示在OLED

读取W25Q64数据并显示在OLED

一、数据准备

1.PS处理图片

  • 裁剪
    将图片裁剪为128*64
  • 处理为单色
    ①图像->模式->灰度
    ②图像->模式->位图
  • 批处理
    ①窗口->动作
    ②文件->自动->批处理

2.python处理

  • 引用的库
import os
import cv2 as cv
import numpy as np
import struct
import binascii
from PIL import Image
  • 处理单张图片
#单色BMP图片转换为SSD1306 OLED可用的头文件
#BMP必须为126宽、64高的单色图片,8位灰度图可通过PS处理后形成单色BMP
def BMP_2_OLED_HEAD(pic_name,pic_type):#图片的名称  类型(BMP)
    print('开始转换图片:',pic_name+ '.' + pic_type)
    py_dir = os.getcwd()#获取PYTHON当前位置
    file_handle = open(py_dir + '/OLED/BMP12864/'+'ImgData.txt', 'a') #a为追加写入、w为清空后写入
    file_handle.write('static unsigned char ' + pic_type + pic_name + '[] =\n{\n')

    img_screen = Image.open(py_dir + '/OLED/BMP12864/' + pic_name + '.' + pic_type)
    img_screen = np.array(img_screen)#img_scree具体格式为[64][128],其中[0][0]代表第一行第一列,[63][127]第64行128列

    #重组数据需要将[7][0]、[6][0]、[5][0]......[1][0]、[0][0]共8个0/1合并为一个字节
    str_bin_8bit = ''  # 建立空白字符串
    for page in range(0,8):#页
        for lie in range(0, 128):#列
            for hang in range(7, -1,-1):#行
                str_bin_8bit = str_bin_8bit + str(img_screen[page*8+hang][lie])
            mumber = int(str_bin_8bit, 2)  # 01字符串转为10进制数字
            str_hex = '0x' + hex(mumber)[2:].zfill(2).replace("0x", "") + ','
            str_bin_8bit = ''
            file_handle.write(str_hex)
            if (lie+1)%16==0:
                file_handle.write('\n')
    file_handle.write('};\n')
    file_handle.close()
    print(pic_name + '.' + pic_type,'转换结束!')
  • 自动处理图片
def BMP_2_OLED_HEAD_AUTO():
    picture_type = 'bmp'
    picture_num = 16
    for namex in range(0, picture_num):
        if len(str(namex)) == 1:
            strName = '0' + str(namex)
        if len(str(namex)) == 2:
            strName = str(namex)
        BMP_2_OLED_HEAD(strName,picture_type)#JPG_2_OLED_Bin,JPG_2_OLED_Head

二、W25Q64操作

1.初始化

  • 并不需要初始化,只需通过判断ID是否正确,确保W25Q64工作正常
	uint16_t jidcode = 0;
    uint32_t midcode = 0;
    jidcode = W25Q_ReadJID16();
    midcode = W25Q_ReadMID32();
    user_info("W25Q64 JID=%x\tMID=%x", jidcode, midcode);
    HAL_Delay(2000);
uint8_t read_buf[1024] = {0};//1次读1k
W25QXX_Read(read_buf, 0, W25Q64_ONETIME_WR);


/**
 * @brief   读取SPI FLASH数据
 * @param   buffer      —— 数据存储区
 * @param   start_addr  —— 开始读取的地址(最大32bit)
 * @param   nbytes      —— 要读取的字节数(最大65535)
 * @retval  成功返回0,失败返回-1
 */
int W25QXX_Read(uint8_t *buffer, uint32_t start_addr, uint16_t nbytes)
{
    uint8_t cmd = READ_DATA_CMD_0x03;
    start_addr = start_addr << 8;
    W25QXX_Wait_Busy();
    /* 使能片选 */
    W25Q_CS_0;
    SPI_Transmit(&cmd, 1);
    if (HAL_OK == SPI_Transmit((uint8_t *)&start_addr, 3))
    {
        if (HAL_OK == SPI_Receive(buffer, nbytes))
        {
            W25Q_CS_1;
            return 0;
        }
    }
    W25Q_CS_1;
    return -1;
}


uint8_t write_buf[W25Q64_ONETIME_WR] = {0};
W25QXX_Page_Program(write_buf, 0, W25Q64_ONETIME_WR);
/**
 * @brief    页写入操作
 * @param    dat —— 要写入的数据缓冲区首地址
 * @param    WriteAddr —— 要写入的地址
 * @param   byte_to_write —— 要写入的字节数(0-256)
 * @retval    none
 */
void W25QXX_Page_Program(uint8_t *dat, uint32_t WriteAddr, uint16_t nbytes)
{
    uint8_t cmd = PAGE_PROGRAM_CMD_0x02;
    WriteAddr <<= 8;
    W25QXX_Write_Enable();
    /* 使能片选 */
    W25Q_CS_0;
    SPI_Transmit(&cmd, 1);
    SPI_Transmit((uint8_t *)&WriteAddr, 3);
    SPI_Transmit(dat, nbytes);
    W25Q_CS_1;
    W25QXX_Wait_Busy();
}
  • 擦除扇区(4k)
//页0.25kb											1page			256byte			
//扇区4kb						1sector			16page		4096byte		
//块64kb		1bock		16sector		256page		65536byte		
//W25Q64  8mb=8192kb		128block		2048sector
void W25QXX_Erase_Sector(uint32_t sector_addr)
{
    uint8_t cmd = SECTOR_ERASE_CMD_0x20;
    sector_addr *= 4096;    //每个块有16个扇区,每个扇区的大小是4KB,需要换算为实际地址
    sector_addr <<= 8;
    W25QXX_Write_Enable();  //擦除操作即写入0xFF,需要开启写使能
    W25QXX_Wait_Busy();        //等待写使能完成
    /* 使能片选 */
    W25Q_CS_0;
    SPI_Transmit(&cmd, 1);
    SPI_Transmit((uint8_t *)&sector_addr, 3);
    W25Q_CS_1;
    W25QXX_Wait_Busy();       //等待扇区擦除完成
}
  • 接口函数
//向W25Q64写入(1K)1024字节=4*256,能让OLED显示一次的数据
//sector_addr代表扇区地址
//page_addr代表页地址,一般为0,4,8,12
//
//1页0.25k		1扇区4k
//							00页	01页	02页	03页	04页	05页	06页	07页	08页	09页	10页	11页	12页	13页	14页	15页
//扇区sector0		BMP1										BMP2										BMP3										BMP4
//扇区sector1		BMP5										BMP6										BMP7										BMP8
void Write_1024Byte_To_W25Q64(uint8_t *bmpdata, uint16_t sector_addr, uint8_t page_addr)

//sector_addr代表扇区地址
//page_addr代表页地址,一般为0,4,8,12
void Read_1024Byte_From_W25Q64(uint8_t *bmpdata, uint16_t sector_addr, uint8_t page_addr)

三、OLED显示

  • 将数据写入W25Q64
    W25QXX_Erase_Sector(0);
    Write_1024Byte_To_W25Q64(bmp00,0,0);
    Write_1024Byte_To_W25Q64(bmp01,0,4);
    Write_1024Byte_To_W25Q64(bmp02,0,8);
    Write_1024Byte_To_W25Q64(bmp03,0,12);
  • 读取并显示
for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 13; j = j + 4)
        {
            Read_1024Byte_From_W25Q64(read_buf, i, j);
            OLED_ShowBmp_12864(read_buf);
            OLED_Refreash();
            HAL_Delay(1000);
        }
    }
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值