huarana 发表于 2013-6-20 10:35:06

fm25040 和at25040一样吗

    at25040找不到中文资料 。所以就用fm25040来看。   

fm25040是非易失铁电存储器。at25040是不是也是一样的

绿茶山人 发表于 2013-6-20 10:44:18

FM是铁电的,AT好像就是普通的eeprom,铁电的好些也更贵,使用上应该差别不大。

huarana 发表于 2013-6-20 11:30:50

绿茶山人 发表于 2013-6-20 10:44 static/image/common/back.gif
FM是铁电的,AT好像就是普通的eeprom,铁电的好些也更贵,使用上应该差别不大。 ...

我主要的意思是问,操作起来是否一样的。也就是代码层面

绿茶山人 发表于 2013-6-20 14:06:22

huarana 发表于 2013-6-20 11:30 static/image/common/back.gif
我主要的意思是问,操作起来是否一样的。也就是代码层面

时序你得看数据手册了,也就是改改时序参数

陶新成 发表于 2017-3-6 11:01:41

我也在使用AT25040,你调通了吗

huarana 发表于 2017-3-6 11:14:33

陶新成 发表于 2017-3-6 11:01
我也在使用AT25040,你调通了吗

n年前的帖子了 - -

早就调通了。不复杂的。

陶新成 发表于 2017-3-6 11:25:33

huarana 发表于 2017-3-6 11:14
n年前的帖子了 - -

早就调通了。不复杂的。

我用时序模拟的收发,但是收到的数据总是0,

//   通过SPI发送数据                     
void data_sent(unsigned char data)
{
       unsigned char i=8;
   GPIO_ResetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
       while(i)
       {
                  if((data&0x80)>>7) GPIO_SetBits(GPIOA,GPIO_Pin_6);//SO
                        else GPIO_ResetBits(GPIOA,GPIO_Pin_6);//SO
                  data<<=1;
                  Delay_Us_SPI(2);//1M
                  GPIO_SetBits(GPIOA,GPIO_Pin_5);//SCK
                  Delay_Us_SPI(2);//1M
                  GPIO_ResetBits(GPIOA,GPIO_Pin_5);//SCK
                  i--;   
   }
}


//通过SPI接收数据
unsigned char data_receive(void)
{
   unsigned char i=8;
   unsigned char data=0;
   while(i)
   {
                  Delay_Us_SPI(2);//1M
                  GPIO_SetBits(GPIOA,GPIO_Pin_5);//SCK
               data<<=1;
                  if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_7)) data|0x01;
                  Delay_Us_SPI(2);//1M
                  GPIO_ResetBits(GPIOA,GPIO_Pin_5);//SCK
               i--;
   }
   return(data);
}


//写入操作   
void write(void)
{
   unsigned int x;
   //使能片外EEPROM
       GPIO_ResetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
   data_sent(0x06);
   delay();
       GPIO_SetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
   delay();

   //向片外EEPROM写入数据
       GPIO_ResetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
   data_sent(0x02);
   data_sent(0x00);
   for(x=0;x<5;x++)
    data_sent(datacun);   //连续写入5个字节
   delay();
       GPIO_SetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
}

// 读取操作
void read(void)
{
   unsigned int x;
   //由片外EEPROM读取数据
       GPIO_ResetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
   data_sent(0x03);
   data_sent(0x00);
   for(x=0;x<5;x++)
       {
      dataout = data_receive();
                  USART_Byte_Send(USART1,dataout);       
   }
       delay();
       GPIO_SetBits(GPIOA,GPIO_Pin_4);//CS低电平有效
}

陶新成 发表于 2017-3-6 11:30:56

你还有当初写的程序吗,能给我看一下吗

huarana 发表于 2017-3-6 12:53:09

陶新成 发表于 2017-3-6 11:30
你还有当初写的程序吗,能给我看一下吗

我用的硬件spi啊 - -
很多年前写的了比较菜 呵呵

/************************************************/
/* Update to TouchQin V1.0 by huarana        *********/       
/* MCU: PIC16LF1933                *************************/                       
/* 2013.6.24        *********************************/               
/* 功能: SPI测试,使用SPI读写AT25040                *********/
/************************************************/
/* TouchQin V1.0SPI测试程序,使用MSSP硬件SPI        */
/* 使用单片机PIC16LF1933         *********************/
/* 晶振:内部8M                *****************************/
/* 显示:LED                *********************************/
/* 编译环境 MPLAB IDE V8.85,PICC V9.83        *****/
/* 参考MicroChip官网16F1784_SPI_EEPROM        *********/
/* 时间:2013年6月24日        *************************/
/* QQ:xx                *****************************/
/************************************************/



#include<pic.h>
#include<pic16lf1933.h>
#include<stdio.h>



typedefunsigned int uint;
typedef       unsigned char uchar;


/*************************************************************************************/
/* 端口配置                                                                                                                                                        **/
/**************************************************************************************/

#define LED                                LATC                /*LED所在脚*/       
#define CS_Eeprom            LATC0                /*SPI SS脚*/
#define SPI_WP                        LATA6                /*SPI WP脚*/

/*   PIC16LF1933   */
__CONFIG(FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF);
__CONFIG(WRT_OFF & PLLEN_OFF & STVREN_ON & BORV_LO & LVP_OFF);
       

/*************************************************************************************/
/* 系统初始化                                                                                                                                                **/
/**************************************************************************************/
void SPI_init(void)
                        {
                                OSCCON= 0b01110000;        /*8M内部震荡*/
                        //        OSCCON= 0b01101000;        /*4M内部震荡*/
                                TRISA=0XBF;
                                TRISC=0x10;
                                TRISB=0X00;
                                ANSELA=0X00;
                                ANSELB=0x00;
                                LATB=0X00;
                                LATC0=1;
                                LATA6=1;
                                CKP = 0;    //1: 时钟高电平为空闲状态
                                                        //0: 时钟低电平为空闲状态
                                CKE = 1;    //1:当时钟从有效状态变为空闲状态时开始发送
                                                    //0:当时钟从空闲状态变为有效状态时开始发送
       
                                SSPM3 =0;        /*        0000:时钟 = FOSC/4                */       
                                SSPM2 =0;        /*        0001:时钟 = FOSC/16                */
                                SSPM1 =0;        /*        0010:时钟 = FOSC/64                */
                                SSPM0 =0;        /*        0011:时钟 = TMR2输出/2        */                       
                                                       
                                SMP =0;          //1:在数据输出时间的末尾采样输入数据
                                                        //0:在数据输出时间的中间采样输入数据
                       
                                SSPEN = 1;//使能端口
                        }
/*************************************************************************************/
/* ms延时                                                                                                                                                        **/
/**************************************************************************************/
void delay_ms(uint n)
                        {
                                uchar i;
                                while(n--)
                                        {
                                                for(i=0;i<150;i++);
                               
                                        }
                        }


/*************************************************************************************/
/* us延时                                                                                                                                                        **/
/**************************************************************************************/

void delay(uint m)
                        {
                                while(m--);
                        }

/*************************************************************************************/
/* Send one byte to SEE                                                                                                                                **/
/**************************************************************************************/
void SSP_Send(uchar sByte)
                        {
                                SSPBUF = sByte;
                                while(BF==0);
                               
                        }

/**************************************************************************************/
/* Read one byte from EEPROM                                                                                                                ***/
/**************************************************************************************/
uchar ReadSPI(void)
                        {
                          uchar databyte;
                       
                          SSPIF=0;                  // Clear SSP interrupt bit
                       //        SSPBUF = 0x00;      // Write dummy data byte to the buffer to initiate transmission
                          while(!BF);           // Wait for interrupt flag to go high indicating transmission is complete
                          databyte = SSPBUF;// Read the incoming data byte
                          return (databyte);
                        }

/*************************************************************************************/
/* Read the Status Register from the EEPROM                                                                                        **/
/**************************************************************************************/
uchar Read_SPI_StatusReg(void)
                        {
                          uchar data_read;
                          CS_Eeprom=0;
                          SSP_Send(0x05);         // Send read status register command
                          data_read = ReadSPI();// Read the data
                          CS_Eeprom=1;
                          return(data_read);
                        }

/*************************************************************************************/
/* 在指定地址写入数据.....                                                                                                                        **/
/**************************************************************************************/
void write_DataToEeprom(uchar wAddr,uchar wData)
                        {
                                uchar StatusReg;
                                CS_Eeprom = 0;
                                SSP_Send(0x06);        //写使能指令
                                CS_Eeprom = 1;           //这步必须要有,否则上面的写使能指令将无效
                                delay(20);                       //延时
                                CS_Eeprom = 0;           //
                                SSP_Send(0x02);        //写数据指令
                                SSP_Send(wAddr);        //
                                SSP_Send(wData);        // wData
                                delay_ms(20);                //
                                CS_Eeprom = 1;

                                do/* using polling method*/
                                  {
                                      StatusReg = (Read_SPI_StatusReg() & 0x01);           // Read the Status Register and mask out   
                                  }
                                while (StatusReg);                                           // the WIP bit (bit 0)

                       
                        }
/*************************************************************************************/
/* 读指定地址的数据.....                                                                                                                                **/
/**************************************************************************************/
uchar read_DataFromEeprom(uchar rAddr)
                        {
                                uchar rData =0;
                                CS_Eeprom = 0;       
                                SSP_Send(0x03);                //读数据指令
                                SSP_Send(rAddr);        //
                               SSP_Send(0xFF);         //
                                delay(500);               //这个延时的时间可以很少,但必须要有
                                CS_Eeprom = 1;
                                rData=ReadSPI();        //调用读取
                                return rData;
                        }
/*************************************************************************************/
/* 主函数.....                                                                                                                                                **/                                               
/**************************************************************************************/
void main(void)
                        {
                                uchar addr1=0x01,data1=0x7F;                        /*设定写入地址及数据*/
                                uchar addr2=0x02,data2=0xBF;
                                uchar addr3=0x03,data3=0xFE;
                                uchar rData1=0,rData2=0,rData3=0;
                                SPI_init();                                                                /*初始化SPI*/
                                write_DataToEeprom(addr1,data1);                /*指定地址写入*/
                                delay_ms(50);
                               write_DataToEeprom(addr2,data2);                /*指定地址写入*/
                                delay_ms(50);
                                write_DataToEeprom(addr3,data3);                /*指定地址写入*/
                                delay_ms(50);                                                                                                       
                                rData1 = read_DataFromEeprom(addr1);        /*读出指定地址的值*/
                                delay_ms(50);
                                rData2 = read_DataFromEeprom(addr2);        /*读出指定地址的值*/
                                delay_ms(50);
                                rData3 = read_DataFromEeprom(addr3);        /*读出指定地址的值*/
                                delay_ms(50);                                                        /*重新初始化LED所在的IO口*/
                                TRISC=0X00;                                                                /*因为LED所在口和SPI复用*/
                                LED=0XFF;                                                                /*关闭所有LED灯                        */
                                while(1)
                                        {
                                                  LED=rData3;                                        /*按规律点亮LED来指示写入读出数据的正确*/
                                                  delay_ms(500);                                /*可以通过修改初始data值来观察读写正确性*/
                                                  LED=rData2;
                                                  delay_ms(500);
                                                  LED=rData1;
                                                  delay_ms(500);
                                        }
                        }
页: [1]
查看完整版本: fm25040 和at25040一样吗