⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memtest.c

📁 这是《Keil Cx51 V7.0单片机高级语言编程与uVision2应用实践》教材各章中列出的全部程序例子。
💻 C
字号:
#include <reg51.h>
#include <stdio.h>

typedef unsigned char datum;

/***************************** 数据总线测试函数 ***************************
 * 函数原型:datum  memTestDataBus(volatile datum xdata * address)
 * 功    能: 对某一固定地址存储器区域写入“移动的”1(walking 1’s),
*           存储器地址由主调函数给定。测试成功返回0,测试失败返回写入值。
*************************************************************************/
datum memTestDataBus(volatile datum xdata * address) {
  datum pattern;
  for (pattern = 1; pattern != 0; pattern <<= 1) {
    /* Write the test pattern */
    *address = pattern;			/* 写入测试值 */
    /* Read it back (immediately is okay for this test). */
    if (*address != pattern) {  /* 如果读取值与写入值不相等 */
      return (pattern);			/* 测试失败返回写入值 */
    }
  }
  return (0);					/* 测试成功返回0 */
}


/***************************** 地址总线测试函数 **************************** 函数原型:datum xdata *memTestAddressBus(volatile datum xdata 
*                                  baseAddress, unsigned long nBytes)
* 功    能:对某一段存储器地址范围的地址相关位写入“移动的”1(walking 1’s),    *           并检查是否发生混淆,测试中将发现单个位地址的错误,譬如“粘滞高、    *           粘滞低”(stuck-high、stuck-low)以及引脚间短路现象。测试基地址以     *           及测试范围由主调函数给定。测试成功返回 NULL,测试失败返回发生
*           混淆错误的首地址。
* 注:      为了获得最好的测试结果,测试基地址低位部分(LSB)应有足够多的的
*           0以保证单个位地址能够正确变化,例如要测试64KB范围的地址总线,测
*           试基地址应选择在64KB地址范围的边界上,并且应尽可能使被测试的地址
*           范围为2的整数次幂。通过检查存储器内容可以找出其 它错误信息。
*************************************************************************/
datum xdata *memTestAddressBus(volatile datum xdata * baseAddress, 
unsigned long nBytes) {
  unsigned long addressMask=(nBytes-1);
  unsigned long offset;
  unsigned long testOffset;
  
  datum pattern     = (datum) 0xAAAAAAAA;
  datum antipattern = (datum) 0x55555555;
  
  /* 对每个2的整数次幂的偏移地址写入默认的测试数据 */
  for (offset=sizeof(datum); (offset & addressMask)!=0; offset<<= 1) {
    baseAddress[offset] = pattern;
  }
  
  /* 检查地址位是否粘滞高 */
  testOffset = 0;
  baseAddress[testOffset] = antipattern;
  
  for (offset=sizeof(datum); (offset & addressMask)!=0; offset <<= 1) {
    if (baseAddress[offset] != pattern) {
      return ((datum xdata *) &baseAddress[offset]);
    }
  }
  
  baseAddress[testOffset] = pattern;
  
  /* 检查地址位是否粘滞低或发生短路 */
  for (testOffset=sizeof(datum); (testOffset & addressMask)!=0;
                                                testOffset <<= 1) {
    baseAddress[testOffset] = antipattern;
    for (offset=sizeof(datum); (offset & addressMask)!=0; offset <<= 1) {
      if ((baseAddress[offset] != pattern) && (offset != testOffset)) {
        return ((datum xdata *) &baseAddress[testOffset]);
      }
    }
    baseAddress[testOffset] = pattern;
  }
  return (NULL);
}

/******************************* 器件测试函数 ****************************** 函数原型:datum xdata *memTestDevice(volatile datum xdata * baseAddress,  
*                                                     unsigned long nBytes)
* 功    能:通过对存储器器件的整个地址单元进行加1和减1来测试其完整性,每一
*           个存储位都要进行写0和写1测试。测试基地址以及测试范围由主调函数
*           给定。测试成功返回NULL,并且整个存储器区域将用0填充。
*           测试失败则返回发生错误的第一个存储器地址。通过检查存储器内容可
*           以找出其它错误信息。
*************************************************************************/
datum xdata *memTestDevice(volatile datum xdata * baseAddress, 
unsigned long nBytes) {
  unsigned long offset;
  unsigned long nWords = nBytes / sizeof(datum);
  datum pattern;
  datum antipattern;

  /* 用已知数据填充存储器单元 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) {
    baseAddress[offset] = pattern;
  }

  /* 检查每个存储器单元并将其取反 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) {
    if (baseAddress[offset] != pattern) {
      return ((datum xdata *) &baseAddress[offset]);
    }

    antipattern = ~pattern;
    baseAddress[offset] = antipattern;
  }

  /* 检查每个存储器单元并将其清零 */
  for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++) {
    antipattern = ~pattern;
    if (baseAddress[offset] != antipattern) {
      return ((datum xdata *) &baseAddress[offset]);
    }
    baseAddress[offset] = 0;
  }
  return (NULL);
} 

/***************************** 存储器测试函数*****************************
* 函数原型:memTest()
* 功    能:测试外部RAM存储器数据总线、地址总线以及RAM器件。
*           测试成功返回0,测试失败返回-1
**************************************************************************/
int memTest(void) {
  #define BASE_ADDRESS  (volatile datum xdata *) 0x00009000 
  #define NUM_BYTES     8 * 1024
  if ((memTestDataBus(BASE_ADDRESS) != 0) ||
      (memTestAddressBus(BASE_ADDRESS, NUM_BYTES) != NULL) ||
      (memTestDevice(BASE_ADDRESS, NUM_BYTES) != NULL))
  {
    return (-1);
  }
  else
  {
    return (0);
  }		
}

void main(void) {
    SCON = 0x5a;        
    TMOD = 0x20;  
    TCON = 0x69;  
    TH1 =  0xfd; 
  if (!memTest())  printf("test t OK\n");
  else printf("test fail\n");
  while(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -