这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 【STCAi8051U】QSPI模式读写W25Q128

共1条 1/1 1 跳转至

【STCAi8051U】QSPI模式读写W25Q128

专家
2025-10-29 14:49:35     打赏

匆匆忙忙拼凑了一个使用QSPI方式读写W25Q128的例程,依旧使用擎天柱开发板。测试中有单线模式、双线模式、四线模式的处理。

接线方式:

图片1.png

程序代码如下:


//// 测试工作频率为 40MHz
//// 测试使用Timer2作为串口1的波特率发生器,波特率=115200
//// 串口1:P3.6(RXD),P3.7(TXD)
#include "AI8051U.h"
#include <stdio.h>
#include <intrins.h>
#include "qspi.h"
#include "w25q128.h"
//#define FOSC 22118400L // 下载程序时,使用改频率烧录
//#define BRT (65536 - (FOSC / 115200+2) / 4)   //加 2 操作是为了让 Keil 编译器,自动实现四舍五入运算
sbit LED = P1^0;
#define FOSC                40000000UL
#define BAUD                (65536 - FOSC/4/115200)
#define SIZE                30
/*****************************************************************************/
#define INIT_BUF()      for (i=0; i<SIZE; i++) buf[i] = 0;
#define SET_BUF()       for (i=0; i<SIZE; i++) buf[i] = (BYTE)(i + 0x00);
#define PRINT_BUF()     for (i=0; i<SIZE; i++)                              \
                        {                                                   \
                            printf("%02bx ", buf[i]);                       \
                            if ((i % 32) == 31)                             \
                                printf("\n                            ");   \
                        }                                                   \
                        printf("\n");
/*****************************************************************************/
BYTE xdata buf[1024];
/*****************************************************************************/
void delay(int n) {
    int i;
    while (n--)
    for (i = 0; i < 1000; i++) {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}
// 初始化定时器2
void Timer2Init(void) {
    T2L = BAUD;
    T2H = BAUD >> 8;
    S1BRT = 1;  // S1BRT:串口 1 波特率发生器选择位, 0:选择定时器 1 作为波特率发生器, 1:选择定时器 2 作为波特率发生器(默认值)
    T2x12 = 1;
    T2R = 1;    
}
// 串口1
//------------------------------begin---------------------------------
// 串口处理用变量
bit busy1;
char wptr1;
char rptr1;
char buffer1[64];
// 串口1的中断处理
void Uart1Isr() interrupt 4 {
    if (TI) {
        TI = 0;
        busy1 = 0;
    }
    if (RI) {
        RI = 0;
        buffer1[wptr1++] = SBUF;
        wptr1 &= 0x0f;
    }
}
// 初始化串口1
void Uart1Init() {
    SCON = 0x50;  //
    wptr1 = 0x00;
    rptr1 = 0x00;
    busy1 = 0;
    
    P_SW1 |= 0x40;   // 选择P3.6,P3.7,因为擎天柱开发板上不提供P3.0,P3.1引脚
    ES = 1;
}
// 向串口1输出一个字符
void Uart1Send(char dat) {
    while (busy1);
    busy1 = 1;
    SBUF = dat;
}
char putchar(char c) {
    Uart1Send(c);
    return c;
}
//------------------------------end---------------------------------
// 延时
void delay_ms(int ms) {
    int i;
    do {
        i = FOSC/6000;
        while(--i);
    } while(--ms);
}
void sys_inti(void) {
    WTST = 0;  //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
    EAXFR = 1; //扩展寄存器(XFR)访问使能
    CKCON = 0; //提高访问XRAM速度
    
    P0M0 = 0x00; P0M1 = 0x00;
    P1M0 = 0x00; P1M1 = 0x00;
    P2M0 = 0x00; P2M1 = 0x00;
    P3M0 = 0x00; P3M1 = 0x00;
    P4M0 = 0x00; P4M1 = 0x00;
    P5M0 = 0x00; P5M1 = 0x00;
    P4M0 |= 0x09;               //设置CS/P4.0,SCK/P4.3为强推挽模式
    P4M1 &= ~0x09;
    P4SR &= ~0x0f;              //设置所有的QSPI口为快速模式
    P5SR &= ~0x0c;
    P4PU |= 0x0f;               //使能所有的QSPI口的内部10K上拉电阻
    P5PU |= 0x0c;
    P4BP &= ~0x06;              //使能QSPI的IO0~IO3数据硬件自动设置端口模式
    P5BP &= ~0x0c;
}
void main() {
    unsigned char state = 0;
    unsigned long addr = 0;
    unsigned char buff[24]={0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,};
    int i;
    int j;
    unsigned char d1, d2;
    
    // 初始化单片机
    sys_inti();
    
    // 打开调试信号
    LED = 1;
    
    // 初始化定时2,串口波特率发生器
    Timer2Init();
    
    // 初始化串口1
    Uart1Init();
    
    
    // 初始化SPI外设
    QSPI_Init();
    
    // 开总中断
    EA = 1;
    
    printf("QSPI Test !\n");
    printf("W25Q_ReadJEDECID_9F         %08lx\n", W25Q_ReadJEDECID_9F());
    printf("SR1: %02bx\n", W25Q_ReadSR1_05());
    printf("SR2: %02bx\n", W25Q_ReadSR2_35());
    printf("SR3: %02bx\n", W25Q_ReadSR3_15());
    
    // 启动测试信号
    LED = 0;
    
    if ((W25Q_ReadSR2_35() & 0x02) == 0) {
        W25Q_WriteEnableVSR_50();
        
        //W25Q80写SR2方法不同
        if ((W25Q_ReadJEDECID_9F() & 0xffff) == 0x4014) {
            W25Q_WriteSR12_01(0x0002);
        } else  {
            W25Q_WriteSR2_31(0x02);
        }
        printf("SR2: %02bx\n", W25Q_ReadSR2_35());
    }
    
    printf("W25Q_Erase4K_20\n");
    W25Q_Erase4K_20(0);
    
    printf("W25Q_ReadData_03            ");
    INIT_BUF();
    W25Q_ReadData_03(0, buf, SIZE);
    PRINT_BUF();
    printf("W25Q_PageProgram_02\n");
    SET_BUF();
    W25Q_PageProgram_02(0, buf, SIZE);
    
    printf("W25Q_ReadData_03            ");
    INIT_BUF();
    W25Q_ReadData_03(0, buf, SIZE);
    PRINT_BUF();
    
    // 单线模式
    printf("W25Q_FastRead_0B            ");
    INIT_BUF();
    W25Q_FastRead_0B(0, buf, SIZE);
    PRINT_BUF();
    
    // 双线模式
    printf("W25Q_FastRead_3B            ");
    INIT_BUF();
    W25Q_FastRead_3B(0, buf, SIZE);
    PRINT_BUF();
    
    // 四线模式
    printf("W25Q_FastRead_6B            ");
    INIT_BUF();
    W25Q_FastRead_6B(0, buf, SIZE);
    PRINT_BUF();
    while (1);
}

W25Q128中地址0 开始的32个单元,预先通过编程器写入00~1F数据,测试结果:

图片2.png

工程文件(使用Keil5.28开发):串口_QSPI_W25Q128.zip




关键词: 菜鸟学单片机     Ai8051U     QSPI应用示例         

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]