📄 framflashmemory.c
字号:
/*******************NVRAM读写程序以及时钟程序********************************/
/*******************用芯片SD2000E来实现**************************/
#include <C8051f120sfr.h>
#include <intrins.h>
#include <DataDefine.h>
#define DELAY_WRITE 5000 // 延时时间,目的是让I2C元件读的过程
#define high_byte(x) ((x&0xff00)>>8) // 取字的高位字节
//外部变量定义
xdata unsigned int smbus_over_time_num=0;
xdata unsigned char MyBuff[72];
//I2C元件读写部分函数原型
void NVRAM_write_byte (unsigned char data_out, unsigned char address); //写NVRAM
unsigned char NVRAM_read_byte (unsigned char address); //读NVRAM
void i2c_write (unsigned char output_data);
unsigned char i2c_read (void);
void delay_time (unsigned int time_end);
void i2c_start (void);
unsigned char i2c_stop_and_read (void);
void repeated_i2c_start_and_write (unsigned char output_data);
void i2c_stop_and_write (unsigned char output_data);
//SD2000B(第一页)的写入程序,如果是SD2000E,需注意机器字及地址位数的区别。
void NVRAM_write_byte (unsigned char data_out, unsigned char address) // 往NVRAM里写一个字节
{
xdata unsigned int i,j;
char SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=SMB0_PAGE;
i=address;
EA=0;
i2c_start(); // 使总线开始工作
i2c_write(0xA0); // 往总线上写目标装置的地址,以便识别目标装置
i2c_write(address); // 写NVRAM中地址的低位
i2c_stop_and_write(data_out); // 往给定地址中写数据并停止总线
EA=1;
for(j=0;j<2000;j++) // 延时一段时间给NVRAM让它自己写
_nop_();
SFRPAGE=SFRPAGE_SAVE;
}
//SD2000B(第一页)的读出程序,如果是SD2000E,需注意机器字及地址位数的区别。
unsigned char NVRAM_read_byte (unsigned char address) // 从NVRAM中读一个字节
{
unsigned char data_in;
xdata unsigned int i;
char SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=SMB0_PAGE;
i=address;
EA=0;
i2c_start(); // 发送开始信号
i2c_write(0xA0); // 发送目标元件地址,标志位为写
// i2c_write(high_byte(address)); // 发送要读数据地址的高位
repeated_i2c_start_and_write((unsigned char)address); //发送要读地址的地位并重发起始信号
i2c_write(0xA1); // 发送目标元件地址,标志位为读
data_in = i2c_stop_and_read(); // 读数据并停止总线
EA=1;
SFRPAGE=SFRPAGE_SAVE;
return data_in;
}
// 当SCL为高时,SDA上由高到低的变化,就是一个起始状态,这个状态必须先于其它任何命令
void i2c_start (void) // 发送起始条件函数
{
while (BUS_BUSY) // 判断总线是否空闲
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_STOP=1;
SMB0CN=0x00;
SMB0CN=0x44; //应答周期内返回确认,允许SMBUS
BUS_BUSY=0;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_START = TRUE; // 若总线空闲,就发送一个起始条件
while (!BUS_INT) // 判断起始条件是否发送
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_START = FALSE; // 起始条件发送后该位复位,否则将重复发送起始条件
BUS_INT = 0; // 将中断标志清零
}
void repeated_i2c_start_and_write (unsigned char output_data) // 重复开始并写,用于随即读的时序中,顺序???
{
BUS_START = TRUE; // 发送开始标志
SMB0DAT = output_data; // 将要写的数据写到数据寄存器
while (!BUS_INT) // 等待发送完成
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_INT = 0; // 中断标志清零
BUS_START = FALSE; // 起始条件发送后该位复位,否则将重复发送起始条件
while (!BUS_INT) // 这句是否可以不要????
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_INT = 0; // 将中断标志清零
}
void i2c_stop_and_write (unsigned char output_data) // 发送停止信号并写,用于字节写的时序
{
BUS_STOP = TRUE; // 发送停止信号
SMB0DAT = output_data; // 发送要写的最后一个数据
while (!BUS_INT) // 等待发送完
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_INT = 0; // 中断标志清零
}
unsigned char i2c_stop_and_read (void) // 发送停止信号并读,用于随机读的时序
{
unsigned char input_data;
BUS_STOP = TRUE; // 发送停止信号
while (!BUS_INT) // 等待发送完
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0; //SMBUS超时计数器清零
input_data = SMB0DAT; // 读数据
BUS_INT = 0; // 清中断标志
return input_data;
}
void i2c_write (unsigned char output_data) // 向总线上写一个字节
{
SMB0DAT = output_data; // 将要写的数据装入总线数据寄存器
while (!BUS_INT) // 判断数据是否发送出去
{
smbus_over_time_num++;
if(smbus_over_time_num>=5000){ //如果超时,则发送停止条件
BUS_INT=1;
BUS_STOP=1;
smbus_over_time_num=0;
}
}
smbus_over_time_num=0;
BUS_INT = 0; // 发送完将中断标志清零
}
void Write_Self_Flash(void)
{
unsigned char i,j,k;
unsigned char xdata *pwrite;
char SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=LEGACY_PAGE;
EA=0;
FLSCL=0x31;
PSCTL=0x07;
pwrite=0x10000;
*pwrite=0;
for(i=0;i<255;i++)
for(j=0;j<255;j++)
for(k=0;k<10;k++)
_nop_();
PSCTL=0x05;
for(i=0;i<72;i++)
*(pwrite+i)=MyBuff[i];
PSCTL=0;
FLSCL=0x30;
EA=1;
SFRPAGE=SFRPAGE_SAVE;
}
void Read_Self_Flash(void)
{
unsigned char i;
unsigned char code *pread;
char SFRPAGE_SAVE=SFRPAGE;
SFRPAGE=LEGACY_PAGE;
PSCTL=0x04;
pread=0;
for(i=0;i<72;i++)
MyBuff[i]=*(pread+i);
PSCTL=0;
SFRPAGE=SFRPAGE_SAVE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -