新唐MCU技术
直播中

jefljel

9年用户 1199经验值
擅长:20762
私信 关注
[问答]

如何在 Keil C51 中对 SPROM 进行编程?

如何在 Keil C51 中对 SPROM 进行编程?

回帖(1)

yqdedli

2025-8-27 17:57:18

在Keil C51中对SPROM(如串行EEPROM 93C46)编程,需通过GPIO模拟通信协议(如Microwire/SPI),并遵循器件时序。以下是详细步骤和代码示例:




1. 硬件连接


假设MCU(如AT89C51)与93C46连接如下:



  • CS  → P1.0  

  • SK  → P1.1  

  • DI  → P1.2  

  • DO  → P1.3  




2. 关键操作流程



  • 写使能:发送WREN命令(0x98)。

  • 写入数据:发送WRITE命令(0xA0 + 地址),后跟8位数据。

  • 读取数据:发送READ命令(0xC0 + 地址),读取8位数据。

  • 等待写入完成:轮询DO引脚状态。




3. Keil C51示例代码


#include 
#include   // 包含_nop_()延时函数

sbit CS  = P1^0;  // 片选
sbit SK  = P1^1;  // 时钟
sbit DI  = P1^2;  // 数据输入
sbit DO  = P1^3;  // 数据输出

// 函数声明
void SPROM_Init();
void SPROM_WriteEnable();
void SPROM_WriteByte(unsigned char addr, unsigned char dat);
unsigned char SPROM_ReadByte(unsigned char addr);
void SPROM_Delay();  // 短延时函数

// 初始化IO口
void SPROM_Init() {
    CS = 0;  // 初始时片选拉低
    SK = 0;  // 时钟初始低电平
    DI = 0;  // 数据线默认低
}

// 发送一个字节(MSB first)
void SPROM_SendByte(unsigned char dat) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        DI = (dat & 0x80) ? 1 : 0;  // 取最高位
        SK = 1;
        SPROM_Delay();
        SK = 0;                    // 下降沿发送数据
        SPROM_Delay();
        dat <<= 1;                 // 左移一位
    }
}

// 接收一个字节(MSB first)
unsigned char SPROM_ReceiveByte() {
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++) {
        SK = 1;
        SPROM_Delay();
        dat <<= 1;          // 左移接收新位
        dat |= DO;          // 读取数据位
        SK = 0;
        SPROM_Delay();
    }
    return dat;
}

// 写使能(发送WREN命令)
void SPROM_WriteEnable() {
    CS = 1;               // 片选有效
    SPROM_SendByte(0x98); // WREN命令
    CS = 0;               // 片选结束
    SPROM_Delay();
}

// 向指定地址写入数据
void SPROM_WriteByte(unsigned char addr, unsigned char dat) {
    SPROM_WriteEnable();   // 开启写使能

    CS = 1;                // 开始写入
    SPROM_SendByte(0xA0 | (addr & 0x0F)); // 地址(93C46地址为4位)
    SPROM_SendByte(dat);   // 数据
    CS = 0;                // 结束操作

    // 等待写入完成(DO变高)
    while (DO == 0);       // 轮询直到写入完成
}

// 从指定地址读取数据
unsigned char SPROM_ReadByte(unsigned char addr) {
    unsigned char dat;
    CS = 1;
    SPROM_SendByte(0xC0 | (addr & 0x0F)); // READ命令+地址
    dat = SPROM_ReceiveByte(); // 接收数据
    CS = 0;
    return dat;
}

// 短延时(根据CPU频率调整)
void SPROM_Delay() {
    _nop_(); _nop_(); _nop_(); _nop_();
}

// 主函数示例
void main() {
    SPROM_Init();             // 初始化SPROM接口
    SPROM_WriteByte(0x01, 0x55); // 向地址0x01写入0x55
    unsigned char val = SPROM_ReadByte(0x01); // 读取验证
    while(1); // 停止
}



4. 关键注意事项




  1. 时序严格性:  



    • 每个时钟沿(SK上升/下降)需严格满足器件时序要求(参考93C46手册)。延时函数SPROM_Delay()需根据MCU频率调整(如12MHz时约1μs)。




  2. 写保护机制:  



    • 写操作前必须发送WREN命令,否则写入无效。

    • 写入后需轮询DO引脚,等待内部写周期完成(约2ms)。




  3. 地址对齐:  



    • 93C46的地址为4位(0x00~0x0F),超过会导致错误。




  4. 封装复用:  



    • 读写函数可封装为库,方便调用(如eeprom.c/h)。






5. 调试建议



  • 逻辑分析仪:监控CS、SK、DI、DO信号,验证时序是否符合手册。

  • 写入验证:写入后立即读取检查,确保数据正确。

  • 电源稳定性:EEPROM写入时确保VCC无毛刺。




6. 扩展功能



  • 多字节读写:实现连续读写函数(如WriteArray())。

  • 擦除操作:添加ERASE(0xC0)和ERAL(全擦)命令支持。


通过以上步骤,即可在Keil C51中高效编程SPROM器件。务必以具体器件手册为准调整时序!

举报

更多回帖

发帖
×
20
完善资料,
赚取积分