/*******************************************************************************
* 标题: me300系列单片机开发系统演示程序 - at93c46读写演示程序 *
* 硬件: me300a+,me300b *
* 文件: wl006.c *
* 日期: 2004-1-5 *
* 版本: 1.0 *
* 作者: 伟纳电子 - freeman *
* 邮箱:
freeman@willar.com *
* 网站:
http://www.willar.com *
********************************************************************************
* 描述: *
* at93c46读写演示程序 *
* 从地址0x00开始写入数据“
www.willar.com”, 然后再读出 *
* *
* 注意:在擦除或写入数据之前,必须先写入ewen指令,93c46右边的jp7跳线 *
* 用于8位和16位模式选择,默认为8位模式 *
********************************************************************************
* 跳线设置: *
* me300a+ jp1 全部短接,jp2短接3-4端 *
* me300b jp1 短接,jp2短接3-4端,jp3短接93端 *
* *
********************************************************************************
* 【版权】 copyright(c)伟纳电子
www.willar.com all rights reserved *
* 【声明】 此程序仅用于学习与参考,引用请注明版权和作者信息! *
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>
//define op code
#define op_ewen_h 0x00 // 00 写入使能指令的高8位
#define op_ewen_l 0x60 // 11x xxxx 写入全能指令的低8位
#define op_ewds_h 0x00 // 00 写入禁止指令的高8位
#define op_ewds_l 0x00 // 00x xxxx 写入禁止指令的低8位
#define op_eral_h 0x00 // 00 整片擦除指令高8位
#define op_eral_l 0x40 // 10x xxxx 整片探险指令低8位
#define op_wral_h 0x00 // 00 整片写入指令的高8位
#define op_wral_l 0x20 // 01x xxxx 整片写入指令的低8位
#define op_write_h 0x40 // 01 a6-a0 写入指令的高位
#define op_read_h 0x80 // 10 a6-a0 读取指令的高位
#define op_erase_h 0xc0 // 11 a6-a0 删除指令的高位
//define pin
sbit cs = p3^4; //片选
sbit sk = p3^3; //时钟
sbit di = p3^5; //数据输入
sbit do = p3^6; //数据输出
unsigned char code dis_code[] = {0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e,0xff};
//void start(); //
void ewen(); //写入使能函数
void ewds(); //写入禁止函数
void erase(); //整片擦除函数
void write(unsigned char addr, unsigned char indata); //在指定地址写入数据函数
unsigned char read(unsigned char addr); //读取指定地址函数
void inop(unsigned char op_h, unsigned char op_l); //写入指令函数
void shin(unsigned char indata); //写入数据函数
unsigned char shout(); //读出数据函数
void delayms(unsigned char ms); //延时函数
main()
{
unsigned char i;
cs = 0; //初始化端口
sk = 0;
di = 1;
do = 1;
ewen(); // 使能写入操作
erase(); // 擦除全部内容
for(i = 0 ; i < 8; i++) //写入显示代码到at93c46
{
write(i, dis_code
);
}
ewds(); // 禁止写入操作
i = 0;
while(1)
{
p0 = read(i); // 循环读取at93c46内容,并输出到p0口
i++;
i &= 0x07; // 循环读取地址为0x00~0x07
delayms(250);
}
}
void write(unsigned char addr, unsigned char indata)
// 写入数据indata到addr
{
inop(op_write_h, addr); //写入指令和地址
shin(indata); //写入数据
cs = 0;
delayms(10); // twp
}
unsigned char read(unsigned char addr)
// 读取addr处的数据
{
unsigned char out_data;
inop(op_read_h, addr); //写入指令和地址
out_data = shout(); //读出数据
cs = 0;
return out_data;
}
void ewen()
//写入使能
{
inop(op_ewen_h, op_ewen_l);
cs= 0;
}
void ewds()
//写入禁止
{
inop(op_ewds_h, op_ewds_l);
cs= 0;
}
//整片擦除
void erase()
{
inop(op_eral_h, op_eral_l);
delayms(30);
cs = 0;
}
void inop(unsigned char op_h, unsigned char op_l)
//移入op_h的高两位和op_l的低7位
//op_h为指令码的高两位
//op_l为指令码的低7位或7位地址
{
unsigned char i;
sk = 0; // 开始位
di = 1;
cs = 1;
_nop_();
_nop_();
sk = 1;
_nop_();
_nop_();
sk = 0; // 开始位结束
di = (bit)(op_h & 0x80); // 先移入指令码高位
sk = 1;
op_h <<= 1;
sk = 0;
di = (bit)(op_h & 0x80); // 移入指令码次高位
sk = 1;
_nop_();
_nop_();
sk = 0;
// 移入余下的指令码或地址数据
op_l <<= 1;
for(i = 0; i < 7; i++)
{
di = (bit)(op_l & 0x80); // 先移入高位
sk = 1;
op_l <<= 1;
sk = 0;
}
di = 1;
}
void shin(unsigned char indata)
//移入数据
{
unsigned char i;
for(i = 0; i < 8; i++)
{
di = (bit)(indata & 0x80); // 先移入高位
sk = 1;
indata <<= 1;
sk = 0;
}
di = 1;
}
unsigned char shout(void)
// 移出数据
{
unsigned char i, out_data;
for(i = 0; i < 8; i++)
{
sk = 1;
out_data <<= 1;
sk = 0;
out_data |= (unsigned char)do;
}
return(out_data);
}
void delayms(unsigned char ms)
// 延时子程序
{
unsigned char i;
while(ms--)
{
for(i = 0; i < 120; i++);
}
}