// 移植了别人的程序,如果你也需要那么可以学习,此代码不保证可靠。只是方便学习和测试用的。
// 测试铁电的平台,// 2010 0130 测试日期;
#include <pic18.h>
#include <pic18f4520.h>
#define _nop_() ; //asm("nop") // 延时一个CLK;
#define _NOP() ; //asm("nop")
//------ 管脚定义-----------
//sbit P20 = P2^0; //线引脚
//sbit P21 = P2^1; //线引脚
//sbit P22 = P2^2; //线引脚
//sbit P23 = P2^3; //线引脚
//#define FM25CL64_SI P20 //p2.4为数据输入口 向 FM25CL64 写数据字节(一个字节) MO_SI 单片机输出;
//#define FM25CL64_SO P21 //芯片的数据输出口, 单片机读 MiSo // M25CL64_SO FM25CL64 读数据字节(一个字节)
//
//#define FM25CL64_SCK P22 //p2.6时钟信号
//#define FM25CL64_CS P23 //p2.3片选信号 FM25CL64_SI FM25CL64_SO FM25CL64_CS FM25CL64_SCK
//
//修改的数据接口; ------------- 硬件模拟的SPI,排列
#define DirSpiCS TRISC2 // RA1 //1写数据,0写指令
#define DirSpiMDoSi TRISC4 // MO SI RC4 ==0
#define DirSpiMdiSo TRISC5 // Mi SO RC5 ==1
#define DirSpiclk TRISC3 // clk
//修改的数据接口---硬件模拟的SPI,排列
#define FM25CL64_CS RC2 //1写数据,0写指令
#define FM25CL64_SI RC4 //MO SI RC4 20091030 cc
#define FM25CL64_SO RC5 //Mi SO RC5
#define FM25CL64_SCK RC3 //clk
///////////////////// *SI 可连接到SO,用作一个单管脚的数据接口 ////////////////////////////
// /HolD ? ==1,VCC 时候无效, 可以读写控制;
// /WP 在发布WRSR 指令之前,/WP 管脚必须为高电平状态或者无效状态。
//保持:当主CPU 必须中断存储器当前的操作而执行另一个任务时,/HOLD
//管脚被使用。当/HOLD 管脚为低电平时,当前操作被挂起。器件忽略SCK
//或者/CS 上的任何跳变。/HOLD 管脚的所有跳变必须发生在SCK 为低电
//平的时间
//////////////////////// 以上是 我添加的函数 定义 ///////////////////////
unsigned char temp[16];
unsigned char tempw[16]={
0x55,0x56,0x57,0x58,0x59,0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x70 };
volatile unsigned char tempr[16];
volatile unsigned char temp1[16];
// volatile unsigned char numtime[16]; //读回来的地址;
//
unsigned char tempa;
unsigned int number;
unsigned char numtime;
unsigned char bbyte;
// ---------------------------函数声明---------------------------
//如果子函数定义在main函数之后,则子函数必须声明。
//如果main函数在子函数后面,则该子函数可以不申明
//此例子中,delay函数定义出现在main的后方,所以一定要先申请,让编译器先
//识别delay是在后方定义的,否则会报错,大家可以分两种方式试一下
//1)把声明屏蔽掉 2)把delay的定义称到main的前面
void delay (unsigned int);
//延时子程序
//函数申明时,可以省略形参名称,即只带形参类型,如上。具体请参照C语言的教程。
//1
//铁电存储器FM25CL64 的C51 编程
//作者:刘健永
//Email:ts_jianyong@tom.com
//铁电存储器 FM25CL64 寄存器定义
#define FM25CL64_WREN_INST 0x06 // 写使能 //WREN 设置写使能锁存器0000 0110b
#define FM25CL64_WRDI_INST 0x04 // WRDI 写禁止0000 0100b
#define FM25CL64_RDSR_INST 0x05 // 读状态寄存器子程序(FM25CL64)//RDSR 读状态寄存器0000 0101b
#define FM25CL64_WRSR_INST 0x01 // WRSR 写状态寄存器0000 0001b WL="1"
#define FM25CL64_WRITE_INST 0x02 //WRITE 写存储器数据0000 0010b
#define FM25CL64_READ_INST 0x03 //READ 读存储器数据0000 0011b
#define FM25CL64_STATUS_REG 0x0 // FM25CL64_WRSR_INST 表 2 状态寄存器 ,写入00 //取消写保护
// #define FM25CL64_INIT_STATE 0x09 // ??
//状态寄存器&写保护
//FM25CL64 的写保护特性是多样的。第一,WREN 操作码必须在进行任何写操作之前
// WEL=1 表示进行写操作是允许的
//表 2 状态寄存器
//位 7 6 5 4 3 2 1 0
//名称 WPEN 0 0 0 BP1 BP0 WEL 0
// ^^ ^^
// || ||
// SPI 模式3:CPOL=1,CPHA=1 ?
///////////////////////////////////////////////////////////////////////////////////////////////
// TRISC3=0; //c.3sclk SCK引脚为输
// TRISC4=1; //c4 in
// TRISC5=0; //c.5dou //SDO
// TRISC2=0; //AT_CS
void Moni_SPIinint(void )
{
TRISC2 = 0; //AT_CS
TRISC3 = 0; //c.3sclk SCK 引脚为输
TRISC4 = 0; //DA c4 in
TRISC5 = 1; //DIN c.5dou //SDO
} //
//6.3.命令结构
//有 6 种称为操作码的指令,它们由总线主控器发布给FM25CL64。下表列出了这几种
//指令。这些操作码控制了存储器执行的功能。它们可以分为三类。第一类是无并发操作的
//指令。它们执行单一的功能,例如使能写操作。第二类是带一个字节的指令,写入或者读
//出。它们对状态寄存器进行操作。第三类包括了执行存储器操作的命令,这些命令后面跟
//随有地址和一个或更多数据字节。
// 1M25CL64_SO FM25CL64 读数据字节(一个字节)
unsigned char In_FM25CL64_Byte()
{
unsigned char Datain="0",i;
// SPI,读写的引脚 与方向设定
// DirSpiclk = 0;
// DirSpiCS = 0; // AT_CS =0
// DirSpiMDoSi = 0;
// DirSpiMdiSo = 1; //芯片端的方向,由MDI决定;
//
for(i=0;i<8;i++){
FM25CL64_SCK=0;
_nop_();
_nop_();
_nop_();
FM25CL64_SCK=1;
//////////////////////////////////////////////////////
Datain=Datain<<1;//
if( FM25CL64_SO ) Datain|=0x01; //
//////////////////////////////////////////////////////////
// Datain = Datain<< 1; // 先移位,一格,再读取数据;
// Datain |= FM25CL64_SO; // SPIdin 对应从机的SO
// SO; //Mi
//
}
return(Datain);
}//
//2
//if (adata &0x80 ) {
//
//SPIdo = 1;
//}
//
////对应从机的SI
//
//else{
//
//SPIdo = 0;
//}
//adata <<= 1;
//
// 2.向 FM25CL64 写数据字节(一个字节)
void Out_FM25CL64_Byte( unsigned char byte)
{
unsigned char i="0";
//DirSpiMDoSi = 0; //out
//DirSpiMdiSo = 1; //芯片端的方向,由MDI决定;
for(i=0;i<8;i++){
FM25CL64_SCK=0;
_nop_();
_nop_();
_nop_();
// 高位先移出去;
FM25CL64_SI= (bit)(byte&0x80);
//if( byte&0x80==0x80 ){ //
//FM25CL64_SI=1; //mo
//}//
//else {
//FM25CL64_SI=0;}//
byte<<=1;
FM25CL64_SCK=1;
//////////////////////////////////////////////
}//
FM25CL64_SCK=0;
FM25CL64_SI=0;
return ;
}//
//读状态寄存器子程序(FM25CL64) 3.
unsigned char ReadState()
{
unsigned char r;
FM25CL64_SCK=0;
FM25CL64_CS=0;
Out_FM25CL64_Byte(FM25CL64_RDSR_INST);
_nop_();
_nop_();
_nop_();
r=In_FM25CL64_Byte();
FM25CL64_SCK=0;
_nop_();
_nop_();
_nop_();
FM25CL64_CS=1;
return(r);
}//
// 4.检测读状态 铁电很快,就不用等了;
void wip_poll() // 4.检测读状态
{
unsigned char i="0",r;
r=ReadState();
/*
do{
//3
r=ReadState();
i++;
}
while((r&0x01)&&i<0x99);
*/
}//
//5.写使能
void WriteEnable()
{
FM25CL64_SCK=0;
FM25CL64_CS=0;
Out_FM25CL64_Byte(FM25CL64_WREN_INST);
FM25CL64_SCK=0;
FM25CL64_CS=1;
return;
}
// wrsr_cmd(0x00); WriteState( FM25CL64_STATUS_REG); //取消写保护
// 6.写状态寄存器子程序 FM25CL64_STATUS_REG 00
void WriteState( unsigned char status)
{
WriteEnable();
FM25CL64_SCK=0;
FM25CL64_CS=0;
Out_FM25CL64_Byte(FM25CL64_WRSR_INST); // 6.写状态寄存器子程序
Out_FM25CL64_Byte( status ); // FM25CL64_STATUS_REG 表 2 状态寄存器
FM25CL64_SCK=0;
FM25CL64_CS=1;
wip_poll();
}
// wrsr_cmd(0x00); //取消写保护
//void wrsr_cmd(uchar status) //写状态寄存器
//{
// wren_cmd();
// CLK_0;
// CSX_0;
// outbyt(WRSR_INST);
// outbyt(status);
// CLK_0;
// CSX_1;
//}
//读多字节数据 MSP程序;
//void read_seq(uint Address,uchar *ptr,uchar num)
//{
// uchar i;
// uchar temp;
// temp=(uchar)Address;
// CLK_0;CSX_0;
// outbyt(READ_INST);
// outbyt((uchar)(Address>>8));
// outbyt((uchar)Address);
// for(i=0;i<num;i++)
// {
// *(ptr+i)=inputbyt();
// }
// CLK_0;CSX_1;
//} //
// 7.读存储单元内容子程序
unsigned char Read_FM25CL64_Byte( unsigned int address)
{
unsigned char dat;
FM25CL64_SCK=0;
FM25CL64_CS=0;
_nop_();
Out_FM25CL64_Byte(FM25CL64_READ_INST);
_nop_();
_nop_();
Out_FM25CL64_Byte((address&0xff00)>>8);
_nop_();
//4
_nop_();
Out_FM25CL64_Byte(address&0x00ff);
_nop_();
_nop_();
dat=In_FM25CL64_Byte();
FM25CL64_SCK=0;
FM25CL64_CS=1;
return(dat);
}//
// 8.读存储单元内容子程序(多字节) C51
void Read_FM25CL64_nByte(unsigned int address,
unsigned char *dat,unsigned char number)
{
unsigned char i;
FM25CL64_SCK=0;
FM25CL64_CS=0;
_nop_();
Out_FM25CL64_Byte(FM25CL64_READ_INST);
_nop_();
_nop_();
Out_FM25CL64_Byte((address&0xff00)>>8);
_nop_();
_nop_();
Out_FM25CL64_Byte(address&0x00ff);
_nop_();
_nop_();
for(i=0;i<number;i++){
*(dat+i)=In_FM25CL64_Byte();
}
FM25CL64_SCK=0;
FM25CL64_CS=1;
return;
}
// 9.写存储单元内容子程序(单字节)
void Write_FM25CL64_Byte(unsigned int address,unsigned char dat)
{
WriteEnable();
FM25CL64_SCK=0;
FM25CL64_CS=0;
// 5
Out_FM25CL64_Byte(FM25CL64_WRITE_INST);
_nop_();
_nop_();
Out_FM25CL64_Byte((address&0xff00)>>8);
_nop_();
_nop_();
Out_FM25CL64_Byte(address&0x00ff);
_nop_();
_nop_();
Out_FM25CL64_Byte(dat);
FM25CL64_SCK=0;
FM25CL64_CS=1;
wip_poll(); // 4.检测读状态
return;
}//
////////////////////////////////////////////////////////////////////////////////////////
// 10.写存储单元内容子程序(多字节)
void Write_FM25CL64_nByte(unsigned int address,
unsigned char *dat,unsigned char number)
{
unsigned char i;
WriteEnable();
FM25CL64_SCK=0;
FM25CL64_CS=0;
Out_FM25CL64_Byte(FM25CL64_WRITE_INST);
_nop_();
_nop_();
Out_FM25CL64_Byte((address&0xff00)>>8);
_nop_();
_nop_();
Out_FM25CL64_Byte(address&0x00ff);
_nop_();
_nop_();
for(i=0;i<number;i++){
Out_FM25CL64_Byte(*(dat+i));
}
FM25CL64_SCK=0;
FM25CL64_CS=1;
wip_poll();
return;
}//
//----------------------------全局变量定义----------------------------------
// ---------------------------主函数-----------------------------------
void main(void)
{
unsigned int i="0";
unsigned char number[16]={
0x1,0x2,0x3,0x4,0x5,0x6,0x7,0x8,0x9,0xa,
0xb,0xc,0xd,0xe,0xf,0x55
};// //
// WDTCTL="WDTPW"+WDTHOLD;
// P2DIR|=BIT3+BIT5+BIT6; //设置P2.3 P2.5 P2.6为输出
// P2DIR&=~BIT4; //设置为P2.4输入
// wrsr_cmd(0x00); //取消写保护
DirSpiCS = 0; //SPI,读写的引脚 与方向设定
DirSpiclk = 0;
DirSpiMDoSi = 0;
DirSpiMdiSo = 1; //芯片端的方向,由MDI决定;
FM25CL64_SI=0;
FM25CL64_SO=0;
FM25CL64_CS=0;
FM25CL64_SCK=0;
FM25CL64_SI=1;
FM25CL64_SO=1;
FM25CL64_CS=1;
FM25CL64_SCK=1;
FM25CL64_SI=0;
FM25CL64_SO=0;
FM25CL64_CS=0;
FM25CL64_SCK=0;
FM25CL64_SI=1;
FM25CL64_SO=1;
FM25CL64_CS=1;
FM25CL64_SCK=1;
WriteState( FM25CL64_STATUS_REG); // 取消写保护
WriteEnable(); // // wren_cmd(); //设置为写
while(1){;
FM25CL64_SI=1;
FM25CL64_SO=1;
FM25CL64_CS=1;
FM25CL64_SCK=1;
for(i=0;i<16;i++) { //从地址0开始写16个数 测试单字节写
Write_FM25CL64_Byte( i, 5);//number byte_write(i,number);
}
_NOP();
_NOP();
for(i=0;i<15;i++) //从地址0开始读16个数 测试单字节读
{
temp1=Read_FM25CL64_Byte(i);
// = numtime;numtime
}//
_NOP();
_NOP();
}//
/*
write_seq(31000,tempw,16); //从地址31000开始写16个数 测试多字节写
_NOP();
_NOP();
read_seq(31000,tempr,16); //从地址31000开始读16个数 测试多字节读
_NOP();
_NOP();
}
*/
} //main
//-----------------------延时程序---------------------------------------
void delay (unsigned int i)
{
while(i--)
;
}
//--------------------------------------------------------------
//---------------------------------------------------------------------------
文章评论(0条评论)
登录后参与讨论