您现在所在的是:

单片机论坛

回帖:1个,阅读:1171 [上一页] [1] [下一页]
1006
mahuaqiang
文章数:39
年度积分:49
历史总积分:1006
注册时间:2005/6/27
发站内信
08年博客人气奖
发表于:2009/6/10 15:42:23
#0楼
at45db041是atmel公司的新型flash芯片。该芯片具有容量大、读写速度快、外围电路少等诸多优点,更为重要的是该芯片可最低工作在2.5v,工作电流仅为4ma,因此在移动通信、便携等场合得到了广泛的应用。
芯片工作原理与硬件连接
at45db041中的数据按页存放,主存共2048页,每页264字节,所以总容量为528k字节(约4m比特)。存放在主存中的数据掉电不丢失。除了主存以外,at45db041还有两个容量为264字节的数据缓存。缓存可以用作主存与外部进行数据交换时的缓冲区域,也可以暂存一些临时数据。缓存读写方便迅速,但掉电数据会丢失。at45db041数据读写采用串行方式,读写速度快,从页到缓存的传输时间为80 s左右,并且兼容cmos和ttl输入和输出。
at45db041通过片选管脚/cs使能,通过串行输出(so)和串行输入(si)进行数据读和写。由串行时钟(sck)对读写进行控制。
设备运行受微处理器的指令控制。一条有效的指令起始于/cs管脚的下降沿,并跟随相应的8位操作码和指定的缓存或主存地址码。当/cs管脚为低时,轮换时钟管脚(sck)控制操作码和指定的缓存或主存地址码通过si口的载入。所有的指令、地址和数据都从高字节开始传送。
数据读取
读缓存:通过不同的操作码可选择读取两个缓存中的其中一个(操作码54h用作读缓存1,而操作码56h用作读缓存2)。为了实现读缓存的操作,在8位操作码后必须跟有15位任意码,9位地址码和8位任意码。其中9位地址码(bfa8-bfa0)被用作指定要读取的首字节。在轮换时钟sck的控制下,从si载入操作码、地址码、任意码。当载入结束后,在sck轮换时钟的控制下,缓存中的数据就可以从so读出。当读到缓存的末尾时,设备将继续从缓存的开端重读。在这整个过程中/cs必须保持低电平。读缓存结束后,/cs上一个从低到高的电平跳变将终止读操作。
主存页到缓存的传送:一页数据可以从主存传至缓存1或2。8位操作码(53h用于缓存1,55h用于缓存2)后跟有4位保留位,11位用于指定目的页的地址位(pa10-pa0),和9位任意码,在轮换时钟sck的控制下从si载入。在这一过程中/cs管脚必须保持低电位。当载入结束后,在/cs上检测到一个由低到高的电平跳变后,主存页中的数据开始传送至缓存。在数据传送的过程中,状态寄存器将指示状态忙。
数据写入
写缓存:在sck的控制下,8位的操作码(84h用于缓存1,87h用于缓存2)后面跟着15位任意码和9位地址码(bfa8-bfa0)由si载入,其中9位地址码指定了缓存中被写的首字节,数据紧随着地址码输入。/cs上一个由低到高的跳变,将结束写缓存操作。
带有内置擦除的缓存至主存页的传送:8位的操作码(83h用于缓存1,86h用于缓存2)后跟有4位保留位,11位指定要写入的主存页的地址码(pa10-pa0),和9位任意码,在轮换时钟sck的控制下从si载入。当/cs上检测到一个由低到高的跳变时,器件将首先擦除被选中的主存页,然后将储存在缓存中的数据写入该页。擦除和写入的过程都是自动进行的,这一进程不超过20ms。在这个时间里,状态寄存器将指示状态忙。 状态寄存器值读取:读状态寄存器的值可以用来确定设备的忙闲状态。忙闲状态通过寄存器的第7位指示。如果第7位为1,则设备位于空闲状态并可接收下一条指令。如果为0,则设备忙。在载入8位操作码57h后,从so上可以读出1字节的状态寄存器的值。
写保护(/wp) b041具有的写保护功能仅对主存的前256页有效。当/wp管脚为低电平时,flash禁止对主存的前256页进行写操作(只读),但主存的其它页并不受影响,仍然可以进行读写。at45db041的选择性写保护功能为用户的使用提供了很大的便利,用户可以将非常重要的数据,如系统参数、密码和身份信息等存入主存的前256页,并将/wp置低,使这些数据处于写保护状态,以保证这些数据不会被误擦除。而与此同时,用户仍能对其它地址进行读写。如果用户将/wp管脚悬空或接地,flash将不具备写保护功能,所有的主存页都可进行读写。
复位(/reset) b041采用低电平复位,即当/reset管脚出现低电平(2.0v)后,恢复正常工作。为了避免接通电源时,由于电压不稳可能会对芯片正常工作造成影响,所以在使用时,最好在系统开机后延时10ms,再对flash进行操作。
与微处理器的接口
b041外围电路非常简单,可以很方便地与微控制器连接。so、si、sck、/cs,/wp分别与微处理器的通用i/o相连即可。
软件设计
下面主要对at45db041的数据读写作简要介绍。
at45db041进行数据读写主要包括操作码、保留位、地址码、任意码、用户数据的载入和用户数据和状态字的读出两部分。
数据载入子程序
要载入的数据(操作码、保留位、地址码、任意码和用户数据)寄存从r0开始的地址单元里
;数据个数放在r6中 dadain:push  acc
   clr  cs   ;使能r0
trsmit:mov a,@r0
mov r7,#08h 1字节=8比特
loopt: rlc a ;将要发送的数据由高位到低位依次移出
clr sck
mov si, 将1比特的数据送入si
nop
setb sck ;在sck的上升沿at45dbo41从si上取数
djnz r7,loopt ;一字节的数据发送完毕
inc r0
djnz r6,trsmit
setb cs ;所有数据发送完毕
pop acc
ret
数据读取子程序:
;将取出的数据(用户数据和状态字)寄存从r1开始的地址单元里
;数据个数放在r6中
dataout:push acc
clr, a
clr c
clr cs ;使能
receive:clr sck
mov r7,#08h
loopr: setb sck 在sck的上升沿at45db041将数据放在s0上
mov c,so ;将1比特的数据取出
nop
setb sck
rlc a
djnz r7,loopr ;一字节的数据接收完毕
mov @r1,a
inc r1
djnz r6,receive
setb csp ;所有数据接收完毕
pop acc
ret
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
用avr的spi口实现了对at45db041
读写与大家一起分享。
同时感谢曾经给与我帮助的各位前辈。
unsigned char at45db041_statusregisterread()
{  
 unsigned char state_at45db041;  
         
 portb&=~bit(0);    
 spi_hostwrite_read_byte(0x57);  
 state_at45db041=spi_hostwrite_read_byte(0x00);  
 portb|=bit(0);
 return state_at45db041;    
}  
void jude_busystate()
{
       while((at45db041_statusregisterread()&0x80)!=128)
               ;
}
/*******************************************************
描述: 主存读取指定页地址与字节地址固写长度
参数:  
         *read_pheader 读出数据存贮地址指针
         length   读入数据的长度,>8));  
 spi_hostwrite_read_byte((unsigned char)address_history_264);  
 for(i=0;i>8));  
 spi_hostwrite_read_byte((unsigned char)address_history_264);  
 for(i=0;i>8));
 spi_hostwrite_read_byte((unsigned char)address_history_264);
 spi_hostwrite_read_byte(0x00);
 for(j=0;j
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
     
51读写 at45db041读写程序

    /******************************************************************************/
     /*正常操作电压为2.7~3.6v,实验中发现当电压超过4.25v后读出的状态字节为9a(正常 */
     /*的状态字节值为9d),并且读写数据均不准确,所以应当保证卡片的供电电压不超过  */
     /*4.25v。*/
     /*spi规范:data is always clocked into the device on the rising edge of sck a-*/
     /*    nd clocked out of the device on the falling edge of sck.allinstruction-*/
     /*    s,addresses and data are transferred with the most significant bit(msb) */
     /*    first.*/
     /*2005-06-02*/
     /******************************************************************************/
     #pragma    optimize(5)
     #include  
     #include  
     #define    uchar                      unsigned char
     #define    uint                       unsigned int
     sbit       spi_cs                   = p2^0;
     sbit       spi_sck                  = p2^2;
     sbit       spi_so                   = p2^3;
     sbit       spi_si                   = p2^4;
     unsigned char spi_hostreadbyte(void){
         unsigned char i,rbyte=0;
         
         for(i=0;i>7));    
         spi_hostwritebyte((unsigned char)((pa>8)));
         spi_hostwritebyte((unsigned char)bfa);
         for(i=0;i>8));
         spi_hostwritebyte((unsigned char)bfa);
         
         for(i=0;i
         at45db041b_bufferwrite(buffer,bfa,pheader,len);
         while(i++>7));
         spi_hostwritebyte((unsigned char)(pa
         at45db041b_bufferwrite(buffer,bfa,pheader,len);
         while(i++>7));
         spi_hostwritebyte((unsigned char)(pa
     void main(void){
         unsigned char i;
         uchar data test[32];
       
         i=at45db041b_statusregisterread();
         
         memset(test,0x77,32);
         
     at45db041b_buffertomainmemorypageprogramwithbuilt_inerase(1,2047,0,test,32);
         memset(test,0x26,32);
         at45db041b_continuousarrayread(2047,0,test,32);
             
         memset(test,0x88,32);
         
     at45db041b_buffertomainmemorypageprogramwithbuilt_inerase(2,2047,0,test,32);
         memset(test,0x55,32);
         at45db041b_continuousarrayread(2047,0,test,32);
         while(1){}
     }
----------------------------------------------
此篇文章从博客转发
原文地址: Http://blog.gkong.com/more.asp?id=90705&Name=mahuaqiang
匿名用户
文章数:N/A
年度积分:0
历史总积分:0
注册时间:2009/6/15
发站内信
发表于:2009/6/15 22:50:20
#1楼
该用户被锁定,回复内容不予显示!

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

62.4004