搜索
bottom↓
回复: 10

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

[复制链接]

出0入0汤圆

发表于 2011-10-27 21:21:35 | 显示全部楼层 |阅读模式
主控芯片是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);
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2011-10-27 21:51:48 | 显示全部楼层
是给大家学习的吗?

出0入0汤圆

 楼主| 发表于 2011-10-27 21:58:18 | 显示全部楼层
是分享! 也希望大家一起深入讨论!

出0入0汤圆

发表于 2013-3-2 11:32:18 | 显示全部楼层
刚刚我用的上

出0入0汤圆

发表于 2013-3-2 15:19:05 | 显示全部楼层
如果用CCS编译器,可以直接单指令读写。

出0入0汤圆

发表于 2013-3-2 17:03:51 | 显示全部楼层
求教   推荐PIC单片机的C编译平台和烧写平台,什么软件比较好用啊!我是新手啊

出0入0汤圆

发表于 2013-4-17 09:35:49 | 显示全部楼层
下来研修一下,谢谢。

出0入4汤圆

发表于 2013-6-24 16:04:33 | 显示全部楼层
试用了下楼主的代码,移植过来  发现一个小问题。就是写入一个字节的话没问题。但是连续写入就会出错 。不知道怎么搞。

出0入0汤圆

发表于 2017-6-28 10:54:16 | 显示全部楼层
解释做的很好 学习

出0入0汤圆

发表于 2017-6-29 13:56:34 | 显示全部楼层
标记下,估计用的到,谢谢

出0入0汤圆

发表于 2017-7-19 21:02:44 | 显示全部楼层
先收藏,待闲时学习,谢谢楼主!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 22:55

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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