#include "stm32f10x.h"
#include "hw_config.h"
/* Private typedef -----------------------------------------------------------*/
typedef void (*pFunction)(void);
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
#define ApplicationAddress 0x08003000
/* Private variables ---------------------------------------------------------*/
uint32_t l_ApplicationAddress = 0x08003000;
/* Extern variables ----------------------------------------------------------*/
pFunction Jump_To_Application;
uint32_t JumpAddress;
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数
/*初始化延迟函数*/
void delay_init(u8 SYSCLK)
{
SysTick->CTRL&=0xfffffffb; //选择内部时钟 HCLK/8
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
/*
*@ 延时Nms
*@ 注意Nms的范围
*@ Nms<=0xffffff*8/SYSCLK
*@ 对72M条件下,Nms<=1864
*/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
u8 SPI_FLASH_SendByte(u8 byte)
{
/* 等待SPI发送寄存器里的数据发送结束 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* 发送数据 */
SPI_I2S_SendData(SPI2, byte);
/* 等待接收完一字节数据 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
/* 返回接收到的数据 */
return SPI_I2S_ReceiveData(SPI2);
}
u8 SPI_FLASH_PP(u32 addr, u8 data)
{
u32 _addr = addr;
/* 发送命令 */
SPI_FLASH_SendByte(0x02);
/* 发送地址 */
_addr = (addr >> 16) & 0xff ;
SPI_FLASH_SendByte(_addr);
_addr = (addr >> 8) & 0xff ;
SPI_FLASH_SendByte(_addr);
_addr = addr & 0xff;
SPI_FLASH_SendByte(_addr);
return SPI_FLASH_SendByte(data);
}
void SPI_FLASH_WREN()
{
/* 等待SPI发送寄存器里的数据发送结束 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* 发送命令 */
SPI_I2S_SendData(SPI2, 0x06);
/* 等待接收完一字节数据 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI2);
}
u8 SPI_FLASH_RDSR(u8 *pStatus_Register)
{
/* 等待SPI发送寄存器里的数据发送结束 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* 发送命令 */
SPI_I2S_SendData(SPI2, 0x05);
/* 等待接收完一字节数据 */
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI2);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, 0xff);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
*pStatus_Register = SPI_I2S_ReceiveData(SPI2);
return 0;
}
u8 SPI_FLASH_Read(u32 byte)
{
/* 发送命令 */
SPI_FLASH_SendByte(0x03);
/* 发送地址 */
SPI_FLASH_SendByte(0x0);
SPI_FLASH_SendByte(0x0);
SPI_FLASH_SendByte(0x0);
return SPI_FLASH_SendByte(0xff);
}
u32 SPI_FLASH_ReadDeviceID(u8 *pManufacturer_ID, u8 *pMemory_type, u8 *pMemory_Density)
{
// SPI_FLASH_SendByte(0X9F);
/* 等待SPI发送寄存器里的数据发送结束 */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
/* 发送数据 */
SPI_I2S_SendData(SPI2, 0X9F);
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
SPI_I2S_ReceiveData(SPI2);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, 0XFF);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, 0XFF);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI2, 0XFF);
/* Read a byte from the FLASH */
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
*pManufacturer_ID = SPI_I2S_ReceiveData(SPI2);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
*pMemory_type = SPI_I2S_ReceiveData(SPI2);
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
*pMemory_Density = SPI_I2S_ReceiveData(SPI2);
/* 返回器件地址 */
return 0;
}
int main(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef USART_ClockInitStructure;
u8 Manufacturer_ID; u8 Memory_type; u8 Memory_Density;
u8 Status_Register;
u16 val = 0x30;
DATASTREAM_Port_Config();
#ifdef SPI2_CONFIG
/* Enable SPI2 and GPIO clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/*!< SPI_FLASH_SPI Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/*将PA5(CLK)配置成复用推挽输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/*将PA6(DO)设置成浮空输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 将PA7(DIO)设为浮空输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 将PA4(CS)设为推挽输出 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* 拉高CS,失能芯片,该语句是宏定义,就是置高PA4 */
GPIO_SetBits(GPIOB, GPIO_Pin_12); //SPI_FLASH_CS_HIGH();
/* SPI配置 */
// W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.
// Data on the DO and DIO pins are clocked out on the falling edge of CLK.
/* 将SPI设为全双工模式 */
SPI_Cmd(SPI2, DISABLE);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
/* 将SPI设为主模式*/
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
/*将SPI通信的数据大小设为8位 */
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
/* 将CLK的高电平设为空闲 */
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
/* 设置在第二个时钟沿捕获数据 */
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
/* 指定NSS信号由软件管理 */
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
/* SPI_BaudRatePrescaler用来定义波特率预分频的值,这个值用以设置发送和接收的SCK时钟 */
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;
/* SPI_FirstBit指定了数据传输从高位还是低位开始 */
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
/* SPI_CRCPolynomial定义了用于CRC值计算的多项式 */
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init(SPI2, &SPI_InitStructure);
/* Enable SPI1 */
SPI_Cmd(SPI2, ENABLE);
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |
RCC_APB2Periph_AFIO |
RCC_APB2Periph_USART1 ,
ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Pushpull out-TX A9 USART1_Tx
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //In floating in-RX A10 USART1_Rx
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 38400;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;
USART_ClockInit(USART1, &USART_ClockInitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //usart1 interrupt enable
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1, ENABLE);
/* printf first test flag */
USART_SendData(USART1, val);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
val = SPI_FLASH_ReadDeviceID(&Manufacturer_ID, &Memory_type, &Memory_Density);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
/* printf resoult */
USART_SendData(USART1, Manufacturer_ID);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, Memory_type);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
USART_SendData(USART1, Memory_Density);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// GPIO_ResetBits(GPIOB, GPIO_Pin_12);
// val = SPI_FLASH_Read(0x00000000);
// GPIO_SetBits(GPIOB, GPIO_Pin_12);
/* printf resoult */
// USART_SendData(USART1, val);
// while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
SPI_FLASH_WREN();
GPIO_SetBits(GPIOB, GPIO_Pin_12);
// GPIO_ResetBits(GPIOB, GPIO_Pin_12);
// val = SPI_FLASH_RDSR(&Status_Register);
// GPIO_SetBits(GPIOB, GPIO_Pin_12);
//
// /* printf resoult */
// USART_SendData(USART1, Status_Register);
// while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// GPIO_ResetBits(GPIOB, GPIO_Pin_12);
// SPI_FLASH_PP(0x00000000, 0x55);
// GPIO_SetBits(GPIOB, GPIO_Pin_12);
val = 0;
GPIO_ResetBits(GPIOB, GPIO_Pin_12);
val = SPI_FLASH_Read(0x00000000);
GPIO_SetBits(GPIOB, GPIO_Pin_12);
/* printf resoult */
USART_SendData(USART1, val);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
#endif
// delay_init(72);
while(1) {
// delay_ms(1500);
// DATASTREAM_Port_Write(data_received, usart1_rx_data_counts);
}
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
/* 初始化使能进入DFU模式的按钮 */
DFU_Button_Config();
/* 检查按钮是否被按下 */
if(DFU_Button_Read() != 0x00)
{
/* 测试用户程序是否以0x20000000为起始标志(用户程序的中断向量表前是栈地址,在RAM中,RAM是从0x20000000位置起始) */
if (((*(__IO uint32_t*)l_ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)
{ /* 跳转到用户程序 */
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);
Jump_To_Application = (pFunction) JumpAddress;
/* 初始化用户程序栈 */
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
}
}
/* Enter DFU mode */
while(1);
}