⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45db161d.c

📁 AT45DB161D芯片的读写驱动程序,有多款程序,包括有51,AVR,MSP430等,需要的朋友可以拿去看看,很有帮助.
💻 C
字号:
#include <msp430x14x.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcdzk.h"

#define uchar unsigned char
#define uint unsigned int
/****************************************************************
*          ATMEL的DATAFLASH操作函数库(FOR AT45DB161D)         *
*                                                               *
*                     作者:gxlujd(彩虹)                      *
*             最后修改时间:2007年2月18日(大年初一)           *
*                                                               *
*    感谢www.ouravr.com、阿莫和坛子里的哥们一直以来的热心帮助   *
*                                                               *
*    如果这些资源能帮到你,请保留以上这些信息,同时也请你把自   *
*    己的一些日常积累拿出来分享,这个世界需要更多的无私开源,   *
*    别让金钱和利益蒙住了内心的真诚,谢谢!                     *
*****************************************************************/


//unsigned char DF_buffer[528] = {0x0};


//msp430 SPI 初始化
void SPI_Init(void) {
        WDTCTL = WDTPW + WDTHOLD;
        FCTL2 = FWKEY + FSSEL_1 + FN1;              //工作频率设为  MCLK/3,333.3KHZ
        _DINT();  
        
        P1DIR |= BIT7;//液晶背光
        P1OUT &= 0x00;//关背光    
        
        IO_SET_WP_OUTPUT();                       //设置WP信号输出引脚
        IO_SET_RESET_OUTPUT();                    //设置RESET信号输出引脚
        IO_SET_CS_OUTPUT();                       //设置CS信号输出引脚

        IO_SET_WP();                              //WP信号置位
        IO_SET_RESET();                           //RESTE信号置位
        IO_SET_CS();                              //CS信号置位


        P3SEL |= 0x0E;                            // Setup P3 for SPI mode
  	U0CTL = CHAR + SYNC + MM + SWRST;         // 8-bit, SPI, Master
  	U0TCTL = CKPL + SSEL1 + STC;              // Polarity, SMCLK, 3-wire
  	//U0TCTL = SSEL1 + STC;
        U0BR0 = 0x02;                             // SPICLK = SMCLK
  	U0BR1 = 0x00;
  	U0MCTL = 0x00;			    	  //波特率 = BRCLK / (UBR + (M7 + M6 + ... + M0) / 8),M7-M0为U0MCTL寄存器的相应位
  	ME1 = USPIE0;                             // Module enable
  	U0CTL &= ~SWRST;                          // SPI enable
  	//IE1 |= URXIE0;                          // Recieve interrupt enable
  	_EINT();                                  // Enable interrupts
}

//往SPI口写一个字节的数据
void write_SPI(unsigned char data) {
	U0TXBUF = data;	
        while(!(U0TCTL & TXEPT));//等待发送完毕
}

unsigned char read_SPI(void) {
        unsigned char temp;
        IFG1 &= ~URXIFG0;
        while(!(IFG1 & URXIFG0));
        temp = U0RXBUF;
        return temp;         
}

//检查状态寄存器最高位是否为忙,并等待空闲
void DF_wait_busy(void) {
	unsigned char state_reg = 0x00;
	DF_SELECT_1;
	write_SPI(READ_STATE_REGISTER);
	write_SPI(0x00);
	write_SPI(0x00);                        
	write_SPI(0x00);
	while((state_reg & 0x80) == 0) {
		write_SPI(0x00);
		state_reg = read_SPI();
	}
	DF_DESELECT_1;
}

//格式化主存储器(以扇区<0A,0B,1……15>为单位删除所有页数据)
void DF_format(void) {
	unsigned char i;
	DF_SPI_ON;
	
	DF_wait_busy();
	DF_SELECT_1;
	write_SPI(SECTOR_ERASE);
	write_SPI(0x00);
	write_SPI(0x00);
	write_SPI(0x00);
	DF_DESELECT_1;
	
	DF_wait_busy();
	DF_SELECT_1;
	write_SPI(SECTOR_ERASE);
	write_SPI(0x00);
	write_SPI(0x20);
	write_SPI(0x00);
	DF_DESELECT_1;

	for(i = 1; i < 16; i++) {
		DF_wait_busy();
		DF_SELECT_1;
		write_SPI(SECTOR_ERASE);
		write_SPI(i << 2);
		write_SPI(0x00);
		write_SPI(0x00);
		DF_DESELECT_1;
	}
	DF_SPI_OFF;
}


//擦除指定的主存储器页(地址范围0-4095)
void DF_page_earse(unsigned int page) {
	DF_SPI_ON;
	DF_wait_busy();
	
	DF_SELECT_1;
	write_SPI(PAGE_ERASE);
	write_SPI((unsigned char)(page >> 6));
	write_SPI((unsigned char)(page << 2));
	write_SPI(0x00);
	DF_DESELECT_1;
	DF_SPI_OFF;
}


//将保存在数组DF_buffer[]中的一页数据写入第一或者第二缓冲区后送入主存储区
//(先擦除后写入模式,页地址范围0-4095)
void DF_write_page(unsigned char buffer, unsigned int page) {
	unsigned int i;
	DF_SPI_ON;
	
	DF_wait_busy();
	DF_SELECT_1;
	if(buffer == 1)
		write_SPI(BUFFER_1_WRITE);
	else
		write_SPI(BUFFER_2_WRITE);
	write_SPI(0x00);
	write_SPI(0x00);
	write_SPI(0x00);
	for (i=0;i<528;i++)
		write_SPI(DF_buffer[i]);
	DF_DESELECT_1;
	
	if (page<4096) {
		DF_SELECT_1;
		if(buffer == 1)
			write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);
		else
			write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);
		write_SPI((unsigned char)(page>>6));
		write_SPI((unsigned char)(page<<2));
		write_SPI(0x00);
		DF_DESELECT_1;
		DF_wait_busy();
	}
	DF_SPI_OFF;
}


//将指定主存储器页的数据转入第一缓冲区后读出,保存在DF_buffer[]数组中
//(页地址范围0-4095)
void DF_read_page(unsigned char buffer, unsigned int page) {
	unsigned int i;
	DF_SPI_ON;
	
	while(!(P2IN & 0x80));//查询Flash是否处于忙状态
	
	DF_SELECT_1;
	if(buffer == 1)
		write_SPI(MM_PAGE_TO_B1_XFER);
	else
		write_SPI(MM_PAGE_TO_B2_XFER);
	write_SPI((unsigned char)(page >> 6));
    	write_SPI((unsigned char)(page << 2));
    	write_SPI(0x00);
	DF_DESELECT_1;
	
	DF_wait_busy();
	DF_SELECT_1;
	if(buffer == 1)
		write_SPI(BUFFER_1_READ);
	else 
		write_SPI(BUFFER_2_READ); 
	write_SPI(0x00);                        
	write_SPI(0x00);   
	write_SPI(0x00);        
	write_SPI(0x00);
	for (i=0;i<528;i++) {
		write_SPI(0xFF);
		DF_buffer[i] = read_SPI();
	}
	DF_DESELECT_1;
	DF_SPI_OFF;
}


//以直接读取方式读取指定的主存储器页数据(页地址范围0-4095)
void DF_MM_read_page(unsigned int page) {
	unsigned int i;
	DF_SPI_ON;
	
	while(!(P2IN & 0x80));//查询Flash是否处于忙状态
	DF_SELECT_1;
	write_SPI(MM_PAGE_READ);
	write_SPI((unsigned char)(page >> 6));
    	write_SPI((unsigned char)(page << 2));
    	write_SPI(0x00);
	write_SPI(0x00);
	write_SPI(0x00);
	write_SPI(0x00);
	write_SPI(0x00);
	for (i=0;i<528;i++) {
		write_SPI(0x00);               
		DF_buffer[i] = read_SPI();
	}
	DF_DESELECT_1;
	
	DF_SPI_OFF;
}


//读取状态寄存器
//bit7		bit6	bit6	bit6	bit6	bit6	bit6	bit6
//RDY/BUSY	COMP	1	0	1	1	PROTECT	PAGE SIZE	
unsigned char DF_read_reg(void) {
	unsigned char temp;
	DF_SPI_ON;
	DF_SELECT_1;
	write_SPI(READ_STATE_REGISTER);
	write_SPI(0x00);
	write_SPI(0x00);                        
	write_SPI(0x00);   
	write_SPI(0x00);
	temp = RXBUF0;
	DF_DESELECT_1;
	DF_SPI_OFF;
	return temp;
}





//将指定主存储器页的数据转入指定缓冲区
void DF_mm_to_buf(unsigned char buffer,unsigned int page) {
	DF_SPI_ON;
	DF_wait_busy();
	DF_SELECT_1;
	if (buffer==1)
		write_SPI(MM_PAGE_TO_B1_XFER);
	else
		write_SPI(MM_PAGE_TO_B2_XFER);
	write_SPI((unsigned char)(page >> 6));
    	write_SPI((unsigned char)(page << 2));
    	write_SPI(0x00);
	DF_DESELECT_1;
	DF_SPI_OFF;
}


//读取指定缓冲区指定单元的数据,保存在DF_buffer[]数组中
unsigned char DF_read_buf(unsigned char buffer,unsigned int start_address,unsigned int length) {
	unsigned int i;
	if ((527-start_address)>=length) {
		DF_SPI_ON;
		DF_wait_busy();
		DF_SELECT_1;
		if (buffer==1)
			write_SPI(BUFFER_1_READ); 
		else
			write_SPI(BUFFER_2_READ);
		write_SPI(0x00);                        
		write_SPI((unsigned char)(start_address >> 8));   
		write_SPI((unsigned char)start_address);        
		write_SPI(0x00);
		for (i=0;i<length;i++) {
			write_SPI(0xFF);                        
			DF_buffer[i] = read_SPI();
		}
		DF_DESELECT_1;
		DF_SPI_OFF;
		return 1;
	}
	else
		return 0;
}


//将DF_buffer[]数组中指定长度的数据写入指定缓冲区
unsigned char DF_write_buf(unsigned char buffer,unsigned int start_address,unsigned int length) {
	unsigned int i;
	if  ((527-start_address)>=length) {
		DF_SPI_ON;
		DF_wait_busy();
		DF_SELECT_1;
		if (buffer==1)
			write_SPI(BUFFER_1_WRITE);
		else
			write_SPI(BUFFER_2_WRITE);
		write_SPI(0x00);
		write_SPI((unsigned char)(start_address >> 8));   
		write_SPI((unsigned char)start_address);
		for (i=0;i<length;i++)
			write_SPI(DF_buffer[i]);
		DF_DESELECT_1;
		return 1;
	}
	else
		return 0;
}


//将指定缓冲区中的数据写入主存储区的指定页
void DF_buf_to_mm(unsigned char buffer,unsigned int page) {
	DF_SPI_ON;
	DF_wait_busy();
	if (page<4096) {
		DF_SELECT_1;
		if (buffer==1)
			write_SPI(B1_TO_MM_PAGE_PROG_WITH_ERASE);
		else
			write_SPI(B2_TO_MM_PAGE_PROG_WITH_ERASE);
		write_SPI((unsigned char)(page>>6));
		write_SPI((unsigned char)(page<<2));
		write_SPI(0x00);
		DF_DESELECT_1;
	}
	DF_SPI_OFF;
}

void delay(int v) {
        while(v != 0) v--;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -