目前共有4篇帖子。 内容转换:不转换▼
 
点击 回复
683 3
【程序】51单片机操作93C46存储器
一派护法 十九级
1楼 发表于:2017-2-22 08:12
/* ORG悬空,选16位模式 */
#include <at89x52.h>

#define _BV(n) (1 << (n))

sbit CS = P1^0;
sbit SK = P1^1;
sbit DI = P1^2;
sbit DO = P1^3;

unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90};
unsigned int num = 0;

void delay(unsigned int n)
{
    unsigned char i;
    while (n--)
        for (i = 0; i < 115; i++);
}

// 在数码管上显示num的值
void seg_scan(void)
{
    char i;
    unsigned int n = num;
    for (i = 7; i >= 3; i--) // 从低位扫描到高位
    {
        P2 = 0xff;
        P0 = seg8[n % 10];
        P2 = ~_BV(i);
        delay(3);
        n /= 10;
    }
}

void _93C46_WriteOP(unsigned char op)
{
    // 初态
    CS = 0;
    SK = 0;
    DI = 1;
    
    // 开始位
    CS = 1;
    SK = 1;
    SK = 0;
    
    // OP位
    if ((op & 2) == 0)
        DI = 0;
    SK = 1;
    SK = 0;
    if (op & 1)
        DI = 1;
    else
        DI = 0;
    SK = 1;
    SK = 0;
}

void _93C46_WriteAddress(unsigned char addr)
{
    unsigned char i;
    for (i = 0; i < 6; i++)
    {
        if (addr & 0x20)
            DI = 1;
        else
            DI = 0;
        SK = 1;
        SK = 0;
        addr <<= 1;
    }
    DI = 0;
}

unsigned int _93C46_ReadWord(void)
{
    unsigned char i;
    unsigned int dat = 0;
    DO = 1;
    for (i = 0; i < 16; i++)
    {
        SK = 1;
        dat <<= 1;
        if (DO)
            dat |= 1;
        SK = 0;
    }
    return dat;
}

unsigned int _93C46_Read(unsigned char addr)
{
    unsigned int dat;
    _93C46_WriteOP(2);
    _93C46_WriteAddress(addr);
    dat = _93C46_ReadWord();
    CS = 0;
    return dat;
}

void _93C46_WriteWord(unsigned int dat)
{
    unsigned char i;
    for (i = 0; i < 16; i++)
    {
        if (dat & 0x8000)
            DI = 1;
        else
            DI = 0;
        SK = 1;
        SK = 0;
        dat <<= 1;
    }
    DI = 0;
}

// 等待操作完毕
void _93C46_Wait(void)
{
    CS = 0;
    CS = 1;
    DO = 1; // tSV<=250ns
    while (!DO);
    CS = 0;
}

// 允许/禁止擦写
void _93C46_EnableWrite(unsigned char enabled)
{
    _93C46_WriteOP(0);
    _93C46_WriteAddress((enabled) ? 0x30 : 0x00);
    CS = 0;
}

// 写入单个存储单元
void _93C46_Write(unsigned char addr, unsigned int dat)
{
    _93C46_WriteOP(1);
    _93C46_WriteAddress(addr);
    _93C46_WriteWord(dat);
    _93C46_Wait();
}

// 擦除单个存储单元
void _93C46_Erase(unsigned char addr)
{
    _93C46_WriteOP(3);
    _93C46_WriteAddress(addr);
    _93C46_Wait();
}

// 擦除所有存储单元(设为0xffff)
void _93C46_EraseAll(void)
{
    _93C46_WriteOP(0);
    _93C46_WriteAddress(0x20);
    _93C46_Wait();
}

// 将所有的存储单元设为指定值
void _93C46_WriteAll(unsigned int dat)
{
    _93C46_WriteOP(0);
    _93C46_WriteAddress(0x10);
    _93C46_WriteWord(dat);
    _93C46_Wait();
}

int main(void)
{
    _93C46_EnableWrite(1); // 允许写入
    num = _93C46_Read(10);
    _93C46_Write(10, num + 1);
    
    _93C46_EnableWrite(0); // 禁止写入
    _93C46_WriteAll(78);
    _93C46_Erase(10);
    _93C46_EraseAll();
    
    while (1)
        seg_scan();
}
一派护法 十九级
2楼 发表于:2017-2-22 08:45
【一次性读多个存储单元】
/* ORG悬空,选16位模式 */
#include <at89x52.h>

#define _BV(n) (1 << (n))

sbit CS = P1^0;
sbit SK = P1^1;
sbit DI = P1^2;
sbit DO = P1^3;

unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e};
struct datablock
{
    unsigned int id;
    unsigned int num;
} db;

void delay(unsigned int n)
{
    unsigned char i;
    while (n--)
        for (i = 0; i < 115; i++);
}

void seg_scan(void)
{
    char i;
    unsigned int n = db.id;
    for (i = 3; i >= 0; i--)
    {
        P2 = 0xff;
        P0 = seg8[n & 0x0f];
        P2 = ~_BV(i);
        delay(2);
        n >>= 4;
    }
   
    n = db.num;
    for (i = 7; i >= 4; i--)
    {
        P2 = 0xff;
        P0 = seg8[n & 0x0f];
        P2 = ~_BV(i);
        delay(2);
        n >>= 4;
    }
}

void _93C46_WriteOP(unsigned char op)
{
    // 初态
    CS = 0;
    SK = 0;
    DI = 1;
   
    // 开始位
    CS = 1;
    SK = 1;
    SK = 0;
   
    // OP位
    if ((op & 2) == 0)
        DI = 0;
    SK = 1;
    SK = 0;
    if (op & 1)
        DI = 1;
    else
        DI = 0;
    SK = 1;
    SK = 0;
}

void _93C46_WriteAddress(unsigned char addr)
{
    unsigned char i;
    for (i = 0; i < 6; i++)
    {
        if (addr & 0x20)
            DI = 1;
        else
            DI = 0;
        SK = 1;
        SK = 0;
        addr <<= 1;
    }
    DI = 0;
}

unsigned int _93C46_ReadWord(void)
{
    unsigned char i;
    unsigned int dat = 0;
    DO = 1;
    for (i = 0; i < 16; i++)
    {
        SK = 1;
        dat <<= 1;
        if (DO)
            dat |= 1;
        SK = 0;
    }
    return dat;
}

// 读入多个存储单元
void _93C46_ReadBlock(unsigned char addr, unsigned int *dat, unsigned char count)
{
    _93C46_WriteOP(2);
    _93C46_WriteAddress(addr);
    while (count > 0)
    {
        *dat++ = _93C46_ReadWord();
        count -= 2;
    }
    CS = 0;
}

int main(void)
{
    _93C46_ReadBlock(0, (unsigned int *)&db, sizeof(db));
    while (1)
        seg_scan();
}
一派护法 十九级
3楼 发表于:2017-2-22 13:45
void _93C46_EnableWrite(unsigned char enabled)
这里enabled参数用bit类型更好一点。
一派护法 十九级
4楼 发表于:2017-2-23 18:44
【全部存储单元测试】
/* ORG悬空,选16位模式 */
#include <at89x52.h>

#define _BV(n) (1 << (n))

sbit CS = P1^0;
sbit SK = P1^1;
sbit DI = P1^2;
sbit DO = P1^3;

unsigned char code seg8[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xa7, 0xa1, 0x86, 0x8e};
unsigned char id;
unsigned int num;

void delay(unsigned int n)
{
    unsigned char i;
    while (n--)
        for (i = 0; i < 115; i++);
}

void seg_scan(void)
{
    char i;
    unsigned int n = id;
    for (i = 1; i >= 0; i--)
    {
        P2 = 0xff;
        P0 = seg8[n % 10];
        P2 = ~_BV(i);
        delay(2);
        n /= 10;
    }
   
    n = num;
    for (i = 7; i >= 3; i--)
    {
        P2 = 0xff;
        P0 = seg8[n % 10];
        P2 = ~_BV(i);
        delay(2);
        n /= 10;
    }
}

void _93C46_WriteOP(unsigned char op)
{
    // 初态
    CS = 0;
    SK = 0;
    DI = 1;
   
    // 开始位
    CS = 1;
    SK = 1;
    SK = 0;
   
    // OP位
    if ((op & 2) == 0)
        DI = 0;
    SK = 1;
    SK = 0;
    if (op & 1)
        DI = 1;
    else
        DI = 0;
    SK = 1;
    SK = 0;
}

void _93C46_WriteAddress(unsigned char addr)
{
    unsigned char i;
    for (i = 0; i < 6; i++)
    {
        if (addr & 0x20)
            DI = 1;
        else
            DI = 0;
        SK = 1;
        SK = 0;
        addr <<= 1;
    }
    DI = 0;
}

unsigned int _93C46_ReadWord(void)
{
    unsigned char i;
    unsigned int dat = 0;
    DO = 1;
    for (i = 0; i < 16; i++)
    {
        SK = 1;
        dat <<= 1;
        if (DO)
            dat |= 1;
        SK = 0;
    }
    return dat;
}

unsigned int _93C46_Read(unsigned char addr)
{
    unsigned int dat;
    _93C46_WriteOP(2);
    _93C46_WriteAddress(addr);
    dat = _93C46_ReadWord();
    CS = 0;
    return dat;
}

void _93C46_WriteWord(unsigned int dat)
{
    unsigned char i;
    for (i = 0; i < 16; i++)
    {
        if (dat & 0x8000)
            DI = 1;
        else
            DI = 0;
        SK = 1;
        SK = 0;
        dat <<= 1;
    }
    DI = 0;
}

// 等待操作完毕
void _93C46_Wait(void)
{
    CS = 0;
    CS = 1;
    DO = 1; // tSV<=250ns
    while (!DO);
    CS = 0;
}

// 允许/禁止擦写
void _93C46_EnableWrite(unsigned char enabled)
{
    _93C46_WriteOP(0);
    _93C46_WriteAddress((enabled) ? 0x30 : 0x00);
    CS = 0;
}

// 写入单个存储单元
void _93C46_Write(unsigned char addr, unsigned int dat)
{
    _93C46_WriteOP(1);
    _93C46_WriteAddress(addr);
    _93C46_WriteWord(dat);
    _93C46_Wait();
}

int main(void)
{
    unsigned char i;
   
    _93C46_EnableWrite(1);
    for (i = 0; i < 64; i++)
        _93C46_Write(i, 10000 + i * 100 + i);
    _93C46_EnableWrite(0);
   
    while (1)
    {
        num = _93C46_Read(id);
        for (i = 0; i < 50; i++)
            seg_scan();
       
        id++;
        if (id > 63)
            id = 0;
    }
}

回复帖子

内容:
用户名: 您目前是匿名发表
验证码:
(快捷键:Ctrl+Enter)
 

本帖信息

点击数:683 回复数:3
评论数: ?
作者:巨大八爪鱼
最后回复:巨大八爪鱼
最后回复时间:2017-2-23 18:44
 
©2010-2024 Arslanbar Ver2.0
除非另有声明,本站采用知识共享署名-相同方式共享 3.0 Unported许可协议进行许可。