基于PIC16F877A的SPI读写外部EEPROM芯片 (25AA1024)

2020-02-06 09:56发布

主控芯片是PIC16F877A,   EEPROM芯片是25AA1024,  编程平台是MPLAB IDE V8.60,  测试平台是 Proteus V7.5
大家如果有更好的方法或理解,请一起踊跃讨论

程序工程文件ourdev_689287FRFXR5.rar(文件大小:89K) (原文件名:PIC SPI.rar)


仿真电路图 (原文件名:QQ截图未命名.png)

程序代码:

#include<pic.h>
#include<stdio.h>
__CONFIG(XT&WDTDIS&LVPDIS);

typedef  unsigned int uint;
typedef unsigned char uchar;

#define CS_Eeprom RA5

//重要事项: 1. 在电路中SPI的几个引脚必须接上上拉电阻
//           2. 如果是连器件的话, 必须是 SI接SO ,  SO接SI , SCK接SCK , CS接CS      
void delay_ms(uint n)
{
        uchar i;
        while(n--)
        {
                for(i=0;i<150;i++)
                {}
        }
}

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

void SSP_Send(uchar sByte)
{
        SSPBUF = sByte;
        while(BF==0);
}

void write_DataToEeprom(unsigned long wAddr, uchar wData)
{
        CS_Eeprom = 0;
        SSP_Send(0x06);  //写使能指令
        CS_Eeprom = 1;   //这步必须要有,否则上面的写使能指令将无效
        CS_Eeprom = 0;   //下面还要操作的话, 记得这一步
        SSP_Send(0x02);  //写读数据指令
        SSP_Send(0x00);  //(uchar)((wAddr&0x00ff0000)>>16);
        SSP_Send(0x00);  //(uchar)((wAddr&0x0000ff00)>>8);
        SSP_Send(0x55);  //(uchar)(wAddr&0x000000ff);
        SSP_Send(0x66);  // wData
        SSP_Send(0x88);  // wData  写在下一个地址
        delay_ms(20);  //这个延时必须要  
        CS_Eeprom = 1;
}

uchar read_DataFromEeprom(unsigned long rAddr)
{
        uchar rData =0;
        CS_Eeprom = 0;
        SSP_Send(0x03);        //读数据指令
        SSP_Send(0x00);        //(uchar)((rAddr&0x00ff0000)>>16);
        SSP_Send(0x00);        //(uchar)((rAddr&0x0000ff00)>>8);
        SSP_Send(0x55); //(uchar)(rAddr&0x000000ff);
        SSP_Send(0xFF); //这个步骤必须要
        delay(1);       //这个延时的时间可以很少,但必须要有
        rData = SSPBUF; //这一步可以在CS = 1之前,也可以在之后
        CS_Eeprom = 1;
        //rData = SSPBUF;
        //PORTD = rData;
        return rData;
}

void main()
{
        unsigned long addr=0x00000055;
        uchar rData=0;
        TRISD = 0x00;
        TRISC = 0x10;
        TRISA = 0x00;
       
       
        CKP = 0;    //1: 时钟高电平为空闲状态
                                //0: 时钟低电平为空闲状态
        CKE = 1;    //1:当时钟从有效状态变为空闲状态时开始发送
                            //0:当时钟从空闲状态变为有效状态时开始发送
       
        SSPM3 =0 ;SSPM2 =0 ;SSPM1 =0 ;SSPM0 =0 ;
        /*0000:时钟 = FOSC/4       
          0001:时钟 = FOSC/16
          0010:时钟 = FOSC/64
          0011:时钟 = TMR2输出/2
        */
        SMP =0;            //1:在数据输出时间的末尾采样输入数据
                                //0:在数据输出时间的中间采样输入数据

        SSPEN = 1;  //使能端口
       
        PORTD = 0X00;;
        write_DataToEeprom(addr, 0x88);       

        while(1)
        {
                PORTD = rData;
                       
                delay_ms(500);
                rData = read_DataFromEeprom(addr);
        }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
huarana
1楼-- · 2020-02-07 04:17
试用了下楼主的代码,移植过来  发现一个小问题。就是写入一个字节的话没问题。但是连续写入就会出错 。不知道怎么搞。
a515509429
2楼-- · 2020-02-07 06:53
解释做的很好 学习
ersha4877
3楼-- · 2020-02-07 08:25
 精彩回答 2  元偷偷看……
freeboyxd
4楼-- · 2020-02-07 14:04
先收藏,待闲时学习,谢谢楼主!

一周热门 更多>