📄 x5045.c
字号:
#include "public.h"
/*
//写使能子程序
void wren_cmd(void)
{
uchar aa;
SCK=0; // Bring SCK low
CS=0; // Bring /CS low
aa=WREN_INST;
inbyte(aa); // Send WREN instruction
SCK=0; // Bring SCK low
CS=1; // Bring /CS high
}
//写使能复位子程序
void wrdi_cmd(void)
{
uchar aa;
SCK=0; // Bring SCK low
CS=0; // Bring /CS low
aa=WRDI_INST;
inbyte(aa); // Send WRDI instruction
SCK=0; // Bring SCK low
CS=1; // Bring /CS high
}
//写状态寄存器子程序
void wrsr_cmd(void)
{
uchar aa;
SCK=0; // Bring SCK low
CS=0; // Bring /CS low
aa=WRSR_INST;
inbyte(aa); // Send WRSR instruction
aa=STATUS_REG;
inbyte(aa); // Send status register
SCK=0; // Bring SCK low
CS=1; // Bring /CS high
wip_poll(); // Poll for completion of write cycle
}
//读状态寄存器,读出的数据放入到aa中
uchar rdsr_cmd (void)
{
uchar aa;
SCK=0;
CS=0;
aa=RDSR_INST;
inbyte(aa);
aa=outbyte();
SCK=0;
CS=1;
return aa;
}
//字节写入,aa为写入的数据,dd为写入的地址,对于25045而言为000-1FF
void byte_write(aa,dd)
uchar aa;
uint dd;
{
SCK=0;
CS=0;
inbyte((((uchar)(dd-0XFF))<<3)|WRITE_INST);// Send WRITE instruction including MSB of address
//将高位地址左移3位与写入先导字相或,得到正确的先导字写入5045
inbyte((uchar)(dd));
//输出低位地址到5045
inbyte(aa);
//写入数据到5045的对应单元
SCK=0;
CS=1;
wip_poll();
//检测是否写完
}
//字节读出,其中dd为读出的地址,返回的值为读出的数据
uchar byte_read(dd)
uint dd;
{
uchar cc;
SCK=0;
CS=0;
inbyte((((uchar)(dd-0XFF))<<3)|READ_INST);// Send READ_INST instruction including MSB of address
//将高位地址左移3位与读出先导字相或,得到正确的先导字写入5045
inbyte((uchar)(dd));
//输出低位地址到5045
cc=outbyte();//得到读出的数据
SCK=0;
CS=1;
return cc;
}
//页面写入,其中aa1,aa2,aa3,aa4为需要写入的4个数据(最大也就只能一次写入4个字,dd为写入的首地址
void page_write(aa1,aa2,aa3,aa4,dd)
uchar aa1,aa2,aa3,aa4;
uint dd;
{
SCK=0;
CS=0;
inbyte((((uchar)(dd-0XFF))<<3)|WRITE_INST);// Send WRITE instruction including MSB of address
//将高位地址左移3位与写入先导字相或,得到正确的先导字写入5045
inbyte((uchar)(dd));
//写入低位地址到5045
inbyte(aa1);
//写入数据1到5045的对应单元
inbyte(aa2);
//写入数据2到5045的对应单元
inbyte(aa3);
//写入数据3到5045的对应单元
inbyte(aa4);
//写入数据4到5045的对应单元
SCK=0;
CS=1;
wip_poll();
}
//连续读出,由于函数的返回值只能为1个,对于连续读出的数据只能使用指针作为函数的返回值才能做到返回一系列的数组
//sequ_read:
unsigned int *page_read(n,dd)
uchar n;//n是希望读出的数据的个数,n<=11
unsigned int dd;//dd是读出数据的首地址
{
uchar i;
uchar pp[10];
unsigned int *pt=pp;
SCK=0;
CS=0;
inbyte((((uchar)(dd-0XFF))<<3)|READ_INST);
for (i=0;i<n;i++)
{
pp[i]=outbyte();
}
return (pt);
}
//复位DOG
void rst_wdog (void)
{
//网上源程序有问题
CS=0;
CS=1;
}
//检测写入的过程是否结束
void wip_poll(void)
{
uchar aa;
uchar idata my_flag;
for (aa=1;aa>MAX_POLL;aa++)
{
my_flag=rdsr_cmd();
if ((my_flag&&0x01)==0) {aa=MAX_POLL;}//判断是否WIP=0,即判断是否写入过程已经结束,若结束就跳出,否则继续等待直到达到最大记数值
}
}
*/
//输入一个数据到5045,此数据可能为地址,先导字,写入的数据等
void inbyte(uchar aa)
{
uchar i; //LHM QUESTION:为什么只有7bits,哦,是8bits
for(i=0;i<=6;i++){
SCK=0;
SI=((aa>>(7-i))&0x01);
SCK=1;
}
SCK=0;
SI=aa&0x01;
SCK=1;
SI=0;
}
//得到一个数据,此数据可能为状态寄存器数据,读出的单元数据等
uchar outbyte(void)
{
uchar bb;
uchar i;
bb=0; //LHM QUESTION:为什么 SCK赋1后马上赋0
for(i=0;i<=7;i++){
SCK=1;
SCK=0;
bb=((bb<<1)|SO);
}
return(bb);
}
//写5045(包含写寄存器,写数据至存储阵列)
void write5045(void)
{
uchar aa;
//设置写使能
CS=0; //CS为低
SCK=0; //SCK为低
aa=WREN_INST;
inbyte(aa); // Send WREN instruction
SCK=0;
CS=1;
//写状态寄存器
CS=0;/*CS为低*/
SCK=0;
aa=WRSR_INST;
inbyte(aa);
aa=STATUS_REG;/*为0x30时,是不允许复位的.设置看门狗动作的超时周期为:200ms*/
inbyte(aa);
SCK=0;
CS=1;
//读状态寄存器,检查WIP位,为0,则没有写操作;为1,则正在进行写操作。//LHM UNDERSTAND:等到写完再做下一步
do{
CS=0;
SCK=0;
aa=RDSR_INST;
inbyte(aa);
aa=outbyte();
SCK=0;
CS=1;
}while((aa&0x01)==1);
//设置写使能
CS=0;//CS为低
SCK=0;//SCK为低
aa=WREN_INST;
inbyte(aa);
SCK=0;
CS=1;
//从以下的地址开始选输入数据至存储器阵列
CS=0;
SCK=0;
aa=WRITE_INST;
inbyte(aa);
aa=0x00;//放在5045的00H开始的位置
inbyte(aa);
inbyte(data5045.cF0);
inbyte(data5045.cF1);
inbyte(data5045.cF2);
inbyte(data5045.cF3);
inbyte(data5045.cF4);
SCK=0;
CS=1;
//读状态寄存器,检查WIP位,为0,则没有写操作;为1,则正在进行写操作。//LHM UNDERSTAND:等到写完再做下一步
do{
CS=0;
SCK=0;
aa=RDSR_INST;
inbyte(aa);
aa=outbyte();
SCK=0;
CS=1;
}while((aa&0x01)==1);
}
//将数据从存储阵列中读出
void read5states(void)
{
uchar aa;
CS=0;
SCK=0;
aa=READ_INST; //LHM QUESTION: Read instruction 的位3选择器件的高半部分,还是低半部分
inbyte(aa);
aa=0x00;
inbyte(aa);
data5045.cF0=outbyte();
data5045.cF1=outbyte();
data5045.cF2=outbyte();
data5045.cF3=outbyte();
data5045.cF4=outbyte();
SCK=0;
CS=1;
}
//LHM COMMENT:资料上说,为防止看门狗复位,在看门狗超时以前CS引脚应该进行由高到低的触发。以下更保险一些。
void watchdog(void)
{
P3_5=!P3_5;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -