前段时间在一款LED点阵屏的控制板看到他们选用的存储芯片为AT45DB161,用来存储显示的内容及其他一些信息。这系列的芯片采用SPI接口并有很高的工作频率,这两点保证了芯片有较高的数据读写速度,另外在容量方面有1兆位到128兆位不等的选择,具有一定应用范围。
对于新接触这款芯片的朋友们可能不太了解其工作方式,比如如何读写芯片,怎样的数据格式以及各种指令。通过这篇文章的学习加上自己的试验可以让你对这芯片从陌生到熟知。
学习思路:让单片机做一个桥梁,使PC机和AT45DB161建立连接。通过串口工具可以很直观的感受存储芯片的工作方式,并掌握各种指令。
步骤:1.
连接硬件,包括单片机(我选择ATmega16)、AD45DB161、max232、串口线。注意:因为存储芯片不能供5v电源会出现电压不匹配,可以在数据线上加220欧电阻降压。
2. 用ICCAVR编译以下程序,烧至单片机。
3. 打开串口,发送“0x55 0x84 0xFF 0xFE 0x00
0x20 0xFF 0xFF 0xFF 0xFF”
刚才我们的代码意思是向存储器缓冲区1的{dy}个字节上写入0x20。其中0x55是只是用于告诉单片机后面数据有效。0x84就是写缓冲区1的指令了,各种指令详见芯片手持28页到31页。
由于程序中要求单片机在接收到10个数据后再处理,所以串口一次发送10个字节,必须0x55开头,不够时可用0xff补上,或是更改程序。
这是我自己的一些学习经验,觉得有用和大家分享一下。有任何疑问,或本篇不对的地方朋友们可以留言告诉我了!
#include
<iom16v.h>
unsigned char jishu;
unsigned char data_232[16];
unsigned char Tem;
#define UNSELECT_CHIP
PORTB|=(1<<4)
#define SELECT_CHIP
PORTB&=~(1<<4)
//串口初始化函数
void Uart_Init(void) {
UCSRA =
0x02; /// 倍速
UCSRB =
0x98; //允许接收和发送
UCSRC =
0x06; //8位数据
UBRRH = 0x00;
UBRRL =
12; //9600
}
//串口数据发送
void Uart_Transmit(unsigned char i)
{
unsigned
char ii;
for(ii=0;ii<10;ii++);
while (!(UCSRA &
(1<<UDRE))); //
等待发送缓冲器为空//
UDR =
i; //发送数据//
}
void Uart_puts(unsigned char *lb)
{
while
(*(lb))
{
while(Uart_Transmit(*lb));
lb++;
}
}
//SPI接口初始化
void SPI_MasterInit(void)
{ DDRB |= (1<<PB5) |
(1<<PB7)|(1<<PB4);
// 设置MOSI 和SCK 为输出,其他为输入
SPCR = (1<<SPE) |
(1<<MSTR) |
(0<<SPR1) |
(1<<SPR0); // 使能SPI
主机模式,设置时钟速率为fck/128
}
//SPI数据发送
unsigned char spi_write(unsigned char data)
{
unsigned
char temp;
SPDR = data;
while(!(SPSR
& (1<<SPIF)))
{
asm("nop");
}
temp = SPDR;
return temp;
}
unsigned char SPI_Read()
{unsigned char temp;
while(!(SPSR&(1<<SPIF)))
temp=SPDR;
return temp;
}
void main()
{
SPI_MasterInit();
Uart_Init();
SEI();
Uart_Transmit(0x30);
while(1);
}
//数据接收,中断方式//
#pragma interrupt_handler Uart_Receive: 12
void Uart_Receive( void ) {
unsigned char aq;
//while (
UCSRA&0x80==0); //
等待接收数据//
LED1_1;
if(Tem==0)
{data_232[jishu]=UDR;
jishu++;}
else aq=UDR;
if(jishu==10){Uart_Transmit(0x33);jishu=0;Tem=1;}
if(data_232[0]==0x55&&Tem==1)
{
SELECT_CHIP;
spi_write(data_232[1]);
Uart_Transmit(spi_write(data_232[2]));
Uart_Transmit(spi_write(data_232[3]));
Uart_Transmit(spi_write(data_232[4]));
Uart_Transmit(spi_write(data_232[5]));
Uart_Transmit(spi_write(data_232[6]));
Uart_Transmit(spi_write(data_232[7]));
Uart_Transmit(spi_write(data_232[8]));
Uart_Transmit(spi_write(data_232[9]));
UNSELECT_CHIP;
}
if(jishu==0)Tem=0;
}