📄 at26df321.c
字号:
/************************************************************
FLASH操作底层函数
型号:AT26df321
Programmer: tian ye
*************************************************************/
#include <c8051f410.h>
#include "sys_config.h"
#define rd_array 0x03 //low_fre
#define erase_4k 0x20
#define erase_32K 0x52
#define erase_64K 0xd8
#define erase_chip 0x60
#define wr_byte_page 0x02
#define wr_en 0x06
#define wr_un 0x04
#define pro_sec 0x36
#define unpro_sec 0x39
#define rd_sec_pro_reg 0x3c
#define rd_state_reg 0x05
#define wr_state_reg 0x01
#define rd_id 0x9f
#define pwr_dwn 0xb9
#define un_pwr_dwn 0xab
#define TRUE 1
#define FALSE 0
//-----------------------------------------------------------------------------
// System_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the system clock to use the internal 24.5MHz / 4
// oscillator as its clock source and enables the missing clock detector reset.
// Additionally, this routine sets up VREF, the internal regulator, and the
// VDD monitor.
//
void System_Init (void)
{
OSCICN = 0x85; // configure internal oscillator打开内部24.5M振荡器并实行4分频
RSTSRC = 0x04; // enable missing clock detector.如果丢掉时钟将引起复位
REF0CN = 0x01; // set up and enable VREF pin 输出参考电压参考电压为1.5V
REG0CN = 0x10; // set up and enable 2.5V VDD from the 开启内部VDD电压产生电路并设置电压为2.5V
// internal regulator
VDDMon_Init (); // initialize the VDD Monitor
}
//-----------------------------------------------------------------------------
// VDDMon_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// This routine initializes the VDD Monitor and enables it as a reset source.
//
void VDDMon_Init (void)
{
char i;
VDM0CN = 0x80; // enable the VDD monitor 打开电压产生器
for (i = 0; i < 80; i++); // wait for the monitor to stabilize 延时等待初始化完毕(其实这些值都是内部默认的值,没有必要重值)
RSTSRC = 0x06; // enable missing clock detector and 允许时钟出错复位和电源出错复位
// VDD monitor as reset sources
}
//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// P0.0 = DAC0 (analog, skip)
// P0.1-3 = unused (skip)
// P0.4-7 = SPI interface (digital, do not skip)
// P1.0-1 = unused (skip)
// P1.2 = VREF (analog, skip)
// P1.3 = analog power-on transistor (digital, skip)
// P1.4 = unused (skip)
// P1.5 = ADC0 (analog, skip)
// P1.6-7 = REC_PLAY and ERASE switches (digital, skip)
// P2.0-1 = LED PCA outputs (digital, do not skip)
//
void Port_Init (void)
{
// P0MDIN = 0xFE; // make switch and SPI pins digital //选择P0口是作为数字输入还是作为模拟输入
// P0MDOUT = 0xD0; // make SPI pins push-pull //选择p0口是不是有上拉
// P1MDIN = 0xC8; // make trans and switches digital //选择P1口是作为数字输入还是作为模拟输入
// P1MDOUT = 0x08; // make trans pin push-pull //选择p1口是不是有上拉
// P2MDIN = 0x03; // make PCA pins digital
// P2MDOUT = 0x03; // make PCA pins push-pull //选择两个LED的驱动GPIO需要上拉.
// P0SKIP = 0x0F; // skip pins not belonging to SPI //跳跃引脚 1为跳跃第二功能,0为可选择第二功能
// P1SKIP = 0xFF; // skip all P1 pins
// P2SKIP = 0xFC; // skip pins not belonging to LED PCA //将PCA的两个引脚跳开
// P0MDIN = 0xFF;
P1MDOUT = 0xD0;
P0SKIP = 0xCF;
P1SKIP = 0x0F;
XBR0 = 0x03;
XBR1 = 0x40;
// XBR0 = 0x02; // enable SPI //将SPI的信号线连接在IO上
// XBR1 = 0x42; // enable PCA0_0 and PCA0_1 //使能跳接开关并将CEX0,CEX1连接在IO口上
// TRANS = 0; // turn on the power to all analog //
// components
// P0MAT = 0x00; // the buttons will go low when pressed, //设置引脚中断功能
// P1MAT = 0xC0; // causing the port match event
// P0MASK = 0x00; // mask off all P0 and P1 pins except
// P1MASK = 0xC0; // the switches
EIE2 = 0x00; // disable the port match interrupt
// (not required to wake up the core)
}
//-----------------------------------------------------------------------------
// SPI0_Init
//-----------------------------------------------------------------------------
//
// Return Value : None
// Parameters : None
//
// Configure the SPI to run in 4-wire master mode at SYSCLK / 4 (1.53 MHz)
// using clock phase 0 and clock polarity 0 to interface with the SST Flash
// memory.
//
void SPI0_Init (void)
{
SPI0CFG = 0x40; // set the master mode, polarity and
// phase
// set the SPI frequency to SYSCLK / 2*(1+1) = SYSCLK / 4
SPI0CKR = 0x01;
SPI0CN = 0x0C; // clear flags, turn off NSS
// set the 4-wire mode
SPIEN = 1; // enable the SPI
}
/*******************************************************************************
函数名:read_flash_id()
函数功能:
********************************************************************************/
void read_flash_id(void)
{
unsigned char i, flash_id[4];
NSSMD0 = 0; // 使能片选
SPI0DAT = rd_id; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
for(i=0;i<4;i++)
{
SPI0DAT = 0xFF; //装入0Xff,其实就是送时钟读数据
while (TXBMT != 1); //确认当前发的是这个字节
SPIF = 0;
while (SPIF != 1); // 等待当前字节发送完毕
// SPIF = 0;
flash_id[i]=SPI0DAT; //读取数据
}
NSSMD0 = 1; // 退出操作
}
/*******************************************************************************
函数名:read_flash_id()
函数功能:
********************************************************************************/
unsigned char read_state_reg(void)
{
NSSMD0 = 0; // 使能片选
SPI0DAT = rd_state_reg; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPI0DAT = 0xFF; //装入0Xff,其实就是送时钟读数据
while (TXBMT != 1); // 确认当前发送的是该字节
SPIF = 0;
while (SPIF != 1); // 等待当前字节发送完
NSSMD0 = 1; // 退出操作
return SPI0DAT; //返回数据
}
/*******************************************************************************
函数名:
函数功能:
********************************************************************************/
void pro_all_sec(bit pro_mode)
{
NSSMD0 = 0; // 使能片选
SPI0DAT = wr_state_reg; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
if(pro_mode)
SPI0DAT = 0x7f;
else
SPI0DAT = 0x00;
while (TXBMT != 1); // 确认当前发送的是该字节
SPIF = 0;
while (SPIF != 1); // 等待当前字节发送完
NSSMD0 = 1; // 退出操作
}
/*******************************************************************************
函数名:
函数功能:
********************************************************************************/
void flash_wr_en(bit en_mode)
{
NSSMD0 = 0; // 使能片选
if(en_mode)
SPI0DAT = wr_en; // 将数据装入
else
SPI0DAT = wr_un; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPIF = 0;
while (SPIF != 1); // 等待当前字节发送完
NSSMD0 = 1; // 退出操作
}
/*******************************************************************************
函数名:
函数功能:
********************************************************************************/
unsigned char read_pro_sec_state(void)
{
NSSMD0 = 0; // 使能片选
SPI0DAT = rd_sec_pro_reg; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPI0DAT = 0x00; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPI0DAT = 0x00; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPI0DAT = 0x00; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPI0DAT = 0xff; // 将数据装入
while (TXBMT != 1); //检查是否可以装入数据
SPIF = 0;
while (SPIF != 1); // 等待当前字节发送完
NSSMD0 = 1; // 退出操作
return SPI0DAT;
}
/*******************************************************************************
函数名:
函数功能:
********************************************************************************/
void un_pro_sig_sec(void)
{
NSSMD0 = 0;// // 使能片选
SPI0DAT = unpro_sec;// // 将数据装入
while (TXBMT != 1);// //检查是否可以装入数据
SPI0DAT = 0x00;// // 将数据装入
while (TXBMT != 1);// //检查是否可以装入数据
SPI0DAT = 0x00;// // 将数据装入
while (TXBMT != 1);// //检查是否可以装入数据
SPI0DAT = 0x00;// // 将数据装入
while (TXBMT != 1);// //检查是否可以装入数据
SPIF = 0;//
while (SPIF != 1);// // 等待当前字节发送完
NSSMD0 = 1; // // 退出操作
}
/*******************************************************************************
函数名:
函数功能:
********************************************************************************/
void main()
{
unsigned char i,m;
System_Init(); //初始化内部时钟复位和核心电压
Port_Init(); //将IO管脚按系统需要进行配置
SPI0_Init(); //初始化SPI模块
read_flash_id();
i=read_state_reg();
while(1)
{
flash_wr_en(TRUE);
//i=read_state_reg();
pro_all_sec(TRUE);
i=read_state_reg();
// m=read_pro_sec_state();
flash_wr_en(TRUE);
//i=read_state_reg();
pro_all_sec(FALSE);
i=read_state_reg();//
flash_wr_en(TRUE); //
// i=read_state_reg();
un_pro_sig_sec();//
m=read_pro_sec_state();//
i=read_state_reg();
m++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -