📄 x5043.c
字号:
#include <intrins.h>
#include "STC12C5410.H"
#include "headfile1.c"
//5043的操作注意事项
/*
1. 任何写操作之前必须执行WREN指令,该指令将写允许锁存位WEL置位,WEL在上电后,
一个写周期,及WP被拉低时都将复位
2. 在写入WREN和WESR指令之间,CS上必须有LOW-HIGH的跳变,否则WRSR指令将会被忽略。
WEL和WP的任意一个有效时,所有的MEMORY BLOCK和 STATUS REGISTER 都将被保护而
当两位都无效时,只有由BL决定的保护区被写保护。
3. CS片选后,依次写入READ指令以及要读的ADDRESS,连续的读操作将会使地址转向下一
个更高的地址,读到最高地址后将会翻转到000X,将CS置位将会结束读操作
4. 写操作之前,首先复位CS,用WREN指令置位WEL,置位CS。后再将CS复位,依次写入
WRITE指令,address,以及 DATA ( WRITE 指令的BIT.3代表address的BIT.8 ),可以
执行连续写操作,但是所有的写入ADDRESS只能在一页中,写操作执行过程中CS的置
位将导致写操作中断
5. 上电后,在开始任何操作之前,都必须使CS引脚上有一个HIGH-LOW的变化,相当预先
执行一个喂狗操作
*/
//------------------//
bit flow;
//------------------//
//5043的操作指令
#define WREN 0X06 //写允许
#define WRDI 0X04 //写禁止
#define RSDR 0X05 //读状态寄存器
#define WRSR 0X01 //写状态寄存器
#define READ 0X03 //读操作
#define WRITE 0X02 //写操作
sbit CS=P1^2; //片选端,低电平有效
sbit SCK=P1^3; //时钟信号 The Serial Clock controls the serial bus timing for data input and output
sbit SI=P1^4; //数据输入端 Data is latched by the rising edge of the serial clock.
sbit SO=P1^5; //数据输出端 During a read cycle, data is shifted out on this pin.
// Data is clocked out by the falling edge of the serial clock.
sbit WP=P1^6; //写保护,低电平有效 When WP is low, nonvolatile writes to the X5043/45 are
//disabled, but the part otherwise functions normally.When WP is held high,
//all functions, including non volatile writes operate normally
//us级延时函数delay_us(BYTE),仿真结果为每一循环3us(11.0592MHZ,STC12C5410)
static void delay_us(BYTE timeout)
{
volatile BYTE del;
for(del=timeout;del>0;del--)
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
}
//ms级延时函数
static void delay_ms(WORD timeout)
{
volatile WORD del;
for(del=timeout;del>0;del--)
{
delay_us(166); //1/2ms
_WDT_();
}
}
static void open(void) //片选及关闭写保护
{
SI = 0;
SO = 1;
SCK= 0;
CS = 0;
WP = 1;
}
static void close(void) //禁止片选,打开写保护
{
SI = 0;
SO = 1;
SCK= 0;
CS = 1;
WP = 0;
}
static void outbyte(BYTE val) //输出字节
{
BYTE over;
for (over=8;over>0;over--)//8次循环,输出一个字节
{
SCK = 0; //时钟低电平
if(val&0x80) SI = 1;
else SI = 0;
delay_us(0x05); //延时,等待数据稳定
SCK = 1; //数据输出
delay_us(0x05); //延时
val <<= 1; //输出下一位
}
SI = 0;
SCK = 0;
delay_us(0x10);
}
static BYTE inbyte(void) //输入字节
{
BYTE temp, val=0;
for(temp=8;temp>0;temp--) //8次循环,完成字节读入
{
if(SO) val |= 0x01;
else val &= 0x0FE; //读入下一位,当addr的最后一位写完的falling edge,数据已经
//开始输出,所以进入后直接先移入
SCK = 1;
delay_us(0x02);
SCK = 0; //读数据时钟
delay_us(0x02);
if(temp>1) val <<= 1;
}
SCK = 0;
delay_us(0x10);
return val; //返回读入值
}
void start_5043 (void)
{
//It should be noted that after power-up,a high to low transition
// on CS is required prior to the start of any operation
CS = 1;
delay_us(10);
CS = 0;
open(); //片选,关闭写保护
outbyte(WREN);
CS = 1;
delay_us(10); //WREN与WRSR之间CS拉高
CS = 0;
outbyte(WRSR); //写状态寄存器
outbyte(0x30);
delay_ms(20); //写操作延时
close();
}
BYTE read(BYTE addr) //从5043读出单字节数据
{
BYTE temp;
open();
outbyte(READ); //写入读指令
outbyte(addr); //写入读起始地址
temp = inbyte(); //读数据
close();
delay_ms(20);
return temp;
}
void save_to_5043(BYTE addr,BYTE val) //向5043写入单字节数据
{
open(); //写允许
outbyte(WREN);
CS = 1;
delay_us(10);
CS = 0;
//If CS does not go HIGH between WREN and WRITE, the WRITE
//instruction is ignored
outbyte(WRITE); //写入写操作命令
outbyte(addr); //写入写操作地址
outbyte(val); //写入数据
delay_ms(20); //此处不做对WIP的判断,直接做延时处理
close(); //写操作禁止
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -