bluehacker

SPI接口的93c46程序

0
阅读(5993)


去年做了个51的开发板,下面是用其中的93c46 eeprom的程序,c51写的。贴在这里充数。
/************************************
** FileName:at93c46.h
***********************************/
#ifndef __LZP_AT93C46_H_
#define __LZP_AT93C46_H_
#include "reg52.h"
#include "intrins.h"

//定义操作命令
#define READ     0xc0
#define WRITE    0xa0
#define ERASE    0xe0
#define EWEN     0x98
#define EWDS     0x80
#define WRAL     0x88
#define ERAL     0x90
 
sbit AT93C46_CS=P3^7;
sbit SPI_CLK=P1^4;
sbit SPI_DI=P1^3;
sbit SPI_DO=P1^2;
void clock(void);
void spi_send(unsigned char dat,unsigned char num);
unsigned char spi_receive(void);
void enable_write(void);
void disable_write(void);
unsigned char at93c46_read(unsigned char addr);
void at93c46_erase(unsigned char addr);
void at93c46_write(unsigned char addr,unsigned char dat);
void at93c46_writeall(unsigned char dat);
void at93c46_eraseall(void);
void init_spi_93c46(void);
#endif
/*********************************************
** FileName:at93c46.c
*********************************************/
#include "at93c46.h"
//#include "delay.h"
//产生一个时钟周期
void clock(void)
{
    SPI_CLK=0;
    _nop_();
    SPI_CLK=1;
    //_nop_();
}
//输入一个字节的数据到at93c46
void spi_send(unsigned char dat,unsigned char num)
{
    unsigned char i;
    for(i=0;i<num;i++)
    {
        SPI_DI=(bit)(dat&0x80);
        dat<<=1;
        clock();
    }
}
//从AT93C46接受一个字节的数据
unsigned char spi_receive(void)
{
    unsigned char i;
    unsigned char tmp=0;
    SPI_DO=1;
    while(SPI_DO)
        clock();
    for(i=0;i<8;i++)
    {
        clock();
        tmp<<=1;
        if(SPI_DO)
            tmp++;
    }
    clock();
    return tmp;
}
//读保存在at93c46存储器中地址为addr处的数据
unsigned char at93c46_read(unsigned char addr)
{
    unsigned char tmp;
//    enable_write();
    AT93C46_CS=0;
    addr<<=1;
    AT93C46_CS=1;
   
    spi_send(READ,3);
    spi_send(addr,7);
    tmp=spi_receive();
    AT93C46_CS=0;
//    disable_write();
    return tmp;
}
//使能写/删除操作
void enable_write(void)
{
    AT93C46_CS=0;
    SPI_CLK=0;
  
    AT93C46_CS=1;
    spi_send(EWEN,5);
    spi_send(0,5);
    AT93C46_CS=0;
}
//禁止写/删除操作
void disable_write(void)
{
    AT93C46_CS=0;
    SPI_CLK=0;
    AT93C46_CS=1;
    spi_send(EWDS,5);
    spi_send(0,5);
    AT93C46_CS=0;
}
//擦除地址为addr的存储单元
void at93c46_erase(unsigned char addr)
{
    enable_write();
    AT93C46_CS=0;
    SPI_DO=1;
    AT93C46_CS=1;
   
    addr<<=1;
    spi_send(ERASE,3);
    spi_send(addr,7);
    AT93C46_CS=0;
    AT93C46_CS=1;
    while(!SPI_DO)
        clock();
    AT93C46_CS=0;
    disable_write();
}
//往at93c46 addr地址写数据dat
void at93c46_write(unsigned char addr,unsigned char dat)
{
    _nop_();
    //檫除原先的数据
    at93c46_erase(addr);
    addr<<=1;
    enable_write();
    AT93C46_CS=1;
   
    spi_send(WRITE,3);
    spi_send(addr,7);
    spi_send(dat,8);
    AT93C46_CS=0;
    AT93C46_CS=1;
    while(!SPI_DO) clock();
    AT93C46_CS=0;
    disable_write();
}
//往at93c46所有存储单元写入dat
void at93c46_writeall(unsigned char dat)
{
    enable_write();
    _nop_();
    AT93C46_CS=1;
    spi_send(WRAL,5);
    spi_send(0,5);
    spi_send(dat,8);
    AT93C46_CS=0;
    AT93C46_CS=1;
    while(!SPI_DO) clock();
    AT93C46_CS=0;
    disable_write();
}
//擦除at93c46
void at93c46_eraseall(void)
{
    enable_write();
    _nop_();
    AT93C46_CS=1;
   
    spi_send(ERAL,5);
    spi_send(0,5);
    AT93C46_CS=0;
    AT93C46_CS=1;
    while(!SPI_DO) clock();
    AT93C46_CS=0;
    disable_write();
}
void init_spi_93c46(void)
{
    AT93C46_CS=0;
    SPI_DI=0;
    SPI_DO=1;
    SPI_CLK=0;
}