2. 数据存储器(RAM)的读写操作

任务说明

本案例面向8051内核单片机,目标是在内部数据存储器(IRAM)中完成一次写入与读取的完整操作,并通过端口输出结果以验证数据正确性。同时,通过断电重新上电后观察数据是否恢复,直观验证RAM的易失性特征。案例使用Keil C51环境,以STC89C52RC为典型目标芯片,代码可直接编译烧录。

硬件连接

使用P1端口连接8个LED(低电平点亮),用于显示RAM读取结果。晶振11.0592MHz,复位电路为标准上电复位。

STC89C52 8051内核 内部RAM 256B P1 330Ω ×8 GND P1.0~P1.7 LED0~LED7(低电平点亮) VCC 5V

代码实现

以下代码完成:向内部RAM的30H~37H单元写入一组测试数据,再依次读出并与期望值比较,比较结果通过P1口输出(一致时对应位点亮LED)。主循环中持续执行该过程,便于观察掉电现象。


#include <reg52.h>

// 测试数据表(8字节)
unsigned char code test_data[8] = {0xAA, 0x55, 0x0F, 0xF0, 0x3C, 0xC3, 0x66, 0x99};

// 延时函数(约10ms @ 11.0592MHz)
void delay_10ms(void)
{
    unsigned char i, j;
    for (i = 0; i < 20; i++)
        for (j = 0; j < 250; j++);
}

void main(void)
{
    unsigned char i;
    unsigned char read_val;
    unsigned char result;
    
    while (1)
    {
        // 1. 向内部RAM 30H~37H写入测试数据
        for (i = 0; i < 8; i++)
        {
            *(unsigned char data *)(0x30 + i) = test_data[i];
        }
        
        // 2. 从内部RAM读出并与期望值比较
        result = 0x00;  // 初始化为全部匹配
        for (i = 0; i < 8; i++)
        {
            read_val = *(unsigned char data *)(0x30 + i);
            if (read_val != test_data[i])
            {
                result |= (0x01 << i);  // 不匹配位置1
            }
        }
        
        // 3. 结果取反后送P1(低电平点亮LED,匹配时亮)
        P1 = ~result;
        
        delay_10ms();  // 延时后重复执行
    }
}

编译与烧录

在Keil C51中新建工程,选择Atmel AT89C52或STC89C52RC器件,将上述代码添加为main.c,编译生成HEX文件。使用STC-ISP软件通过串口将HEX烧录到单片机。

验证方法与判定标准

验证步骤:

  1. 烧录程序后上电运行,观察P1口连接的8个LED。
  2. 正常工作时,由于写入数据与读出数据完全一致,result = 0x00,P1 = 0xFF,所有LED应全部熄灭(高电平不点亮)。
  3. 人为修改代码中test_data数组的任意一个值(例如将0xAA改为0xAB),重新编译烧录,对应位LED点亮,表示该位数据不匹配。
  4. 断电后等待5秒重新上电,观察LED状态与断电前一致(程序重新执行写入操作,RAM内容被重新初始化)。

判定标准:

  • RAM读写功能正确:LED全部熄灭,说明写入与读取的数据完全一致,读写操作无误。
  • RAM易失性验证:在程序运行过程中断电,重新上电后程序从头执行,RAM中原有数据(非本次写入的)已丢失,但程序会重新写入测试数据,因此LED状态恢复为全部熄灭。若在断电前修改程序使某位LED点亮,重新上电后该位恢复熄灭,则证明RAM数据在掉电后丢失,程序重新初始化了RAM内容。

预期输出:程序正常运行且RAM读写正确时,P1输出0xFF,8个LED全部处于熄灭状态。若将test_data[0]改为0xAB,则P1输出0xFE,LED0点亮,其余熄灭。