单片机控制带SPI的EEPROM

用AT89C51的I/O口模拟SPI控制25AA040

 

按一下按键数码管加1,断电重启后数字依然存在。

 

spi.c:

#include
#include
#include "main.h"
             
sbit SCK=P2^4;
sbit SDO=P2^5;
sbit SDI=P2^6;
sbit CS =P2^7;
             
#define READ  0x03
#define WRITE 0x02
#define WREN  0x06
#define WRDI  0x04
#define RDSR  0x05
#define WRSR  0x01
             
void delay(void)
{
    _nop_();_nop_();
    _nop_();_nop_();
}
             
void init_SPI(void)
{
    CS=1;
    delay();
    SCK=1;
    delay();
    SDO=1;
    delay();
    SDI=1;
    delay();
}
             
uchar SPI_read_byte(void)
{
    uchar i;
    uchar dat=0x00;
    SCK=0;
    for(i=0;i<8;i++)
    {
        SCK=0;
        delay();
        SCK=1;
        delay();
        dat <<= 1;
        dat |= (uchar)SDI;
    }
    return(dat);
}
             
void SPI_write_byte(uchar dat)
{
    uchar i;
    SCK=0;
    for(i=0;i<8;i++)
    {
        SDO= (bit)(dat&0x80);
        SCK=0;
        delay();
        SCK=1;
        delay();
        dat<<=1;
    }
}
             
void write_SPI(uchar dat,uchar addr)
{
    SCK=0;
    CS=0;
    delay();
    SPI_write_byte(WREN);
    CS=1;
    delay();
    CS=0;
    delay();
    SPI_write_byte(WRITE);
    SPI_write_byte(addr);
    SPI_write_byte(dat);
    CS=1;
    SCK=0;
}
             
uchar read_SPI(uchar addr)
{
    uchar dat;
    SCK=0;
    delay();
    CS=0;
    delay();
    SPI_write_byte(READ);
    SPI_write_byte(addr);
    dat=SPI_read_byte();
    CS=1;
    delay();
    SCK=0;
    delay();
    return dat;
}
             
void write_SPI_SR(uchar sReg)
{
    CS=0;
    delay();
    SPI_write_byte(WREN);
    CS=1;
    delay();
    CS=0;
    delay();
    SPI_write_byte(WRSR);
    SPI_write_byte(sReg);
    CS=1;
    delay();
}
             
uchar read_SPI_SR(void)
{
    uchar sReg=0;
    CS=0;
    delay();
    SPI_write_byte(RDSR);
    sReg=SPI_read_byte();
    CS=1;
    delay();
    return sReg;
}

 

delay.c:

/*****************************************************************************
* 文件名:delay.c
* 说  明:延时函数
*****************************************************************************/
#include "main.h"
            
/******************************************************
* 函数:延时timer毫秒(单片机:AT89C51、晶振频率:12MHz)
* 参数:timer要延时的毫秒数值
*******************************************************/
void delay_ms(uint timer)
{
    uchar j = 0;
    while(timer--)
    {
        for(j = 124; j>0; j--)
        {
        ;
    }
    }
}

 

delay.h:

/*******************************************************
* 文件名:delay.h
********************************************************/
#ifndef _DELAY_H
#define _EDLAY_H
           
void delay_ms(unsigned int timer);
           
#endif

 

main.h:

/*******************************************************
* 文件名:main.h
********************************************************/
#ifndef _MAIN_H
#define _MAIN_H
         
#define uint    unsigned int 
#define uchar   unsigned char 
         
#endif

 

spi.h:

#ifndef _SPI_H
#define _SPI_H
        
#include "main.h"
        
void init_SPI(void);
uchar read_SPI_SR(void);
void write_SPI_SR(uchar rs);
uchar read_SPI(uchar addr);
void write_SPI(uchar dat,uchar addr);
#endif

 

main.c:

#include 
#include "main.h"
#include "delay.h"
#include "spi.h"
       
sbit LED1=P2^0;
sbit LED2=P2^1;
       
#define DAT_ADDR 0x03
       
uchar g_ucDat;
       
void display(uchar dat)
{
    LED1=0;
    LED2=1;
    P0=(dat%10);
    delay_ms(1);
    LED2=0;LED1=1;
    P0=(dat/10);
    delay_ms(1);
}
       
void int0_init(void)
{
    EX0=1;
    IT0=1;
    EA=1;
}
       
void int0_inter() interrupt 0
{
    g_ucDat ++;
}
       
void main(void)
{
    uchar tmp=0;
    g_ucDat=0;
    int0_init();
    init_SPI();
       
    write_SPI_SR(0x00);
    delay_ms(10);
    tmp=read_SPI_SR();
       
    tmp=read_SPI(DAT_ADDR);
    if(tmp == 0xFF)
    {
        tmp=0;
        write_SPI(tmp,DAT_ADDR);
        delay_ms(10);
    }
    g_ucDat =tmp;
       
    while(1)
    {
        if (tmp != g_ucDat)
        {
            if(g_ucDat > 99)
            {
                g_ucDat=1;
            }
            tmp=g_ucDat;
            write_SPI(tmp,DAT_ADDR);
            delay_ms(10);
        }
       
        display(tmp);
    }
}

单片机控制带SPI的EEPROM》上有1条评论

  1. Pingback引用通告: BZ编程小组 作品 | BZ编程小组

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.