查看: 1046|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
沙发
发表于 2016-4-1 18:16:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主控芯片是PIC16F877A,   EEPROM芯片是25AA1024,  编程平台是MPLAB IDE V8.60,  测试平台是 Proteus V7.5
大家如果有更好的方法或理解,请一起踊跃讨论

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


仿真电路图 (原文件名Q截图未命名.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);
        }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表