📄 memtest.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 + -