📄 at45db_for_msp430.c
字号:
/**********************************Copyright (c)*********************************
*
* 西安.兰特水电测控技术有限责任公司
*
* 开发部
*
*----------------------------------文件信息-------------------------------------
* 文件名称: at45db_for_msp430.c
* 创 建 人: 李良福
* 创建时间: 2006/03/08
* 修改时间: 2006/03/08
* 当前版本: v1.0: 针对于MSP430单片机的C语言(水情测量板:LT_V3RTU_2006_03_16)
* 描 述:本模块定义了基于SPI总线读写Data Flash的相关函数。使用芯片为at45db021
* 此Flash存储器共1024页,每页264字节。
********************************************************************************/
#include <msp430x14x.h>
#include "spi_for_msp430.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//SDI: P3.1
//SDO: P3.2
//SCK: P3.3
//端口数据输出电平高低控制
//#define CS_high (P5OUT |= BIT4)
//#define CS_low (P5OUT &= ~BIT4)
#define SCK_high (P3OUT |= BIT3)
#define SCK_low (P3OUT &= ~BIT3)
#define SDI_high (P3OUT |= BIT1)
#define SDI_low (P3OUT &= ~BIT1)
#define SDO_high (P3OUT |= BIT2)
#define SDO_low (P3OUT &= ~BIT2)
//端口方向控制
//#define CS_in (P5DIR &= ~BIT4)
//#define CS_out (P5DIR |= BIT4)
#define SCK_in (P3DIR &= ~BIT3) //SCK输出, P3.3输入: P3DIR.3=0;
#define SCK_out (P3DIR |= BIT3) //SCK输入, P3.3输出: P3DIR.3=1;
#define SDI_in (P3DIR &= ~BIT1) //SDO输出, P3.1输入: P3DIR.1=0;
#define SDI_out (P3DIR |= BIT1) //SDO输入, P3.1输出: P3DIR.1=1;
#define SDO_in (P3DIR &= ~BIT2) //SDI输出, P3.2输入: P3DIR.2=0;
#define SDO_out (P3DIR |= BIT2) //SDI输入, P3.2输出: P3DIR.2=1;
unsigned int page=1,addr=1;
extern const unsigned char flash_data_len;
unsigned int page_rebegin_flag = 0;
// 定义at45db021的信息头结构
typedef struct
{
unsigned char cmd;
unsigned char addr1;
unsigned char addr2;
unsigned char addr3;
} AT45_HDR;
AT45_HDR at45;
/*******************************************************************************
* name: CS_low()
* description: 数据存储芯片的片选信号线为低
* input parameter:
* output parameter:
********************************************************************************/
static void CS_low(void)
{
/*
// 000 001 010 011; 100 101 110 111 //CS: P1.7 P1.6 P1.5
// 0 1 2 3 4 5 6 7
P1OUT |= BIT7; //100
P1OUT &= ~BIT6;
P1OUT &= ~BIT5;
*/
P3OUT &=~BIT0; //lhy
}
/*******************************************************************************
* name: CS_high()
* description: 数据存储芯片的片选信号线为高
* input parameter:
* output parameter:
********************************************************************************/
static void CS_high(void)
{
/*
// 000 001 010 011; 100 101 110 111 //CS: P1.7 P1.6 P1.5
// 0 1 2 3 4 5 6 7
P1OUT |= BIT7; //111
P1OUT |= BIT6;
P1OUT |= BIT5;
*/
P3OUT |=BIT0; //lhy
}
/*******************************************************************************
* name: Init_at45db()
* description: 数据存储芯片的初始化
* input parameter:
* output parameter:
********************************************************************************/
void Init_at45db(void)
{
P1DIR |= BIT5; // 74ls138--CS
P1DIR |= BIT6;
P1DIR |= BIT7;
P1SEL &= ~BIT5;
P1SEL &= ~BIT6;
P1SEL &= ~BIT7;
P3OUT = 0x00; // SCK SO SI
P3SEL = 0x00;
P3DIR |= 0x0f; // 0000 1110;
//lhy
}
/*******************************************************************************
* name: CheckStatus()
* description: 读状态寄存器内容
* input parameter: Null.
* output parameter: 0 or 1
********************************************************************************/
int CheckStatus(void)
{
char status;
SPIDataWrite(0xD7);
status=SPIDataRead();
if(status&0x80)
return 1;//ready
else
return 0;//busy
}
/*******************************************************************************
* name: at45_hdr()
* description: 将提供的命令码和有效地址转换为便于处理的形式。
* input parameter: cmd--------------8位操作命令码;
* page-----11位页地址,有效页范围:0~2047; // PA10~PA7 // PA6~PA0,BA8
* addr-----9位页内地址,有效氛围:0~263; // BA7~BA0
* output parameter: AT45_HDR 类型指针 at45 所指向的数据内容
********************************************************************************/
static void at45_hdr(unsigned char cmd_op,unsigned int page,unsigned int addr)
{
at45.cmd =cmd_op;
at45.addr1 = 0x0f & (page>>7); // PA10~PA7
at45.addr2 = (page<<1) | (0x01 & (addr>>8)); // PA6~PA0,BA8
at45.addr3 = addr; // BA7~BA0
}
/*******************************************************************************
* name: at45_write_hdr()
* description: 该函数用于写 at45db021b时发送命令字和地址。发送信息包含在数据结构at45中。
* input parameter: NULL
* output parameter: NULL
********************************************************************************/
void at45_write_hdr(void)
{
unsigned char i;
for(i=0;i<4;i++)
{
SPIDataWrite(*(((unsigned char *)&at45)+i));// 发送命令码和地址码
//delay(10);
// while(CheckStatus()==0);
}
}
/*******************************************************************************
* name: At45_write_Flash()
* description: 该函数向指定的地址连续写入指定个数的数据。
* input parameter: page------目的页。有效范围:0~2047;
* addr------页内地址。有效范围:0~263;
* data------操作数据指针;
* num-------数据个数。
* output parameter: NULL
********************************************************************************/
void At45_write_Flash(unsigned int page,unsigned int addr,unsigned char *data,unsigned int num)
{
unsigned char cmd1, cmd2;
unsigned int i;
static unsigned char flag=0;
if((page>2047) || (addr>263)) return; // 超出 at45 寻址范围,函数返回
if(flag==0)
{
flag = 1;
cmd1 = 0x82;// 通过 Buffer1 写,命令码为0x82
} // Main memory page program through buffer1
else
{
cmd1 = 0x85;// 通过 Buffer2 写,命令码为0x85
flag = 0;
}
at45_hdr(cmd1,page,addr);
/**************************** 等待 at45 空闲 *******************************/
CS_low();
delay(100);
/************************** 将指定页的数据传入 Buffer **********************/
if(at45.cmd == 0x82)
cmd2 = 0x53; // 传入 Buffer1,命令码为0x53
else
cmd2 = 0x55; // 传入 Buffer2,命令码为0x55
at45_hdr(cmd2,page,addr);// Main memory page to buffer 1 transfer
at45_write_hdr(); // 主存储器和缓存之间数据的传递
SPIDataWrite(0x00);
//while(CheckStatus()==0); //等待 at45 数据传输完毕
/******************* Main Memorry Page write through Buffer *****************/
CS_high(); // 选通 at45db041b
delay(100);
CS_low();
delay(100);
at45_hdr(cmd1,page,addr);// Main memory page program through buffer1
at45_write_hdr(); // 通过 Buffer写入主存储器
//while(CheckStatus()==0); //等待 at45 数据传输完毕
for(i=0;i<num;i++) // 发送 num 个数据
{
SPIDataWrite(*(data+i));
//while(CheckStatus()==0); // 等待数据发送完毕
}
delay(100);
CS_high();
}
/*******************************************************************************
* name: At45_read_Flash()
* description: 该函数从 at45db041b 的指定地址连续读出指定个数的数据
* input parameter: page------目的页。有效范围:0~1023。
* addr------页内地址。有效范围:0~263。
* data------数据存放的首地址。
* num-------数据个数。
* output parameter: NULL
********************************************************************************/
void At45_read_Flash(unsigned int page,unsigned int addr,unsigned char *data,unsigned int num)
{
unsigned int i;
if((page>2047) || (addr>263)) return; // 超出 at45 的寻址范围,返回
CS_low(); // 选通 at45db041b
delay(100);
// Main memory page read
at45_hdr(0xD2,page,addr); // 读主存储器的命令码为0xD2
at45_write_hdr(); // 发送读命令和地址
/**************************** 等待 at45 空闲 *******************************/
SPIDataWrite(0xE8); //连续写32位don't care bits.
SPIDataWrite(0xE8); //注意:不能在这条程序后面加while(CheckStatus()==0);
SPIDataWrite(0xE8);
SPIDataWrite(0xE8); //32位don't care bits
//while(CheckStatus()==0); //等待 at45 数据传输完毕
for(i=0;i<num;i++)
{
*(data+i) = SPIDataRead();
//while(CheckStatus()==0); //一定要加上,否则读出的数据出错
}
delay(100);
CS_high();
}
/*******************************************************************************
* name: At45_write_Flash_module_init(void)
* description: 需要在实现自动时间数据的查询之前对数据存储芯片AT45DB021进行初始化,
* 全部写为方法0xff
* input parameter: 数据包指针。
* output parameter: NULL
********************************************************************************/
void At45_write_Flash_module_init(void)
{
unsigned int min_page=1, max_page=1023, min_addr=1, max_addr=252;
unsigned int page_temp=1,addr_temp=1, i=0, j=0;
unsigned char init_data = 0xff, wdata[252];
for (j=min_addr; j<=max_addr; j++)
{
wdata[j-1]=init_data;
}
for (i=min_page; i<=max_page; i++)
{
At45_write_Flash(i, min_addr, wdata, 252);//写数据存储芯片
delay(100);
}
}
/*******************************************************************************
* name: At45_write_Flash_module(unsigned char *w_data)
* description: 模块内部自行维护flash的地址指针,自动写Flash的代码,数据指针自动递增
flash第0页已占用,本模块不得对第0页做写操作。
数据包长度定义为全局变量 const uchar flash_data_len=21。
需要定义全局变量:unsigned int page=1,addr=1;
* input parameter: 数据包指针。
* output parameter: null.
********************************************************************************/
void At45_write_Flash_module(unsigned char *wm_data)
{
unsigned int min_page=1, max_page=1023, min_addr=1, max_addr=252;
unsigned int page_temp=1,addr_temp=1;
unsigned char page_p[2];
At45_write_Flash(page, addr, (unsigned char *)wm_data, flash_data_len); //写数据存储芯片缓存
delay(1000); //注意:这个延时不能少,否则下一个At45_write_Flash写不进去
page_p[0]=page/256;
page_p[1]=page-page_p[0]*256;
At45_write_Flash(0, 262, page_p, 2);
//delay(500);
if (addr < max_addr-flash_data_len)//判断是否写到了页内最高地址处
{
page_temp = page; //页不变
addr_temp = addr + flash_data_len; //地址增加数据包长度
}
else if(addr == max_addr-flash_data_len+1 && page < max_page)
{//在页内最高地址处判断如果没有写到最大页
page_temp = page+1; //页加1
addr_temp = min_addr; //地址重新开始计数
}
else if(addr == max_addr-flash_data_len+1 && page == max_page)
{//在页内最高地址处判断如果写到了最大页
page_temp = min_page;//页重新开始计数
addr_temp = min_addr;//地址重新开始计数
page_rebegin_flag = 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -