Board logo

标题: 【晒FRAM铁电存储器样片】+使用ATMEL Mega16读写MB85RC256V [打印本页]

作者: fanglirong    时间: 2014-8-19 23:36     标题: 【晒FRAM铁电存储器样片】+使用ATMEL Mega16读写MB85RC256V

    主控MCU是ATMEL Mega16,主频8MHz,使用硬件I2C(ATMEL叫TWI)。标准的I2C电路,电路图我就不给出了。当电压为5V时, 上拉电阻为10K时, SCL和SDA的一个时钟周期为10us; 上拉电阻为1K时, SCL和SDA的一个时钟周期为2.5us。兼容多种容量的EEPROM.






#include<iom16v.h>
#include<macros.h>
#include"xd.h"
#define XDmain
#include"xdprj.h"




uchar r_buf[64];


uchar w_buf[64];


void main()
{

uint i;


     uchar *r;
     uint b;
     uint c;


     uchar *w;
     uint x;
     uint y;



tms(100);



//-----初始化cpu------
    setreg_m16();
//初始化cpu





for(i=0;i<64;i++)
//清主机读和写缓存区

r_buf=w_buf=0;



for(i=0;i<64;i++)
//写缓存区赋初值

w_buf=i;


     r=r_buf;
//读参数
     b=0x00;
     c=64;


     w=w_buf;
//写参数
     x=0x00;
     y=64;


     wt24c(w,x,y);
//写


     rd24c(r,b,c);
//读


     //-----读出的数据发送到PC-----
     for(i=0;i<64;i++)
     
txd_buf=r_buf;


     txd_buf[69]=syserr;


     txdpo(txd_buf, 69);


     while(1);
     //----------------------------



c=0;




}






//-------------------------------------------------------------------------------------------------------------------------
//ICC-AVR application builder : 2005-11-9 22:09:34
// Target : M16
// Crystal: 8.0000Mhz




void port_init(void)
{
PORTA = 0xFF;
DDRA  = 0x00;
PORTB = 0xFF;
DDRB  = 0x00;
PORTC = 0xFF; //m103 output only
DDRC  = 0x00;
PORTD = 0xFF;
DDRD  = 0x00;
}


//TWI initialize
// bit rate:100
void twi_init(void)
{
TWCR= 0X00; //disable twi
TWBR= 0x64; //set bit rate
TWSR= 0x00; //set prescale
TWAR= 0x00; //set slave address
TWCR= 0x04; //enable twi
}


//UART0 initialize
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x33; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x08;
}


//call this routine to initialize all peripherals
void setreg_m16(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
twi_init();
uart0_init();


MCUCR = 0x00;
GICR  = 0x00;
TIMSK = 0x00; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
















作者: fanglirong    时间: 2014-8-19 23:37

1# fanglirong
#include<iom128v.h>
#include<macros.h>
#include"xd.h"
#include"xdprj.h"



//------在此设定芯片型号------
#define e2prom 32
// <---在此设定芯片型号, 1代表24C01; 16代表24C16; 512代表24C512

#if e2prom==1

#define PAGE_SIZE 8

#define PAGE_EXP  3

#define SIZE 0x007f
#elif e2prom==2

#define PAGE_SIZE 8

#define PAGE_EXP  3

#define SIZE 0x00ff
#elif e2prom==4

#define PAGE_SIZE 16

#define PAGE_EXP  4

#define SIZE 0x01ff
#elif e2prom==8

#define PAGE_SIZE 16

#define PAGE_EXP  4

#define SIZE 0x03ff
#elif e2prom==16

#define PAGE_SIZE 16

#define PAGE_EXP  4

#define SIZE 0x07ff
#elif e2prom==32

#define PAGE_SIZE 32

#define PAGE_EXP  5

#define SIZE 0x0fff
#elif e2prom==64

#define PAGE_SIZE 32

#define PAGE_EXP  5

#define SIZE 0x1fff
#elif e2prom==128

#define PAGE_SIZE 64

#define PAGE_EXP  6

#define SIZE 0x3fff
#elif e2prom==256

#define PAGE_SIZE 64

#define PAGE_EXP  6

#define SIZE 0x7fff
#elif e2prom==512

#define PAGE_SIZE 128

#define PAGE_EXP  7

#define SIZE 0xffff
#endif
//--------------------------

//--------在此设定芯片地址-------
#define W_ADD_COM 0xa0
//写字节命令及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 0
#define R_ADD_COM 0xa1
//读命令字节及器件地址(根据地址实际情况改变), 1010 A2 A1 A0 1
//-------------------------------



#define SLAW
0x18
//SLA_W 已正常发送代码,判断器件是否正常应答的常量.

//-----在此改变预置错误号-----
#define ERR_SLAW
ERR_10
//写字节命令及器件地址错, 在此也就是读写器件错!!
//---------------------------



//-----------4个I2总线公用函数, 可供其它I2总线器件的程序调用--------------
void i2cstart(void);
//总线上起动开始条件
uchar i2cwt(uchar a);
//把一个字节数据输入器件, 返回TWI状态
uchar i2crd(void);
//i2c读要调用的函数
void i2cstop(void);
//总线上起动停止条件
//------------------------------------------------------------------------

uchar * wt24c_fc(uchar *p, uint ad, uchar n);
//向24Cxx写入数据wt24c_h()所要调用的函数

//向24Cxx写入数据
//参数: *p_rsc要输出数据的主机内存地址指针; ad_dst要写入数据的i2c的地址(双字节); num数据个数
//参数条件: ad_dst: ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
void wt24c(uchar *p_rsc, uint ad_dst, uint num)
{   uint n;

    n=ad_dst/PAGE_SIZE;
//确定地址与块地址的差

if(n) n=(ulong)PAGE_SIZE*(n+1)-ad_dst;


else n=PAGE_SIZE-ad_dst;


    if(n>=num)
//如果ad_dst所在的数据块的末尾地址 >= ad_dst + num, 就直接写入num个数据
    {
wt24c_fc(p_rsc, ad_dst, num);
   
if(syserr!=0) return;
    }
    else
//如果ad_dst所在的数据块末尾地址 < ad_dst + num, 就先写入ad_dst所在的数据块末尾地址与 ad_dst 之差个数据
    {   p_rsc=wt24c_fc(p_rsc, ad_dst, n);
   
if(syserr!=0) return;



num-=n;     //更新剩下数据个数
        ad_dst+=n;
//更新剩下数据的起始地址

        //把剩下数据写入器件
        while(num>=PAGE_SIZE)
//先按PAGE_SIZE为长度一页一页的写入
        {
p_rsc=wt24c_fc(p_rsc, ad_dst, PAGE_SIZE);
        
if(syserr!=0) return;
        

            num-=PAGE_SIZE;
//更新剩余数据个数
        
ad_dst+=PAGE_SIZE;
//更新剩下数据的起始地址

}


if(num)
//把最后剩下的小于一个PAGE_SIZE长度的数据写入器件

wt24c_fc(p_rsc, ad_dst, num);
    }
}


//从24cxx读出数据
//参数: *p_dst要读入数据的主机内存地址指针; ad_rsc要输出数据的i2c的地址(整形); num数据个数(整形)
//参数条件:  ad_dst+(num-1)不能大于器件的最高地址; num必须>0;
void rd24c(uchar *p_dst, uint ad_rsc, uint num)
{   uchar t=0;


#if e2prom<32

t=ad_rsc>>8;

t<<=1;

#endif



i2cstart();
//发送起始信号



if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址

{


#if e2prom>16

i2cwt(ad_rsc>>8);
//ad_rsc的高位,  发送要读出数据的地址

#endif

i2cwt(ad_rsc);
//ad_rsc的低位



i2cstart();
//再发送起始信号

i2cwt(R_ADD_COM+t);
//发送SLA_R, 读命令字节及器件地址



for(;num>0;num--)

{   *p_dst=i2crd();
//从器件读出一个字节

p_dst++;

}

}

else syserr=ERR_SLAW;
//写字节命令及器件地址错或对方无应答



i2cstop();

}



//向24Cxx写入数据wt24c_h()所要调用的函数
//返回写入n个字节后的主机内存指针
uchar * wt24c_fc(uchar *p, uint ad, uchar n)
{
uchar t=0;


#if e2prom<32

t=ad>>8;

t<<=1;

#endif



i2cstart();
//发送起始信号



if(i2cwt(W_ADD_COM+t)==SLAW)//发送SLA_W, 写字节命令及器件地址

{


#if e2prom>16

i2cwt(ad>>8);
//ad_dst的高位到器件

#endif

i2cwt(ad);
//ad_dst的低位到器件



for(;n>0;n--)
//发送要写入的数据

{   i2cwt(*p);

p++;

}

}

else syserr=ERR_SLAW;
//写字节命令及器件地址错



i2cstop();
    tms(6);
//延时6ms



return(p);
}



//-------------------------------以下为其它I2总线器件可调用的函数--------------------------

//总线上起动开始条件
void i2cstart(void)
{

TWCR= BIT(TWINT) | BIT(TWSTA) | BIT(TWEN);
   
while (!(TWCR & BIT(TWINT)));
}

//把一个字节数据输入器件, 返回TWI状态
uchar i2cwt(uchar a)
{

TWDR = a;
   
TWCR = BIT(TWINT) | BIT(TWEN);
   
while (!(TWCR & BIT(TWINT)));
   
_NOP();
   
return(TWSR&0b11111000);
}

//i2c读要调用的函数
//从器件读出一个字节
uchar i2crd(void)
{
   
TWCR= BIT(TWINT) | BIT(TWEA) | BIT(TWEN);
   
while (!(TWCR & BIT(TWINT)));
   
return(TWDR);
}


//总线上起动停止条件
void i2cstop(void)
{
   TWCR = BIT(TWINT) | BIT(TWSTO) | BIT(TWEN);
}




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0