📄 spi_flash.c
字号:
#include "include/AT91SAM7X256.h"
#include "include/lib_AT91SAM7X256.h"
//*------------变量定义--------------------------------------------------
static char IsTransfer;
//*------------宏定义-----------------------------------------------------
#define HighToLow(u32val) ((u32val &0xFF000000)>>24|(u32val&0x00FF0000)>>8 \
|(u32val&0x0000FF00)<<8|(u32val&0x000000FF)<<24)
//*----------------------------------------------------------------------
//* 函数名称 : __irqSPIHandler
//* 功能描述 : SPI中断服务子函数
//* 入口参数 : 无
//* 出口参数 : 无
//*----------------------------------------------------------------------
__irq void __irqSPIHandler()
{
if(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RXBUFF)
{
//关闭PDC收发
AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_RXTDIS|AT91C_PDC_TXTDIS;
//关SPI中断
AT91C_BASE_SPI0->SPI_IDR = 0xFFFFFFFF;
//关闭SPI时钟
AT91C_BASE_PMC->PMC_PCDR = (unsigned int)0x1<<4;
//设置全局变量
IsTransfer = 0;
}
//向AIC发送中断处理结束
AT91C_BASE_AIC->AIC_EOICR = 0x1;
}
//*----------------------------------------------------------------------
//* 函数名称 : HardwareInit
//* 功能描述 : 硬件初始化
//* 入口参数 : 无
//* 出口参数 : 无
//*----------------------------------------------------------------------
void HardwareInit(void)
{
//*引脚设置
//关闭对应中断
AT91C_BASE_PIOA->PIO_IDR = AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;
//????禁止拉高引脚
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;
//选择外设A
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;
//选择复用引脚
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA16_SPI0_MISO|AT91C_PA17_SPI0_MOSI|AT91C_PA18_SPI0_SPCK;
//????拉高引脚MISO
AT91C_BASE_PIOA->PIO_PPUER = AT91C_PA16_SPI0_MISO;
//*SPI设置
//使能SPI时钟
AT91C_BASE_PMC->PMC_PCER = (unsigned int)1<<4;
//复位SPI
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;
//设置SPI模式
AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MSTR|AT91C_SPI_PS_FIXED|AT91C_SPI_MODFDIS;
//关闭PDC收发
AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_RXTDIS|AT91C_PDC_TXTDIS;
//使能SPI
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
//关闭SPI时钟
AT91C_BASE_PMC->PMC_PCDR = (unsigned int)0x1<<4;
//*设置中断
//注册中断
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,
4,
AT91C_AIC_PRIOR_HIGHEST,
AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE,
__irqSPIHandler);
//关闭SPI中断
AT91C_BASE_SPI0->SPI_IDR = 0xFFFFFFFF;
//使能AIC中断
AT91C_BASE_AIC->AIC_IECR = (unsigned int)0x1<<4;
//*flash设置
//复位flash
AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x09 << 8);
AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
//等待RSTC复位完毕
while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL));
//设置片选PIO
AT91C_BASE_PIOA->PIO_IDR = AT91C_PA12_SPI0_NPCS0;
AT91C_BASE_PIOA->PIO_PPUDR = AT91C_PA12_SPI0_NPCS0;
AT91C_BASE_PIOA->PIO_ASR = AT91C_PA12_SPI0_NPCS0;
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA12_SPI0_NPCS0;
//设置PCS
AT91C_BASE_SPI0->SPI_MR |= 0xF0000;
AT91C_BASE_SPI0->SPI_MR ^= 0x10000;
//设置为模式3,波特率为1M,片选后延时,连续两次传输延时
AT91C_BASE_SPI0->SPI_CSR[0] = (unsigned int)0x1 | (unsigned int)0x48<<8 |
(unsigned int)0x12<<16 | (unsigned int)0x1<<24;
}
//*----------------------------------------------------------------------
//* 函数名称 : GetFlashStatus
//* 功能描述 : 获取Flash的状态
//* 入口参数 : 无
//* 出口参数 : unsigned char 状态
//*----------------------------------------------------------------------
void TransferData(unsigned char *OptCode,
unsigned int OptLength,
unsigned char *Data,
unsigned int DataLength)
{
//开SPI时钟
AT91C_BASE_PMC->PMC_PCER = (unsigned int)1<<4;
//关闭PDC收发
AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_RXTDIS|AT91C_PDC_TXTDIS;
//设置PDC
AT91C_BASE_SPI0->SPI_RPR = OptCode;
AT91C_BASE_SPI0->SPI_RCR = OptLength;
AT91C_BASE_SPI0->SPI_TPR = OptCode;
AT91C_BASE_SPI0->SPI_TCR = OptLength;
AT91C_BASE_SPI0->SPI_RNPR = Data;
AT91C_BASE_SPI0->SPI_RNCR = DataLength;
AT91C_BASE_SPI0->SPI_TNPR = Data;
AT91C_BASE_SPI0->SPI_TNCR = DataLength;
//清中断
//AT91C_BASE_AIC->AIC_ICCR = (unsigned int)0x1<<4;
//开SPI中断
AT91C_BASE_SPI0->SPI_IER = AT91C_SPI_RXBUFF;
//使能PDC
AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_RXTEN | AT91C_PDC_TXTEN;
}
//*----------------------------------------------------------------------
//* 函数名称 : GetFlashStatus
//* 功能描述 : 获取Flash的状态
//* 入口参数 : 无
//* 出口参数 : unsigned char 状态
//*----------------------------------------------------------------------
unsigned char GetFlashStatus()
{
unsigned char Status;
unsigned char Cmd;
Cmd = 0x57;
IsTransfer = 1;
TransferData(&Cmd,1,&Status,1);
while(IsTransfer);
return Status;
}
//*----------------------------------------------------------------------
//* 函数名称 : FlashWrite
//* 功能描述 : Flash写函数
//* 入口参数 : 操作的页地址OptPage,操作的位地址OptByte
//* : 存放数据指针*OptData,数据长度DataLength
//* 出口参数 : 无
//*----------------------------------------------------------------------
void FlashWrite(unsigned short OptPage,
unsigned short OptByte,
unsigned char *OptData,
unsigned int DataLength)
{
unsigned char status;
//组装操作码
unsigned int Cmd = 0;
Cmd = (unsigned int)0x82<<24;
Cmd |= OptPage<<9;
Cmd |= OptByte;
Cmd = HighToLow(Cmd);
//传输数据
IsTransfer = 1;
TransferData(&Cmd,4,OptData,DataLength);
while(IsTransfer);
//等待写入结束
while(1)
{
status = GetFlashStatus();
if(status==(unsigned char)0xA4)
break;
}
}
//*----------------------------------------------------------------------
//* 函数名称 : FlashRead
//* 功能描述 : Flash读函数
//* 入口参数 : 操作的页地址OptPage,操作的位地址OptByte
//* : 存放数据指针*OptData,数据长度DataLength
//* 出口参数 : 无
//*----------------------------------------------------------------------
void FlashRead(unsigned short OptPage,
unsigned short OptByte,
unsigned char *OptData,
unsigned int DataLength)
{
//组装操作码
unsigned int Cmd[2] = {0};
Cmd[0] = 0x52<<24;
Cmd[0] |= OptPage<<9;
Cmd[0] |= OptByte;
Cmd[0] = HighToLow(Cmd[0]);
//传输数据
IsTransfer = 1;
TransferData(Cmd,8,OptData,DataLength);
while(IsTransfer);
}
//*----------------------------------------------------------------------
//* 函数名称 : CMain
//* 功能描述 : 主函数
//* 入口参数 : 无
//* 出口参数 : 无
//*----------------------------------------------------------------------
int CMain()
{
int i;
unsigned char status;
unsigned char s[6] = "hello";
//硬件初始化
HardwareInit();
//读取状态
status = GetFlashStatus();
//写入数据
FlashWrite(5,2,s,5);
status = GetFlashStatus();
//读出数据
memset(s,0,5);
FlashRead(5,2,s,5);
//读取状态
status = GetFlashStatus();
//*结束后闪灯----------------------
AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA8;
AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA8;
while(1)
{
AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA8;
for(i=0;i<1000000;i++);
AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA8;
for(i=0;i<1000000;i++);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -