📄 x50451.c
字号:
/*------------------- x5045.c ----------------------------*/
/*------------------- 使用AT89C2051模拟SPI总线程序 ------------------------*/
/*---------- 从机器件为X5045,看门狗、复位芯片、自带4Kbit EEPROM存储器 -------*/
/*----------------- Name:lilac Time:2006.7.22 ----------------*/
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
sbit SCK =P3^2; // SPI协议串行时钟
sbit MOSI =P3^3; // SPI协议主机输出从机输入
sbit MISO =P3^4; // SPI协议主机输入从机输出
sbit WCS =P3^5; // 喂狗信号、从机选择
sbit DI =P1^3; // LED数码管显示串行数据
sbit CLK1 =P1^2; // LED数码管显示串行时钟
sbit PWR_OK =P1^6; // 正确上电复位指示
sbit CTRL =P1^7; // LED数码管显示开关控制
#define unchar unsigned char
#define unint unsigned int
#define WREN 0x06 // 置位WEL标识位指令
#define WRDI 0x04 // 清零WEL标识位指令
#define RDSR 0x05 // 读状态寄存器指令
#define WRSR 0x01 // 写状态寄存器指令
#define READ_UPPER 0x0b // 读4Kbit EEPROM的一半高地址存储器指令
#define READ_LOWER 0x03 // 读4Kbit EEPROM的一半低地址存储器指令
#define WRITE_UPPER 0x0a // 写4Kbit EEPROM的一半高地址存储器指令
#define WRITE_LOWER 0x02 // 写4Kbit EEPROM的一半低地址存储器指令
#define PROTECT_ALL 0x0c // 对4Kbit EEPROM全部写保护,看门狗溢出时间为1.4秒
#define PROTECT_HALF 0x08 // 对4Kbit EEPROM地址空间0x100-0x1FF写保护,看门狗溢出时间为1.4秒
#define PROTECT_QUAR 0x04 // 对4Kbit EEPROM地址空间0x180-0x1FF写保护,看门狗溢出时间为1.4秒
#define NO_PROTECT 0x00 // 对4Kbit EEPROM全部不写保护,看门狗溢出时间为1.4秒
#define delaynop() { _nop_(); _nop_(); }; // 时间延时
unchar code ledseg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; // 共阴极显示段码
/* ------------------ x5045操作函数部分 ----------------- */
void delay2ms(unsigned int delay) // 延时程序由Delay参数确定延迟时间
{
unsigned int i;
for(;delay>0;delay--)
{
for(i=0;i<124;i++)
;
}
}
void write_wel(unchar instr) // 对WEL寄存器的置位和复位操作
{
unchar n=8;
WCS=0;
SCK=1;
while(n--)
{
SCK=0;
if((instr & 0x80)==0x80)
MOSI=1;
else
MOSI=0;
instr=instr<<1;
SCK=1;
}
WCS=1;
}
void send_byte(unchar da) // 向从机发送一个字节的数据
{
unchar n=8; // 向SDA上发送一数据字节,共八位
SCK = 1 ; // 时钟置高
while(n--)
{
SCK = 0 ; // 时钟置低
if((da & 0x80) == 0x80) // 若要发送的数据最高位为1则发送位1
MOSI = 1; // 传送位1
else
MOSI = 0; // 否则传送位0
da = da <<1; // 数据左移一位
SCK = 1 ; // 时钟置高
}
}
unchar receive_byte() // 从数据线接收一个字节的数据
{
unchar n=8; // 从MISO线上读取一上数据字节,共八位
unchar tmp;
SCK = 1; // 时钟为高
MISO=1;
while(n--)
{
SCK = 0; // 时钟为低
tmp = tmp <<1; // 左移一位
if(MISO == 1)
tmp = tmp | 0x01; // 若接收到的位为1,则数据的最后一位置1
else
tmp = tmp & 0xfe; // 否则数据的最后一位置0
SCK =1;
MISO=1;
}
return(tmp);
}
void write_char(unchar instr,unchar addr,unchar da) // 对指定地址的存储器空间的写操作
{
WCS=0; // 选择从机
send_byte(instr);
send_byte(addr);
send_byte(da);
WCS=1;
delay2ms(3); // 延时6ms,内部存储器写周期
}
void write_string(unchar instr,unchar addr,unchar *da) // 连续16字节写EEPROM存储器模式
{
unchar tmp;
unchar i;
WCS=0; // 选择从机
send_byte(instr);
send_byte(addr);
for(i=0;i<16;i++)
{
tmp=da[i];
send_byte(tmp);
}
WCS=1; // 从机选择线置位,结束数据传送
delay2ms(3); // 延时6ms,内部存储器写周期
}
unchar read_char(unchar instr,unchar addr) // 从指定地址的存储空间读取一个字节的数据
{
unchar tmp=0;
WCS = 0; // 选择从机
send_byte(instr);
send_byte(addr);
tmp = receive_byte();
WCS=1; // 从机选择线置位,结束数据传送
return tmp;
}
void read_string(unchar instr,unchar addr,unchar *da) // 连续16字节读EEPROM存储器模式
{
unchar tmp;
unchar i;
WCS = 0; //选择从机
send_byte(instr);
send_byte(addr);
tmp=0;
for(i=0;i<16;i++)
{
tmp = receive_byte();
da[i]=tmp;
}
WCS=1; // 从机选择线置位,结束数据传送
}
unchar read_sr(unchar instr) // 读状态寄存器
{
unchar tmp;
WCS = 0; // 选择从机
send_byte(instr);
tmp=0;
tmp = receive_byte();
WCS=1;
return tmp; // 返回状态寄存器的值
}
void write_sr(unchar instr,unchar da)
{
WCS = 0; // 选择从机
send_byte(instr);
send_byte(da);
WCS=1; // 从机选择线置位,结束数据传送
delay2ms(3);
}
void softdog() // 产生喂狗信号
{
WCS=1;
_nop_();
WCS=0;
_nop_();
WCS=1;
}
void clear_mem(unchar be,unchar end) // 一定地址空间的存储器清零
{
for(;be<=end;be++)
{
write_wel(WREN);
WCS=0; // 选择从机
send_byte(WRITE_LOWER);
send_byte(be);
send_byte(0);
WCS=1;
delay2ms(3); // 延时6ms,内部存储器写周期
softdog();
}
}
/* ---------------------- 测试程序部分 ----------------------------- */
void main(void)
{
unchar data da1=76;
unchar code trydata[]={1,2,3,4,5,6,7,8,9,80,70,60,50,40,30,20};
unchar data buf[17]={0};
unchar rs;
unchar i;
PWR_OK=0;
CTRL=1;
to_bcd(rs,showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
write_wel(WREN);
write_char(WRITE_LOWER,0x50,da1);
rs =0;
rs = read_char(READ_LOWER,0x50);
CTRL=1;
to_bcd(rs,showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
delay2ms(200);
softdog();
write_wel(WREN);
write_sr(WRSR,NO_PROTECT);
rs=0;
rs=read_sr(RDSR);
CTRL=1;
to_bcd(rs,showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
delay2ms(200);
write_wel(WREN);
write_string(WRITE_LOWER,0x00,trydata);
read_string(READ_LOWER,0x00,buf);
while(1)
{
for(i=0;i<16;i++)
{
CTRL=1;
to_bcd(buf[i],showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
delay2ms(200);
softdog();
}
}
}
/*
unchar addr;
unchar tmp;
for(addr=0;addr<128;addr++)
{
tmp=0;
tmp = read_char(READ_LOWER,addr);
CTRL=1;
to_bcd(tmp,showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
PWR_OK=0;
delay2ms(100);
PWR_OK=1;
delay2ms(100);
softdog();
}
PWR_OK=0;
delay2ms(400);
PWR_OK=1;
softdog();
clear_mem(0x00,0x80);
while(1)
{
for(addr=0;addr<128;addr++)
{
tmp=0;
tmp = read_char(READ_LOWER,addr);
CTRL=1;
to_bcd(tmp,showbuf);
txdbyte(showbuf[1]);
txdbyte(showbuf[0]);
CTRL=0;
PWR_OK=0;
delay2ms(100);
PWR_OK=1;
delay2ms(100);
softdog();
}
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -