按键扫描
KEY_Init(void);
while(t--)//延时,同时扫描按键
{
delay_ms(1);
key=KEY_Scan(0);
if(key==KEY0_PRES)goto UPD;
}
KEY_Init 按键初始化
//按键初始化函数
void KEY_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//WK_UP对应引脚PA0
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN ;//下拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0
}
之所以0 1 2上拉是因为导通后变低。而WK_UP导通后是高。
KEY_Scan
//按键处理函数
//返回按键值
//mode:0,不支持连续按;1,支持连续按;
//0,没有任何按键按下
//1,KEY0按下
//2,KEY1按下
//3,KEY2按下
//4,WKUP按下 WK_UP
//注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1;//按键按松开标志
if(mode)key_up=1; //支持连按
if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
{
delay_ms(10);//去抖动
key_up=0;
if(KEY0==0)return 1;
else if(KEY1==0)return 2;
else if(KEY2==0)return 3;
else if(WK_UP==1)return 4;
}else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
return 0;// 无按键按下
}
LED闪烁
LED_Init(void);
LED0=!LED0;
LED_Init
//初始化PF9和PF10为输出口.并使能这两个口的时钟
//LED IO初始化
void LED_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//GPIOF9,F10初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化
GPIO_SetBits(GPIOF,GPIO_Pin_9 | GPIO_Pin_10);//GPIOF9,F10设置高,灯灭
}
LED0
//LED端口定义
#define LED0 PFout(9) // DS0
#define LED1 PFout(10) // DS1
SPI
//W25 IC复位
void SpiFlash_Rest(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
//有些地方使用了 16 24 32 位模式 所以这里会重新设置一遍
SPI_SET_DATA_WIDTH(SPI1, 8);//设置SPI为8位模式
au32SourceData = 0xFF;//复位指令
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//选择模具 IChange == 0 或 1
void SpiFlash_IC_Change(u8 IChange)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);//设置SPI为8位模式
//选择模具指令 选择W25M02GV内的两片W25N01GV中的其中一片 然后进行操作
au32SourceData = 0xC2;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = IChange;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//读取IC ID值 一共24位
unsigned int SpiFlash_ReadMidDid(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x9F;//读取ID指令 9F 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
//如果不想更改SPI设置 也可以拆成3个8位来操作
SPI_SET_DATA_WIDTH(SPI1, 24);//设置SPI为24位模式
I2S_CLR_RX_FIFO(SPI1);//清除SPI缓存
// 接收
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
//导出SPI缓存数据
au32DestinationData = SPI_READ_RX(SPI1);
return (au32DestinationData & 0xffffff);
}
//写寄存器1
void SpiFlash_WriteStatusReg1(u8 SRData)
{ unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//写寄存器1指令: 01 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;;//写寄存器1:数据
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//写状态寄存器2
void SpiFlash_WriteStatusReg2(u8 SRData)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x01;//写寄存器2指令: 01 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = SRData;//写寄存器2:数据
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
}
//读寄存器1
unsigned int SpiFlash_ReadStatusReg1(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器1指令: 05 A0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xA0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);//导致寄存器1数据
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//读寄存器2
unsigned int SpiFlash_ReadStatusReg2(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1); SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器2指令: 05 B0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xB0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//读寄存器3
unsigned int SpiFlash_ReadStatusReg3(void)
{
unsigned int au32SourceData;
unsigned int au32DestinationData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x05;//读寄存器2指令: 05 C0
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0xC0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);
au32SourceData = 0X0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
return (au32DestinationData & 0xFF);
}
//等待ic空闲
void SpiFlash_WaitReady(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue & 1;
}while(ReturnValue != 0);
}
//判断是否正在写入IC
void SpiFlash_WaitWEL_1(void)
{
unsigned int ReturnValue;
do
{ ReturnValue = SpiFlash_ReadStatusReg3();
ReturnValue = ReturnValue | 0XFD;
}while(ReturnValue != 0XFF);
}
//擦除一块数据 64页 :64*2048=128k 字节
void SpiFlash_PageErase(u32 StartAddress)
{ unsigned int au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//写启用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0xD8;//擦除块 指令 D8 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
//改块64页中任意一页地址
au32SourceData=ADDR_Row_PA15_PA0(StartAddress);
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
}
//擦除功能函数
void SpiFlash_ChipErase(u32 StartAddress)
{
SpiFlash_PageErase(StartAddress);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x04)//擦除失败
{
//printf("\r\nErase_Error\r\n");
SpiFlash_PageErase(StartAddress);
}
SpiFlash_WaitReady();
}
//写入数据功能函数
//StartAddress1 12~27位: 页地址
//StartAddress1 0~11位:页内数据位置
//ByteCount字节个数
void SpiFlash_WriteData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int Counter;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x06;//写启用指令 06
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SpiFlash_WaitWEL_1();
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x02;//数据写入IC缓冲区指令 02
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16); au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//页内位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
for(Counter = 0; Counter < ByteCount; Counter++)//数据写入IC换冲执行过程
{
au32SourceData = DataBuffer[Counter];
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
SPI_SET_SS_LOW(SPI1);
au32SourceData = 0x10;//换冲导入存储区指令 10 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData>>12);//页地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();//等闲
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x08)//写入失败
{
//printf("\r\nWrite_Error\r\n");
}
SpiFlash_WaitReady();
}
//一页数据导出到IC缓冲区
void SpiFlash_LoadData(u32 StartAddress1)
{
u32 au32SourceData;
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x13;//页数据读取到缓存指令 13 00
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=(u16)(StartAddress1>>12);//页地址
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_SS_HIGH(SPI1);
sys_delayms(2);
SpiFlash_WaitReady();//等闲
}
//读出数据功能函数
//StartAddress1 12~27位: 页地址
//StartAddress1 0~11位:页内数据位置
//ByteCount字节个数void SpiFlash_ReadData(u8 *DataBuffer, u32 StartAddress1, unsigned int ByteCount)
{
u32 au32SourceData;
unsigned int au32DestinationData;
unsigned int Counter;
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x20)//读取失败
{
//printf("\r\nRead_Load_Error\r\n");
SpiFlash_LoadData(StartAddress1);
W25M_STR3=SpiFlash_ReadStatusReg3();//判断是否成功
if(W25M_STR3 & 0x20)//读取失败
{
//UART1_PUTS(":读取失败\r\n");
}
}
SPI_SET_SS_LOW(SPI1);
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x03;//读取IC缓冲区数据指令 03
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 16);
au32SourceData=StartAddress1;
au32SourceData = (u16)(au32SourceData&0x7ff);//页内位置
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
SPI_SET_DATA_WIDTH(SPI1, 8);
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
I2S_CLR_RX_FIFO(SPI1);//清空SPI缓冲区 准备接收IC缓冲区数据
for(Counter = 0; Counter < ByteCount; Counter++)
{
au32SourceData = 0x0;
SPI_WRITE_TX(SPI1, au32SourceData);while(SPI_IS_BUSY(SPI1));
au32DestinationData = SPI_READ_RX(SPI1);
DataBuffer[Counter] = (u8) au32DestinationData;
}
SPI_SET_SS_HIGH(SPI1);sys_delayms(2);
SpiFlash_WaitReady();
}
//以下是工程函数的案例
#defineW25PAGE(n)( 4096 * n )
//0 <= n < { 1024(块)*64(页)}
//注意:擦除操作时是擦除整块 SpiFlash_ChipErase(W25PAGE(n))
//拿第一块为例:n=0或n=63都是擦除第一块64个页的存储区
//参数写0并保存
void W25M_write_0(void)
{
u16 i=0;
for(i=0;i<2048;i++)
{W25M_temp[i]=0;}
SpiFlash_ChipErase(W25PAGE(0));SpiFlash_WriteData(W25M_temp, W25PAGE(0),2048);
}
//保存工程参数
void W25M_write_GongChen(void)
{
SpiFlash_ChipErase(W25PAGE(0));
SpiFlash_WriteData(W25M_temp, W25PAGE(0),500);
}
//读取工程参数
void W25M_read_GongChen(void)
{
SpiFlash_ReadData(W25M_temp,W25PAGE(0),500);
}
w25N01
/*-----------------------------------------------------------------------*/
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
/*-----------------------------------------------------------------------*/
/* If a working storage control module is available, it should be */
/* attached to the FatFs via a glue function rather than modifying it. */
/* This is an example of glue functions to attach various exsisting */
/* storage control modules to the FatFs module with a defined API. */
/*-----------------------------------------------------------------------*/
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "flash_w25n01.h"
/* Definitions of physical drive number for each drive */
#define SPI_FLASH 0
/*-----------------------------------------------------------------------*/
/* Get Drive Status */
/*-----------------------------------------------------------------------*/
DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv == SPI_FLASH)
{
return RES_OK;
}
else
{
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Inidialize a Drive */
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv == SPI_FLASH)
{
//flash_w25n01_init();
if(flash_w25n01_readID() == 0xEFAA21)
return RES_OK;
else
return RES_PARERR;
}
else
{
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Read Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_read (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
BYTE *buff, /* Data buffer to store read data */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to read */
)
{
unsigned short addr_block = 0, addr_page = 0;
if(pdrv == SPI_FLASH)
{
addr_block = sector / 64;//每块有64页
addr_page = sector % 64;
flash_w25n01_buffer_read(buff, addr_block,addr_page,0, count * 2048);
return RES_OK;
}
else
{
return RES_PARERR;
}
}
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
#if FF_FS_READONLY == 0
DRESULT disk_write (
BYTE pdrv, /* Physical drive nmuber to identify the drive */
const BYTE *buff, /* Data to be written */
DWORD sector, /* Start sector in LBA */
UINT count /* Number of sectors to write */
)
{
unsigned short addr_block = 0, addr_byte = 0;
unsigned char addr_page = 0;
if(pdrv == SPI_FLASH)
{
addr_block = sector / 64;//每块有64页
addr_page = sector % 64;
flash_w25n01_sector_write((unsigned char *)buff, addr_block,addr_page, count * 2048);
return RES_OK;
}
else
{
return RES_PARERR;
}
}
#endif
/*-----------------------------------------------------------------------*/
/* Miscellaneous Functions */
/*-----------------------------------------------------------------------*/
DRESULT disk_ioctl (
BYTE pdrv, /* Physical drive nmuber (0..) */
BYTE cmd, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
if (pdrv == SPI_FLASH)
{
switch (cmd)
{
case CTRL_SYNC:
return RES_OK;
/* 扇区数量 1024*1024*1024 =4 (MB) */
case GET_SECTOR_COUNT:
*(DWORD * )buff = 65536;//
return RES_OK;
/* 扇区大小 */
case GET_SECTOR_SIZE :
*(WORD * )buff = 2048;//spi flash的扇区大小是 2048Byte
return RES_OK;
/*块大小 */
case GET_BLOCK_SIZE :
*(DWORD * )buff = 64;//64页
return RES_OK;
default:
return RES_PARERR;
}
}
else
{
return RES_PARERR;
}
}
DWORD get_fattime(void)
{
return 0;
}
6528

被折叠的 条评论
为什么被折叠?



