SRAM 本文展示了STM32 SRAM 内存扩展管理 内容涉及 : SRAM 内存扩展管理 FatFs 文件系统移植 SPI函数移植过程 SPI字节数据模拟输出独写 缓存读写 USART串口的识别 IO口输入输出 按键的外部中断处理 32位数据通讯,字符串通讯,单字符通讯
完整代码 : Git源码下载
前言
STM32F1 系列芯片使用 FSMC 外设来管理扩展的存储器,FSMC 是Flexible StaticMemory Controller 的缩写,译为灵活的静态存储控制器。它可以用于驱动包括 SRAM、NOR FLASH 以及 NAND FLSAH 类型的存储器,不能驱动如 SDRAM 这种动态的存储器而在 STM32F429 系列的控制器中,它具有 FMC 外设,支持控制 SDRAM 存储器。
在框图的右侧是 FSMC 外设相关的控制引脚,由于控制不同类型存储器的时候会有一些不同的引脚,看起来有非常多,其中地址线 FSMC_A 和数据线 FSMC_D 是所有控制器都共用的。这些 FSMC 引脚具体对应的 GPIO 端口及引脚号可在《STM32F103 规格书》中搜索查找到,不在此列出。针对本示例中的 SRAM 控制器,我们整理出以下的 FSMC 与SRAM 引脚对照表
图中左侧的是 Cortex-M3 内核的存储空间分配,右侧是 STM32 FSMC 外设的地址映射。可以看到 FSMC 的 NOR/PSRAM/SRAM/NAND FLASH 以及 PC 卡的地址都在 External RAM 地址空间内。正是因为存在这样的地址映射,使得访问 FSMC 控制的存储器时,就跟访问 STM32 的片上外设寄存器一样(片上外设的地址映射即图中左侧的“Peripheral”区域)。
FSMC 把整个 External RAM 存储区域分成了 4 个 Bank 区域,并分配了地址范围及适用的存储器类型,如 NOR 及 SRAM 存储器只能使用 Bank1 的地址。 在每个 Bank 的内部又分成了 4 个小块,每个小块有相应的控制引脚用于连接片选信号,如 FSMC_NE[4:1]信号线可用于选择 BANK1 内部的 4 小块地址区域,见图 27-8,当 STM32 访问 0x68000000-0x6BFFFFFF 地址空间时,会访问到 Bank1 的第 3 小块区域,相应的 FSMC_NE3 信号线会输出控制信号
当内核发出访问某个指向外部存储器地址时,FSMC 外设会根据配置控制信号线产生时序访问存储器,上图中的是访问外部 SRAM 时 FSMC 外设的读写时序。 以读时序为例,该图表示一个存储器操作周期由地址建立周期(ADDSET)、数据建立周期(DATAST)以及 2 个 HCLK 周期组成。在地址建立周期中,地址线发出要访问的地址,数据掩码信号线指示出要读取地址的高、低字节部分,片选信号使能存储器芯片;地址建立周期结束后读使能信号线发出读使能信号,接着存储器通过数据信号线把目标数据传输给 FSMC,FSMC 把它交给内核。 写时序类似,区别是它的一个存储器操作周期仅由地址建立周期(ADDSET)和数据建立周期(DATAST)组成,且在数据建立周期期间写使能信号线发出写信号,接着 FSMC 把数据通过数据线传输到存储器中。程,主要使用数据线向存储器传输目标数据
一、 编程要点
(1) 初始化通讯使用的目标引脚及端口时钟 (2) 使能 FSMC 外设的时钟; (3) 配置 FSMC SRAM 的时序、工作模式 (4) 建立机制访问外部 SRAM 存储器 (5) 编写测试程序,对读写数据进行校验
二、使用步骤
–理解原理图
(注意)Keil 配置状态
我的博客这里有项目配置 设计; 点击链接 (https://blog.csdn.net/u012651389/article/details/119189949)
建立主程序 main.c
代码如下 :
#include "stm32f10x.h"
#include "PROJ_book.h"
void fn_LED_Flash_Init(void);
void fn_usart_show_Init(void);
void fn_DMA_show_Init(void);
void fn_I2C_EE_Init(void);
void fn_I2C_EE_Soft_Init(void);
void fn_SPI_FLASH_Soft_Init(void);
void fn_FatFs_Document_Init(void);
void fn_SRAM_Init(void);
#define countof(a) (sizeof(a) / sizeof(*(a)))
#define _I2C_BufferSize (countof(writeData)-1)
static uint8_t writeData[_I2C_PageSize]={4,5,6,7,8,9,10,11};
static uint8_t writeData2[_I2C_PageSize]={24,25,26,27,28,29,30,31};
static uint8_t ReadData[_I2C_BufferSize]={0};
#define _SPI_BufferSize SPI_PAGE_SIZE
static uint8_t write_SPI_Data[_SPI_BufferSize]={0};
static uint8_t Read_SPI_Data[_SPI_BufferSize]={0};
int main(void)
{
fn_RCC_Init();
fn_Led_Init();
fn_Key_Init();
fn_USART_Init();
printf("\n\n\r\n********** IC系统开始运行 **********\r\n");
fn_LED_Flash_Init();
fn_usart_show_Init();
fn_EXTI_GPIO_Config();
fn_DMA_show_Init();
fn_I2C_EE_Init();
fn_I2C_EE_Soft_Init();
fn_SPI_FLASH_Soft_Init();
fn_FatFs_Document_Init();
fn_SRAM_Init();
while(1){
fn_LED_ALL_OFF();
fn_Systick_Delay(500,_Systick_ms);
__G_OUT__;
fn_Systick_Delay(500,_Systick_ms);
}
}
void fn_LED_Flash_Init(void){
uint16_t count_Init = 2;
printf("\n ---> LED开始运行 \n");
while(count_Init-->0){
fn_LED_ALL_OFF();
__R_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__G_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__B_OUT__;
fn_Systick_Delay(500,_Systick_ms);
fn_LED_ALL_OFF();
__R_OUT__;
}
}
void fn_usart_show_Init(void){
fn_Usart_Send_Byte(_DEBUG_USARTx,'\r');
printf("-->串口通信指测试完毕 \n");
fn_Usart_SendString(_DEBUG_USARTx," : wangqi \n");
}
void fn_DMA_show_Init(void){
printf("\n ---> DMA开始运行 \n");
_DMA_ROM_TO_RAM(Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer);
_DMA_RAM_TO_USART(Map_BUFFER_SIZE ,USART_Source_ADDR , aDST_Buffer);
printf("---> DMA运行完毕 \n");
}
void fn_I2C_EE_Init(void){
printf("\n-->I2C_函数写入开始 \n");
_I2C_EE_Init();
I2C_Write_fun(writeData ,EEP_Firstpage ,_I2C_BufferSize);
I2C_Read_fun(ReadData ,EEP_Firstpage ,_I2C_BufferSize);
printf("--->I2C_函数写入完毕\n\r");
}
void fn_I2C_EE_Soft_Init(void){
printf("\n-->I2C_软件函数写入开始 \n");
I2C_Soft_Init();
I2C_Soft_Write_fun(writeData2 ,EEP_Firstpage ,_I2C_BufferSize);
I2C_Soft_Read_fun(ReadData ,EEP_Firstpage ,_I2C_BufferSize);
printf("\n--->I2C_软件函数写入完毕\n\r");
}
void fn_SPI_FLASH_Soft_Init(void){
uint16_t i,FlashID;
printf("-->SPI通信指测试开始 \n");
SPI_FLASH_Init();
FlashID = SPI_Read_ID() ;
if(FlashID == _SPI_FLASH_ID){
printf("-->SPI 0x%x \n",FlashID);
}
SPI_Erase_Sector(0);
printf("\n\n-->SPI清空开始 \n");
SPI_Read_Data(Read_SPI_Data , 0, SPI_PAGE_SIZE);
SPI_Show_Data(Read_SPI_Data , SPI_PAGE_SIZE);
printf("\n\n-->SPI清空完成 \n");
for(i=0 ; i < _SPI_BufferSize ; i++){
write_SPI_Data[i] = 0xA7;
}
SPI_Show_Data(write_SPI_Data , SPI_PAGE_SIZE);
SPI_BufferWrite_Data(write_SPI_Data ,0x000000,_SPI_BufferSize);
printf("\n\n-->SPI输入完成 \n");
SPI_Read_Data(Read_SPI_Data , 0x000000, _SPI_BufferSize);
SPI_Show_Data(Read_SPI_Data , _SPI_BufferSize);
printf("-->SPI通信指测试完毕 \n");
}
void fn_FatFs_Document_Init(void){
FatFs_equipment_flash("1:");
FatFs_document_Text(FileTest_ADDR_Buffer_Document, "Wangqi加油!\n" );
file_check(FileTest_ADDR_Buffer_Document);
FatFs_document_set_content(FileTest_ADDR_Buffer_Document , FileTest_ADDR_Buffer_path , FileTest_ADDR_Buffer_NewDocument2);
file_check(FileTest_ADDR_Buffer_NewDocument2);
Scan_file_Check("1:");
FatFs_Close_flash("1:");
}
void fn_SRAM_Init(void){
printf("********** SRAM_扩展内存测试 ********** \n");
printf("-->外部SRAM_内存函数初始化开始 \n");
SRAM_Init();
printf("\n-->外部SRAM_内存函数测试开始 \n");
SRAM_Test();
printf("\n-->外部SRAM_内存函数写入开始 \n");
SRAM_Write();
}
void delay(int x){
int y = 0xFFFFF;
while((x--)>0){
while((y--)>0){
__NOP();
__NOP();
__NOP();
__NOP();
__NOP();
}
}
}
建立 SRAM 内存管理文件SRAM_book.h
代码如下 :
#ifndef __SRAM_BOOK_H_
#define __SRAM_BOOK_H_
#include "stm32f10x.h"
#define SRAM_BASE_ADDR (0x68000000)
#define SRAM_CHIP (1)
#define SRAM_SIZE (SRAM_CHIP*1024*1024)
#define SRAM_END_ADDR (SRAM_BASE_ADDR + SRAM_SIZE)
#define FSMC_A0_GPIO_PORT GPIOF
#define FSMC_A0_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A0_GPIO_PIN GPIO_Pin_0
#define FSMC_A1_GPIO_PORT GPIOF
#define FSMC_A1_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A1_GPIO_PIN GPIO_Pin_1
#define FSMC_A2_GPIO_PORT GPIOF
#define FSMC_A2_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A2_GPIO_PIN GPIO_Pin_2
#define FSMC_A3_GPIO_PORT GPIOF
#define FSMC_A3_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A3_GPIO_PIN GPIO_Pin_3
#define FSMC_A4_GPIO_PORT GPIOF
#define FSMC_A4_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A4_GPIO_PIN GPIO_Pin_4
#define FSMC_A5_GPIO_PORT GPIOF
#define FSMC_A5_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A5_GPIO_PIN GPIO_Pin_5
#define FSMC_A6_GPIO_PORT GPIOF
#define FSMC_A6_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A6_GPIO_PIN GPIO_Pin_12
#define FSMC_A7_GPIO_PORT GPIOF
#define FSMC_A7_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A7_GPIO_PIN GPIO_Pin_13
#define FSMC_A8_GPIO_PORT GPIOF
#define FSMC_A8_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A8_GPIO_PIN GPIO_Pin_14
#define FSMC_A9_GPIO_PORT GPIOF
#define FSMC_A9_GPIO_CLK RCC_APB2Periph_GPIOF
#define FSMC_A9_GPIO_PIN GPIO_Pin_15
#define FSMC_A10_GPIO_PORT GPIOG
#define FSMC_A10_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A10_GPIO_PIN GPIO_Pin_0
#define FSMC_A11_GPIO_PORT GPIOG
#define FSMC_A11_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A11_GPIO_PIN GPIO_Pin_1
#define FSMC_A12_GPIO_PORT GPIOG
#define FSMC_A12_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A12_GPIO_PIN GPIO_Pin_2
#define FSMC_A13_GPIO_PORT GPIOG
#define FSMC_A13_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A13_GPIO_PIN GPIO_Pin_3
#define FSMC_A14_GPIO_PORT GPIOG
#define FSMC_A14_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A14_GPIO_PIN GPIO_Pin_4
#define FSMC_A15_GPIO_PORT GPIOG
#define FSMC_A15_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_A15_GPIO_PIN GPIO_Pin_5
#define FSMC_A16_GPIO_PORT GPIOD
#define FSMC_A16_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A16_GPIO_PIN GPIO_Pin_11
#define FSMC_A17_GPIO_PORT GPIOD
#define FSMC_A17_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A17_GPIO_PIN GPIO_Pin_12
#define FSMC_A18_GPIO_PORT GPIOD
#define FSMC_A18_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_A18_GPIO_PIN GPIO_Pin_13
#define FSMC_D0_GPIO_PORT GPIOD
#define FSMC_D0_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D0_GPIO_PIN GPIO_Pin_14
#define FSMC_D1_GPIO_PORT GPIOD
#define FSMC_D1_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D1_GPIO_PIN GPIO_Pin_15
#define FSMC_D2_GPIO_PORT GPIOD
#define FSMC_D2_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D2_GPIO_PIN GPIO_Pin_0
#define FSMC_D3_GPIO_PORT GPIOD
#define FSMC_D3_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D3_GPIO_PIN GPIO_Pin_1
#define FSMC_D4_GPIO_PORT GPIOE
#define FSMC_D4_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D4_GPIO_PIN GPIO_Pin_7
#define FSMC_D5_GPIO_PORT GPIOE
#define FSMC_D5_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D5_GPIO_PIN GPIO_Pin_8
#define FSMC_D6_GPIO_PORT GPIOE
#define FSMC_D6_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D6_GPIO_PIN GPIO_Pin_9
#define FSMC_D7_GPIO_PORT GPIOE
#define FSMC_D7_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D7_GPIO_PIN GPIO_Pin_10
#define FSMC_D8_GPIO_PORT GPIOE
#define FSMC_D8_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D8_GPIO_PIN GPIO_Pin_11
#define FSMC_D9_GPIO_PORT GPIOE
#define FSMC_D9_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D9_GPIO_PIN GPIO_Pin_12
#define FSMC_D10_GPIO_PORT GPIOE
#define FSMC_D10_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D10_GPIO_PIN GPIO_Pin_13
#define FSMC_D11_GPIO_PORT GPIOE
#define FSMC_D11_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D11_GPIO_PIN GPIO_Pin_14
#define FSMC_D12_GPIO_PORT GPIOE
#define FSMC_D12_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_D12_GPIO_PIN GPIO_Pin_15
#define FSMC_D13_GPIO_PORT GPIOD
#define FSMC_D13_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D13_GPIO_PIN GPIO_Pin_8
#define FSMC_D14_GPIO_PORT GPIOD
#define FSMC_D14_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D14_GPIO_PIN GPIO_Pin_9
#define FSMC_D15_GPIO_PORT GPIOD
#define FSMC_D15_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_D15_GPIO_PIN GPIO_Pin_10
#define FSMC_CS_GPIO_PORT GPIOG
#define FSMC_CS_GPIO_CLK RCC_APB2Periph_GPIOG
#define FSMC_CS_GPIO_PIN GPIO_Pin_10
#define FSMC_WE_GPIO_PORT GPIOD
#define FSMC_WE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_WE_GPIO_PIN GPIO_Pin_5
#define FSMC_OE_GPIO_PORT GPIOD
#define FSMC_OE_GPIO_CLK RCC_APB2Periph_GPIOD
#define FSMC_OE_GPIO_PIN GPIO_Pin_4
#define FSMC_UDQM_GPIO_PORT GPIOE
#define FSMC_UDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_UDQM_GPIO_PIN GPIO_Pin_1
#define FSMC_LDQM_GPIO_PORT GPIOE
#define FSMC_LDQM_GPIO_CLK RCC_APB2Periph_GPIOE
#define FSMC_LDQM_GPIO_PIN GPIO_Pin_0
void SRAM_Init(void);
uint8_t SRAM_Test(void);
void SRAM_Write(void);
#endif
建立 SRAM 内存管理文件SRAM_book.c
代码如下 :
#include "SRAM_book.h"
#include "Systick_book.h"
#include "USART_book.h"
static void SRAM_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(FSMC_A0_GPIO_CLK | FSMC_A1_GPIO_CLK | FSMC_A2_GPIO_CLK |
FSMC_A3_GPIO_CLK | FSMC_A4_GPIO_CLK | FSMC_A5_GPIO_CLK |
FSMC_A6_GPIO_CLK | FSMC_A7_GPIO_CLK | FSMC_A8_GPIO_CLK |
FSMC_A9_GPIO_CLK | FSMC_A10_GPIO_CLK| FSMC_A11_GPIO_CLK|
FSMC_A12_GPIO_CLK| FSMC_A13_GPIO_CLK|FSMC_A14_GPIO_CLK|
FSMC_A15_GPIO_CLK|FSMC_A16_GPIO_CLK|FSMC_A17_GPIO_CLK|FSMC_A18_GPIO_CLK|
FSMC_D0_GPIO_CLK | FSMC_D1_GPIO_CLK | FSMC_D2_GPIO_CLK |
FSMC_D3_GPIO_CLK | FSMC_D4_GPIO_CLK | FSMC_D5_GPIO_CLK |
FSMC_D6_GPIO_CLK | FSMC_D7_GPIO_CLK | FSMC_D8_GPIO_CLK |
FSMC_D9_GPIO_CLK | FSMC_D10_GPIO_CLK| FSMC_D11_GPIO_CLK|
FSMC_D12_GPIO_CLK| FSMC_D13_GPIO_CLK| FSMC_D14_GPIO_CLK|
FSMC_D15_GPIO_CLK|
FSMC_CS_GPIO_CLK | FSMC_WE_GPIO_CLK | FSMC_OE_GPIO_CLK |
FSMC_UDQM_GPIO_CLK|FSMC_LDQM_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = FSMC_A0_GPIO_PIN;
GPIO_Init(FSMC_A0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A1_GPIO_PIN;
GPIO_Init(FSMC_A1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A2_GPIO_PIN;
GPIO_Init(FSMC_A2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A3_GPIO_PIN;
GPIO_Init(FSMC_A3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A4_GPIO_PIN;
GPIO_Init(FSMC_A4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A5_GPIO_PIN;
GPIO_Init(FSMC_A5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A6_GPIO_PIN;
GPIO_Init(FSMC_A6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A7_GPIO_PIN;
GPIO_Init(FSMC_A7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A8_GPIO_PIN;
GPIO_Init(FSMC_A8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A9_GPIO_PIN;
GPIO_Init(FSMC_A9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A10_GPIO_PIN;
GPIO_Init(FSMC_A10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A11_GPIO_PIN;
GPIO_Init(FSMC_A11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A12_GPIO_PIN;
GPIO_Init(FSMC_A12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A13_GPIO_PIN;
GPIO_Init(FSMC_A13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A14_GPIO_PIN;
GPIO_Init(FSMC_A14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A15_GPIO_PIN;
GPIO_Init(FSMC_A15_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A16_GPIO_PIN;
GPIO_Init(FSMC_A16_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A17_GPIO_PIN;
GPIO_Init(FSMC_A17_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_A18_GPIO_PIN;
GPIO_Init(FSMC_A18_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D0_GPIO_PIN;
GPIO_Init(FSMC_D0_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D1_GPIO_PIN;
GPIO_Init(FSMC_D1_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D2_GPIO_PIN;
GPIO_Init(FSMC_D2_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D3_GPIO_PIN;
GPIO_Init(FSMC_D3_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D4_GPIO_PIN;
GPIO_Init(FSMC_D4_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D5_GPIO_PIN;
GPIO_Init(FSMC_D5_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D6_GPIO_PIN;
GPIO_Init(FSMC_D6_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D7_GPIO_PIN;
GPIO_Init(FSMC_D7_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D8_GPIO_PIN;
GPIO_Init(FSMC_D8_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D9_GPIO_PIN;
GPIO_Init(FSMC_D9_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D10_GPIO_PIN;
GPIO_Init(FSMC_D10_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D11_GPIO_PIN;
GPIO_Init(FSMC_D11_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D12_GPIO_PIN;
GPIO_Init(FSMC_D12_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D13_GPIO_PIN;
GPIO_Init(FSMC_D13_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D14_GPIO_PIN;
GPIO_Init(FSMC_D14_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_D15_GPIO_PIN;
GPIO_Init(FSMC_D15_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_CS_GPIO_PIN;
GPIO_Init(FSMC_CS_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_WE_GPIO_PIN;
GPIO_Init(FSMC_WE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_OE_GPIO_PIN;
GPIO_Init(FSMC_OE_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_UDQM_GPIO_PIN;
GPIO_Init(FSMC_UDQM_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = FSMC_LDQM_GPIO_PIN;
GPIO_Init(FSMC_LDQM_GPIO_PORT, &GPIO_InitStructure);
}
static void FSMC_ModleConfig(void){
FSMC_NORSRAMTimingInitTypeDef readTimingInitStruct ;
FSMC_NORSRAMTimingInitTypeDef writeTimingInitStruct ;
FSMC_NORSRAMInitTypeDef SRAMInitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC,ENABLE);
readTimingInitStruct.FSMC_AccessMode = FSMC_AccessMode_A ;
readTimingInitStruct.FSMC_AddressHoldTime = 0;
readTimingInitStruct.FSMC_BusTurnAroundDuration = 0;
readTimingInitStruct.FSMC_CLKDivision = 0;
readTimingInitStruct.FSMC_DataLatency = 0;
readTimingInitStruct.FSMC_AddressSetupTime = 0;
readTimingInitStruct.FSMC_DataSetupTime =2;
writeTimingInitStruct.FSMC_AccessMode = FSMC_AccessMode_A ;
writeTimingInitStruct.FSMC_AddressHoldTime = 0;
writeTimingInitStruct.FSMC_BusTurnAroundDuration = 0;
writeTimingInitStruct.FSMC_CLKDivision = 0;
writeTimingInitStruct.FSMC_DataLatency = 0;
writeTimingInitStruct.FSMC_AddressSetupTime = 0;
writeTimingInitStruct.FSMC_DataSetupTime =2;
SRAMInitStruct.FSMC_Bank = FSMC_Bank1_NORSRAM3;
SRAMInitStruct.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
SRAMInitStruct.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
SRAMInitStruct.FSMC_MemoryType = FSMC_MemoryType_SRAM;
SRAMInitStruct.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable ;
SRAMInitStruct.FSMC_AsynchronousWait = FSMC_AsynchronousWait_Disable;
SRAMInitStruct.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
SRAMInitStruct.FSMC_WaitSignal = FSMC_WaitSignal_Disable;
SRAMInitStruct.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;
SRAMInitStruct.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;
SRAMInitStruct.FSMC_WrapMode = FSMC_WrapMode_Disable;
SRAMInitStruct.FSMC_WriteBurst = FSMC_WriteBurst_Disable;
SRAMInitStruct.FSMC_WriteOperation = FSMC_WriteOperation_Enable;
SRAMInitStruct.FSMC_ReadWriteTimingStruct = &readTimingInitStruct;
SRAMInitStruct.FSMC_WriteTimingStruct = &writeTimingInitStruct;
FSMC_NORSRAMInit(&SRAMInitStruct);
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3,ENABLE);
}
uint8_t SRAM_Test(void){
uint32_t counter=0;
uint8_t ubWritedata_8b = 0, ubReaddata_8b = 0;
uint16_t uhWritedata_16b = 0, uhReaddata_16b = 0;
printf("正在检测SRAM,以8位、16位的方式读写sram...");
for (counter = 0x00; counter < SRAM_SIZE; counter++)
{
*(__IO uint8_t*) (SRAM_BASE_ADDR + counter) = (uint8_t)0x0;
}
for (counter = 0; counter < SRAM_SIZE; counter++)
{
*(__IO uint8_t*) (SRAM_BASE_ADDR + counter) = (uint8_t)(ubWritedata_8b + counter);
}
for(counter = 0; counter<SRAM_SIZE;counter++ )
{
ubReaddata_8b = *(__IO uint8_t*)(SRAM_BASE_ADDR + counter);
if(ubReaddata_8b != (uint8_t)(ubWritedata_8b + counter))
{
printf("8位数据读写错误!");
return 0;
}
}
for (counter = 0x00; counter < SRAM_SIZE/2; counter++)
{
*(__IO uint16_t*) (SRAM_BASE_ADDR + 2*counter) = (uint16_t)0x00;
}
for (counter = 0; counter < SRAM_SIZE/2; counter++)
{
*(__IO uint16_t*) (SRAM_BASE_ADDR + 2*counter) = (uint16_t)(uhWritedata_16b + counter);
}
for(counter = 0; counter<SRAM_SIZE/2;counter++ )
{
uhReaddata_16b = *(__IO uint16_t*)(SRAM_BASE_ADDR + 2*counter);
if(uhReaddata_16b != (uint16_t)(uhWritedata_16b + counter))
{
printf("16位数据读写错误!\n");
return 0;
}
}
printf("SRAM读写测试正常!\n");
return 1;
}
void SRAM_Init(void){
SRAM_GPIO_Config();
FSMC_ModleConfig();
}
static uint8_t testSRAM_Value __attribute__ ((at (SRAM_BASE_ADDR)));
void SRAM_Write(void){
uint8_t* SRAM_P ;
uint16_t* SRAM_P16 ;
float* SRAM_Pf ;
SRAM_P = (uint8_t*)SRAM_BASE_ADDR;
*SRAM_P = 0xA2;
printf("读出的数据为1: 0x%x\n",*SRAM_P);
SRAM_P16 = (uint16_t*)SRAM_BASE_ADDR;
*SRAM_P16 = 0x2AA2;
printf("读出的数据为2: 0x%x\n",*SRAM_P16);
SRAM_Pf = (float*)SRAM_BASE_ADDR;
*SRAM_Pf = 83.65;
printf("读出的数据为3: 0x%.2f\n",*SRAM_Pf);
testSRAM_Value = 0x6A;
printf("读出的数据为1: 0x%x\n",testSRAM_Value);
}
整改 系统文件diskio.c
代码如下 :
#include "diskio.h"
#include "ff.h"
#include "SPI_book.h"
#define ATA 0
#define MMC 1
#define USB 2
#define SD_CARD 0
#define SPI_FLASH 1
DSTATUS disk_status (
BYTE pdrv
)
{
DSTATUS stat = STA_NOINIT;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
if(SPI_Read_ID() == _SPI_FLASH_ID){
stat = RES_OK;
}else{
stat = RES_ERROR;
}
break;
default:
stat = STA_NOINIT;
}
return stat;
}
DSTATUS disk_initialize (
BYTE pdrv
)
{
DSTATUS stat = STA_NOINIT;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
SPI_FLASH_Init();
SPI_Flash_WAKEUP();
stat = disk_status(SPI_FLASH);
break;
default:
stat = STA_NOINIT;
}
return stat;
}
DRESULT disk_read (
BYTE pdrv,
BYTE *buff,
DWORD sector,
UINT count
)
{
DRESULT res = RES_PARERR;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
sector += 512;
SPI_Read_Data(buff,(sector << 12),(count << 12));
res = RES_OK ;
break;
default:
res = RES_PARERR;
}
return res;
}
#if _USE_WRITE
DRESULT disk_write (
BYTE pdrv,
const BYTE *buff,
DWORD sector,
UINT count
)
{
DRESULT res = RES_PARERR;
if(!count){return res;}
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :
sector += 512;
SPI_Erase_Sector(sector << 12);
SPI_BufferWrite_Data((uint8_t *)buff ,sector << 12,count << 12);
res = RES_OK ;
break;
default:
res = RES_PARERR;
}
return res;
}
#endif
#if _USE_IOCTL
DRESULT disk_ioctl (
BYTE pdrv,
BYTE cmd,
void *buff
)
{
DRESULT res = RES_PARERR;
switch (pdrv) {
case SD_CARD : break;
case SPI_FLASH :{
switch(cmd){
case GET_SECTOR_COUNT:
*(DWORD * )buff = 1280;
break;
case GET_SECTOR_SIZE:
*(DWORD * )buff = 4096;
break;
case GET_BLOCK_SIZE:
*(DWORD * )buff = 1;
break;
default:
return RES_PARERR;
}
res = RES_OK;
break;
}
default:
res = RES_PARERR;
}
return res;
}
#endif
DWORD get_fattime(void) {
return ((DWORD)(2015 - 1980) << 25)
| ((DWORD)1 << 21)
| ((DWORD)1 << 16)
| ((DWORD)0 << 11)
| ((DWORD)0 << 5)
| ((DWORD)0 >> 1);
}
修改头文件文件diskio.h
代码如下 :
#define _FFCONF 64180
#define _FS_READONLY 0
#define _FS_MINIMIZE 0
#define _USE_STRFUNC 1
#define _USE_FIND 0
#define _USE_MKFS 1
#define _USE_FASTSEEK 0
#define _USE_LABEL 0
#define _USE_FORWARD 0
#define _CODE_PAGE 936
#define _USE_LFN 2
#define _MAX_LFN 255
#define _LFN_UNICODE 0
#define _STRF_ENCODE 3
#define _FS_RPATH 0
#define _VOLUMES 2
#define _STR_VOLUME_ID 0
#define _VOLUME_STRS "RAM","NAND","CF","SD1","SD2","USB1","USB2","USB3"
#define _MULTI_PARTITION 0
#define _MIN_SS 512
#define _MAX_SS 4096
#define _USE_TRIM 0
#define _FS_NOFSINFO 0
#define _FS_TINY 0
#define _FS_NORTC 0
#define _NORTC_MON 1
#define _NORTC_MDAY 1
#define _NORTC_YEAR 2015
#define _FS_LOCK 0
#define _FS_REENTRANT 0
#define _FS_TIMEOUT 1000
#define _SYNC_t HANDLE
#define _WORD_ACCESS 0
建立FatFs传输的 头文件 FatFs_book.h
代码如下 :
#ifndef __FATFS_BOOK_H_
#define __FATFS_BOOK_H_
#include "ff.h"
extern FATFS fs;
extern FIL fnew;
extern FRESULT res_flash;
extern UINT fnum;
extern BYTE FATFS_buffer[0];
extern BYTE textFile_Buffer[];
extern BYTE textFile_Buffer2[];
extern BYTE File_Read_Buffer[1024];
#define textFile_Buffer "欢迎自己完成第一阶段回国隔离任务,后面加油 今天是个好日子,新建文件系统测试文件\r\n"
#define FileTest_ADDR_Buffer_Document "1:Wangqi.txt"
#define FileTest_ADDR_Buffer_NewDocument "1:Wangqi/Wangqi.txt"
#define FileTest_ADDR_Buffer_path "1:test"
#define FileTest_ADDR_Buffer_NewDocument2 "1:test/testdir.txt"
FRESULT FatFs_equipment_flash(
const TCHAR* path
);
FRESULT FatFs_Close_flash(
const TCHAR* path
);
BYTE* FatFs_document_Text(
const TCHAR* _File_ADDR ,
BYTE* Text_Buffer
);
void FatFs_document_set_content(
const TCHAR* _File_ADDR ,
const TCHAR* _File_OldPath ,
const TCHAR* _File_NewPath
);
FRESULT file_check(const TCHAR* FileTest_ADDR);
FRESULT Scan_file_Check(const TCHAR* File_ADDR);
#endif
建立FatFs传输的 头文件 FatFs_book.c
代码如下 :
#include "FatFs_book.h"
#include "Systick_book.h"
#include "USART_book.h"
#include "string.h"
FATFS fs;
FIL fnew;
FRESULT res_flash;
UINT fnum;
BYTE FATFS_buffer[0];
FRESULT FatFs_equipment_flash(
const TCHAR* path
){
DIR dir;
FATFS *pfs;
DWORD fre_clust , fre_sect , tot_sect ;
printf("\n********** 外部SPIFlash挂载文件系统 **********\r\n");
printf(" 在外部SPI Flash挂载文件系统,文件系统挂载时会对SPI设备初始化\r\n");
res_flash = f_mount(&fs ,path,1);
if(res_flash == FR_NO_FILESYSTEM ){
printf("》FLASH 还没有文件系统,即将进行Flash FatFS 格式化...\r\n");
res_flash=f_mkfs(path,0,0);
if(res_flash == FR_OK ){
printf("》FLASH 已成功格式化文件系统。\r\n");
res_flash = f_mount(NULL ,path ,1);
res_flash = f_mount(&fs ,path ,1);
}else{
printf("》格式化失败。 \r\n");
return res_flash;
}
}
else if(res_flash != FR_OK){
printf("!外部 Flash 挂载文件系统失败。(%d)\r\n",res_flash);
printf("!可能原因:SPI Flash 初始化不成功。\r\n");
return res_flash;
}
else{
printf("》文件系统挂载成功,可以进行读写测试\r\n");
}
res_flash = f_getfree(path ,&fre_clust ,&pfs );
tot_sect = (pfs->n_fatent-2)*pfs->csize ;
fre_sect = fre_clust * pfs->csize ;
printf("》设备总空间:%10lu KB。\n》可用空间: %10lu KB。\r\n", tot_sect<<2, fre_sect<<2);
return FR_OK;
}
FRESULT FatFs_Close_flash(
const TCHAR* path
){
res_flash=f_mkfs(path,0,0);
return f_mount(NULL ,path ,1);
}
BYTE* FatFs_document_Text(
const TCHAR* _File_ADDR ,
BYTE* Text_Buffer
){
BYTE File_Read_Buffer[1024]={0} ;
printf("\n******** 文件%s定位和格式化写入功能测试 ********\r\n",File_Read_Buffer);
res_flash = f_open(&fnew , _File_ADDR, FA_OPEN_ALWAYS|FA_WRITE|FA_READ );
if( res_flash == FR_OK ){
printf("******** 文件定位追加内容 ********\r\n");
res_flash = f_lseek(&fnew , f_size(&fnew));
if( res_flash == FR_OK ){
f_printf(&fnew ,Text_Buffer );
res_flash = f_lseek(&fnew,0);
res_flash = f_read(&fnew , File_Read_Buffer , f_size(&fnew),&fnum );
if(res_flash == FR_OK){
printf("> 文件内容:\n%s\n" ,File_Read_Buffer );
}
}
}
else{
printf("!! 打开文件失败:%d\n",res_flash);
printf("!! 或许需要再次运行“FatFs移植与读写测试”工程\n");
}
f_close(&fnew);
return File_Read_Buffer;
}
void FatFs_document_set_content(
const TCHAR* _File_ADDR ,
const TCHAR* _File_OldPath ,
const TCHAR* _File_NewPath
){
DIR dir;
printf("\n********** 目录创建和重命名功能测试 **********\r\n");
res_flash = f_opendir(&dir,_File_OldPath);
if(res_flash != FR_OK){
printf("!! 打开目录%s 失败开始尝试创建新的目录\n",_File_OldPath);
res_flash = f_mkdir(_File_OldPath);
res_flash = f_opendir(&dir,_File_OldPath);
if(res_flash != FR_OK){
printf("!! 创建新的目录还是失败(%d) \n",res_flash);
return;
}
}
else{
printf("!! 如果目录已经存在,关闭它\n");
res_flash = f_closedir(&dir);
f_unlink(_File_NewPath);
}
res_flash=f_rename(_File_ADDR , _File_NewPath);
printf("> 重命名并移动文件%d完成 \n",res_flash);
}
FRESULT file_check(const TCHAR* File_ADDR){
static FILINFO fno;
printf("\n********** file_check 测试 **********\r\n");
res_flash = f_stat(File_ADDR,&fno);
if(res_flash==FR_OK){
printf("%s 文件信息:\n",File_ADDR);
printf("》文件大小: %ld(字节)\n", fno.fsize);
printf("》时间戳: %u/%02u/%02u, %02u:%02u\n",
(fno.fdate >> 9) + 1980, fno.fdate >> 5 & 15, fno.fdate & 31,
fno.ftime >> 11, fno.ftime >> 5 & 63);
printf("》属性: %c%c%c%c%c\n\n",
(fno.fattrib & AM_DIR) ? 'D' : '-',
(fno.fattrib & AM_RDO) ? 'R' : '-',
(fno.fattrib & AM_HID) ? 'H' : '-',
(fno.fattrib & AM_SYS) ? 'S' : '-',
(fno.fattrib & AM_ARC) ? 'A' : '-');
}
else{
printf("》错误 %ld(字节)\n",res_flash);
}
return res_flash;
}
static FRESULT scan_file(char* File_ADDR){
FRESULT res;
FILINFO fno;
DIR dir;
int i;
TCHAR* fn;
#if _USE_LFN
static char lfn[_MAX_LFN*2 + 1];
fno.lfname = lfn;
fno.lfsize = sizeof(lfn);
#endif
res = f_opendir(&dir, File_ADDR);
if(res == FR_OK){
i = strlen(File_ADDR);
while(1){
res = f_readdir(&dir , &fno);
if((res != FR_OK) || (fno.fname[0] == 0 )){
break;}
#if _USE_LFN
fn = *fno.lfname ?fno.lfname : fno.fname ;
#else
fn = fno.fname;
#endif
if(*fn == '.'){continue;}
if( fno.fattrib & AM_DIR ){
sprintf(&File_ADDR[i], "/%s", fn);
res = scan_file(File_ADDR);
File_ADDR[i] = 0;
if(res != FR_OK ){break;}
}else{
printf( "%s/%s\r\n" , File_ADDR , fn);
}
}
}
else{
printf("》错误 %d \n",res);
}
return res;
}
FRESULT Scan_file_Check(const TCHAR* File_ADDR){
BYTE fpath[100];
printf("\n********** file_路径测试 **********\r\n");
strcpy(fpath,File_ADDR);
return scan_file(fpath);
}
建立SPI传输的 头文件 SPI_book.h
代码如下 :
#ifndef __SPI_BOOK_H_
#define __SPI_BOOK_H_
#include "stm32f10x.h"
#define _SPI_FLASH_ID 0XEF4017
#define _FLASH_SPIx SPI1
#define _FLASH_SPI_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _FLASH_SPI_CLK RCC_APB2Periph_SPI1
#define _FLASH_SPI_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _FLASH_SPI_GPIO_CLK RCC_APB2Periph_GPIOA
#define _FLASH_SPI_SCL_PORT GPIOA
#define _FLASH_SPI_SCL_PIN GPIO_Pin_5
#define _FLASH_SPI_MISO_PORT GPIOA
#define _FLASH_SPI_MISO_PIN GPIO_Pin_6
#define _FLASH_SPI_MOSI_PORT GPIOA
#define _FLASH_SPI_MOSI_PIN GPIO_Pin_7
#define _FLASH_SPI_CSS_PORT GPIOA
#define _FLASH_SPI_CSS_PIN GPIO_Pin_4
#define _FLASH_CSS_HIGH() _FLASH_SPI_CSS_PORT->BSRR = _FLASH_SPI_CSS_PIN
#define _FLASH_CSS_LOW() _FLASH_SPI_CSS_PORT->BRR = _FLASH_SPI_CSS_PIN
#define FLASH_SPI_TIMEOUT ((uint32_t)0x6000)
#define FLASH_SPI_LONG_TIMEOUT ((uint32_t)(10*FLASH_SPI_TIMEOUT))
#define FLASH_ERROR(fmt,arg...) printf("<<-FLASH-ERROR->> "fmt"\n",##arg)
#define SPI_PAGE_SIZE 4096
#define SPI_PAGE_Write_SIZE 256
#define FLASH_SPI_DUMMY 0x00
#define FLASH_SPI_READ_JEDEC_ID 0x9f
#define FLASH_SPI_REASE_SECTOR 0x20
#define FLASH_SPI_READ_STATUS 0x05
#define FLASH_SPI_READ_DATA 0x03
#define FLASH_SPI_WRITE_ENABLE 0x06
#define FLASH_SPI_WRITE_DATA 0x02
#define FLASH_SPI_ChipErase 0xC7
void SPI_FLASH_Init(void);
uint32_t SPI_Read_ID(void);
uint32_t SPI_Read_DeviceID(void);
void SPI_Erase_Sector(uint32_t addr);
void SPI_FLASH_BulkErase(void);
void SPI_Read_Data(uint8_t *readBuffer , uint32_t addr ,uint16_t numByteToRead );
void SPI_BufferRead_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite );
void SPI_Write_Data(uint8_t *writeBuffer , uint32_t addr ,uint16_t numByteToRead );
void SPI_BufferWrite_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite );
void SPI_Show_Data(uint8_t *readBuffer , uint16_t numByteToRead);
#endif
建立SPI传输的 头文件 SPI_book.c
代码如下 :
#include "SPI_book.h"
#include "Systick_book.h"
static __IO uint32_t SPITimeout = FLASH_SPI_LONG_TIMEOUT;
static void SPI_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_FLASH_SPI_APBxClock_FUN(_FLASH_SPI_CLK , ENABLE);
_FLASH_SPI_GPIO_APBxClock_FUN(_FLASH_SPI_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_MISO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_MOSI_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _FLASH_SPI_CSS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(_FLASH_SPI_SCL_PORT,&GPIO_InitStructure);
_FLASH_CSS_HIGH();
}
static void SPI_Mode_Config(void){
SPI_InitTypeDef SPI_InitStructure;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2 ;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge ;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex ;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master ;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_Init(_FLASH_SPIx , &SPI_InitStructure );
SPI_Cmd(_FLASH_SPIx , ENABLE);
}
void SPI_FLASH_Init(void){
SPI_GPIO_Config();
SPI_Mode_Config();
}
static uint32_t SPI_TIMEOUT_UserCallback(uint8_t errorCode)
{
FLASH_ERROR("SPI 等待超时!errorCode = %d",errorCode);
return 0;
}
static uint8_t SPI_FLASH_Send_Byte(uint8_t data){
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET){
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(0);}
}
SPI_I2S_SendData(_FLASH_SPIx , data);
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET){
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(1);}
}
return SPI_I2S_ReceiveData(_FLASH_SPIx);
}
static uint8_t SPI_FLASH_SendHalf_Byte(uint16_t Halfdata){
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_TXE) == RESET){
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(2);}
}
SPI_I2S_SendData(_FLASH_SPIx , Halfdata);
SPITimeout = FLASH_SPI_TIMEOUT;
while(SPI_I2S_GetFlagStatus(_FLASH_SPIx,SPI_I2S_FLAG_RXNE) == RESET){
if(SPITimeout--==0) {return SPI_TIMEOUT_UserCallback(3);}
}
return SPI_I2S_ReceiveData(_FLASH_SPIx);
}
uint32_t SPI_Read_ID(void){
uint32_t flash_id;
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_READ_JEDEC_ID);
flash_id = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
flash_id<<=8;
flash_id|=SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
flash_id<<=8;
flash_id|=SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
_FLASH_CSS_HIGH();
return flash_id;
}
static void SPI_Write_Enable(void){
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_WRITE_ENABLE);
_FLASH_CSS_HIGH();
}
static SPI_WaitForWriteEnd(void){
uint8_t status_reg = 0;
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_READ_STATUS);
do{
status_reg = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
}while((status_reg & 0x01)==1);
_FLASH_CSS_HIGH();
}
void SPI_Erase_Sector(uint32_t addr){
SPI_Write_Enable();
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_REASE_SECTOR);
SPI_FLASH_Send_Byte((addr & 0xFF0000) >> 16);
SPI_FLASH_Send_Byte((addr & 0xFF00) >> 8);
SPI_FLASH_Send_Byte(addr & 0xFF);
_FLASH_CSS_HIGH();
SPI_WaitForWriteEnd();
}
void SPI_FLASH_BulkErase(void){
SPI_Write_Enable();
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_ChipErase);
_FLASH_CSS_HIGH();
SPI_WaitForWriteEnd();
}
void SPI_Read_Data(uint8_t *readBuffer , uint32_t addr ,uint16_t numByteToRead ){
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_READ_DATA);
SPI_FLASH_Send_Byte((addr>>16)&0xff);
SPI_FLASH_Send_Byte((addr>>8)&0xff);
SPI_FLASH_Send_Byte(addr&0xff);
while(numByteToRead--){
*readBuffer = SPI_FLASH_Send_Byte(FLASH_SPI_DUMMY);
readBuffer++;
}
_FLASH_CSS_HIGH();
}
void SPI_Write_Data(uint8_t *writeBuffer , uint32_t addr ,uint16_t numByteToRead ){
SPI_Write_Enable();
_FLASH_CSS_LOW();
SPI_FLASH_Send_Byte(FLASH_SPI_WRITE_DATA);
SPI_FLASH_Send_Byte((addr&0xff0000)>>16);
SPI_FLASH_Send_Byte((addr&0xff00)>>8);
SPI_FLASH_Send_Byte(addr&0xff);
if(numByteToRead > SPI_PAGE_SIZE){
numByteToRead = SPI_PAGE_SIZE;
printf("SPI_FLASH_PageWrite too large!\n");
}
while(numByteToRead--){
SPI_FLASH_Send_Byte(*writeBuffer);
writeBuffer++;
}
_FLASH_CSS_HIGH();
SPI_WaitForWriteEnd();
}
void SPI_BufferWrite_Data(uint8_t *writeBuffer , uint32_t WriteAddr ,uint16_t numByteToWrite ){
uint32_t NumOfPage , NumOfSingle , BufferAddr ,count , temp;
if(numByteToWrite == 0){printf("SPI_FLASH_PageWrite too small!\n"); return;}
BufferAddr = WriteAddr % SPI_PAGE_Write_SIZE;
count = SPI_PAGE_Write_SIZE - BufferAddr;
if(count >= numByteToWrite){
SPI_Write_Data(writeBuffer ,WriteAddr ,numByteToWrite );
return;
}
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)count );
temp = numByteToWrite - count ;
WriteAddr += count;
writeBuffer+=count;
NumOfPage = temp / SPI_PAGE_Write_SIZE ;
NumOfSingle = temp % SPI_PAGE_Write_SIZE ;
if(NumOfPage == 0){
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)NumOfSingle );
return;
}else{
while(NumOfPage--){
SPI_Write_Data(writeBuffer ,WriteAddr ,SPI_PAGE_Write_SIZE );
WriteAddr += SPI_PAGE_Write_SIZE;
writeBuffer += SPI_PAGE_Write_SIZE;
}
SPI_Write_Data(writeBuffer ,WriteAddr ,(uint16_t)NumOfSingle );
return;
}
}
void SPI_Show_Data(uint8_t *readBuffer , uint16_t numByteToRead){
uint32_t i;
for(i=0 ;i<numByteToRead ;i++ ){
if(i%SPI_PAGE_Write_SIZE == 0){
printf("\r\n ");
}
printf("0x%x ",readBuffer[i]);
}
}
与所有使用到 GPIO 的外设一样,都要先把使用到的 GPIO 引脚模式初始化,配置好复 用功能。GPIO 初始化流程如下: (1) 使用 GPIO_InitTypeDef定义 GPIO初始化结构体变量,以便下面用于存储 GPIO 配置; (2) 调用库函数 RCC_APB2PeriphClockCmd 来使能 SPI 引脚使用的 GPIO 端口时钟。 (3) 向 GPIO 初始化结构体赋值,把 SCK/MOSI/MISO 引脚初始化成复用推挽模式。而 CS(NSS)引脚由于使用软件控制,我们把它配置为普通的推挽输出模式。 (4) 使用以上初始化结构体的配置,调用 GPIO_Init 函数向寄存器写入参数,完成 GPIO 的 初始化 SPI_FLASH_SendByte 函数实现了前面讲解的“SPI 通讯过程”: (1) 本函数中不包含 SPI 起始和停止信号,只是收发的主要过程,所以在调用本函数 前后要做好起始和停止信号的操作; (2) 对 SPITimeout 变量赋值为宏 SPIT_FLAG_TIMEOUT。这个 SPITimeout 变量在下 面的 while 循环中每次循环减 1,该循环通过调用库函数 SPI_I2S_GetFlagStatus 检 测事件,若检测到事件,则进入通讯的下一阶段,若未检测到事件则停留在此处 一直检测,当检测 SPIT_FLAG_TIMEOUT 次都还没等待到事件则认为通讯失败, 调用的 SPI_TIMEOUT_UserCallback 输出调试信息,并退出通讯; (3) 通过检测 TXE 标志,获取发送缓冲区的状态,若发送缓冲区为空,则表示可能存 在的上一个数据已经发送完毕; (4) 等待至发送缓冲区为空后,调用库函数 SPI_I2S_SendData 把要发送的数据“byte” 写入到 SPI 的数据寄存器 DR,写入 SPI 数据寄存器的数据会存储到发送缓冲区, 由 SPI 外设发送出去; (5) 写入完毕后等待 RXNE 事件,即接收缓冲区非空事件。由于 SPI 双线全双工模式 下 MOSI 与 MISO 数据传输是同步的(请对比“SPI 通讯过程”阅读),当接收缓冲 区非空时,表示上面的数据发送完毕,且接收缓冲区也收到新的数据; (6) 等待至接收缓冲区非空时,通过调用库函数 SPI_I2S_ReceiveData 读取 SPI 的数据 寄存器 DR,就可以获取接收缓冲区中的新数据了。代码中使用关键字“return” 把接收到的这个数据作为 SPI_FLASH_SendByte 函数的返回值,所以我们可以看 到在下面定义的 SPI 接收数据函数 SPI_FLASH_ReadByte,它只是简单地调用了 SPI_FLASH_SendByte 函数发送数据“Dummy_Byte”,然后获取其返回值(因为 不关注发送的数据,所以此时的输入参数“Dummy_Byte”可以为任意值)。可以 这样做的原因是 SPI 的接收过程和发送过程实质是一样的,收发同步进行,关键 在于我们的上层应用中,关注的是发送还是接收的数据。
建立I2C模拟传输的 头文件 I2C_soft_book.h
代码如下 :
#ifndef __I2C_SOFT_BOOK_H_
#define __I2C_SOFT_BOOK_H_
#include "stm32f10x.h"
#define _Soft_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _Soft_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _Soft_I2C_SCL_PORT GPIOB
#define _Soft_I2C_SCL_PIN GPIO_Pin_6
#define _Soft_I2C_SDA_PORT GPIOB
#define _Soft_I2C_SDA_PIN GPIO_Pin_7
#define _I2C_SCL_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SCL_PIN
#define _I2C_SCL_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SCL_PIN
#define _I2C_SDA_1() _Soft_I2C_SCL_PORT->BSRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_0() _Soft_I2C_SCL_PORT->BRR = _Soft_I2C_SDA_PIN
#define _I2C_SDA_READ() ((_Soft_I2C_SCL_PORT->IDR & _Soft_I2C_SDA_PIN)!=0)
#define I2C_WR 0
#define I2C_RD 1
#define Soft_EEPROM_ADDRESS 0xA0
#define _I2C_Soft_PageSize 8
#define _I2C_Soft_SIZE 256
#define EEP_Soft_Firstpage 0x90
void I2C_Soft_Init(void);
void EE_Soft_Trase(void);
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
建立I2C模拟传输的 头文件 I2C_soft_book.c
代码如下 :
#include "I2C_soft_book.h"
#include "Systick_book.h"
static I2C_GPIO_Soft_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_Soft_I2C_GPIO_APBxClock_FUN(_Soft_I2C_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(_Soft_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _Soft_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(_Soft_I2C_SDA_PORT,&GPIO_InitStructure);
}
static void I2C_Start(void){
_I2C_SCL_1();
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
static void I2C_Stop(void){
_I2C_SDA_0();
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1();
}
static void I2C_SendByte(uint8_t _ucByte){
uint8_t i;
for( i=0; i<8;i++ ){
if(_ucByte & 0x80){
_I2C_SDA_1();
}else{
_I2C_SDA_0();
}
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
_ucByte <<=1;
fn_Systick_Delay(50,_Systick_us);
}
_I2C_SDA_1();
}
static uint8_t I2C_ReadByte(void){
uint8_t i;
uint8_t value;
value = 0;
for(i=0 ;i<8 ;i++ ){
value <<=1;
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
value++;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
return value;
}
static uint8_t I2C_WaitAck(void){
uint8_t re;
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
if(_I2C_SDA_READ()){
re = 1;
}else{
re = 0;
}
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
return re;
}
static void I2C_ACK(void){
_I2C_SDA_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
_I2C_SDA_1();
}
static void I2C_NACK(void){
_I2C_SDA_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_1();
fn_Systick_Delay(50,_Systick_us);
_I2C_SCL_0();
fn_Systick_Delay(50,_Systick_us);
}
static uint8_t I2C_CheckDevice(uint8_t _Address){
uint8_t ucAck;
I2C_GPIO_Soft_Config();
I2C_Start();
I2C_SendByte(_Address | I2C_WR);
ucAck = I2C_WaitAck();
I2C_Stop();
return ucAck;
}
static uint8_t EE_Soft_Check_State(void){
if(I2C_CheckDevice(Soft_EEPROM_ADDRESS)==0){return 1;}
else{I2C_Stop(); return 0;}
}
static uint8_t I2C_Soft_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i ;
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS | I2C_WR);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 1 !\r\n"); goto CMD_Fail;}
I2C_SendByte((uint8_t)ReadAddr);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 2 !\r\n");goto CMD_Fail;}
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_RD);
if(I2C_WaitAck()!=0){printf("EEPROM 错误3 !\r\n"); goto CMD_Fail;}
for(i=0 ;i<NumByteToRead ;i++ ){
pBuffer[i] = I2C_ReadByte();
if(i!=NumByteToRead-1){
I2C_ACK();
}else{
I2C_NACK();
}
}
I2C_Stop();
return 1;
CMD_Fail:
I2C_Stop();
return 0;
}
static uint8_t EE_Soft_WriteBytes(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
uint16_t i , m;
uint16_t usAddr;
usAddr = ReadAddr;
for(i=0 ;i<NumByteToRead;i++ ){
if((i==0)||(usAddr)&(_I2C_Soft_PageSize-1)==0){
I2C_Stop();
m = 100;
for (m = 0; m < 100; m++){
I2C_Start();
I2C_SendByte(Soft_EEPROM_ADDRESS| I2C_WR);
if(I2C_WaitAck()==0){break;}
}
if(m==100){printf("EEPROM 错误 4 !\r\n"); goto CMD_FAIL_bytes ; }
I2C_SendByte((uint8_t)usAddr);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 5 !\r\n"); goto CMD_FAIL_bytes;}
}
I2C_SendByte(pBuffer[i]);
if(I2C_WaitAck()!=0){printf("EEPROM 错误 7 !\r\n"); goto CMD_FAIL_bytes;}
usAddr++;
}
I2C_Stop();
return 1;
CMD_FAIL_bytes:
I2C_Stop();
return 0;
}
void EE_Soft_Trase(void){
uint16_t i ;
uint8_t buf[_I2C_Soft_SIZE]={0};
for(i=0 ;i<_I2C_Soft_SIZE ;i++ ){
buf[i] = 0xFF;
}
if(EE_Soft_WriteBytes(buf,0,_I2C_Soft_SIZE)==0){
printf("擦除EEPROM出错!\r\n");
return;
}else{
printf("擦除EEPROM出错!\r\n");
}
}
void I2C_Soft_Init(void){
if(EE_Soft_Check_State()==0){
printf("没有检测到串行EEPROM!\r\n");
}
}
uint8_t I2C_Soft_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
if(EE_Soft_Check_State()==0){
printf("没有检测到串行EEPROM!\r\n");
return 1;
}
if(EE_Soft_WriteBytes(pBuffer,WriteAddr ,NumByteToWrite)==0){
printf("写EEPROM错误!\r\n");
return 1;
}else{
printf("写EEPROM成功!\r\n");
}
fn_Systick_Delay(150,_Systick_us);
printf("EEPROM写入数据检查检查\r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 0;
}
uint8_t I2C_Soft_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
uint16_t i;
if(I2C_Soft_BufferRead(pBuffer,WriteAddr,NumByteToWrite)==0){
printf("读EEPROM错误!\r\n");
return 1;
}else{
printf("\n读EEPROM成功!\r\n");
}
printf("EEPROM读取数据数据检查 \r\n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf(" %d ",pBuffer[i]);
if((i & 15)==15){
printf("\r\n");
}
}
return 1;
}
建立I2C硬件传输的 头文件 I2C_book.h
代码如下 :
#ifndef __I2C_BOOK_H_
#define __I2C_BOOK_H_
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "USART_book.h"
#define _EEPROM_I2Cx I2C1
#define _EEPROM_I2C_APBxClock_FUN RCC_APB1PeriphClockCmd
#define _EEPROM_I2C_CLK RCC_APB1Periph_I2C1
#define _EEPROM_I2C_GPIO_APBxClock_FUN RCC_APB2PeriphClockCmd
#define _EEPROM_I2C_GPIO_CLK RCC_APB2Periph_GPIOB
#define _EEPROM_I2C_SCL_PORT GPIOB
#define _EEPROM_I2C_SCL_PIN GPIO_Pin_6
#define _EEPROM_I2C_SDA_PORT GPIOB
#define _EEPROM_I2C_SDA_PIN GPIO_Pin_7
#define _I2C_Speed 400000
#define _I2Cx_OWN_ADDRESS7 0x5f
#define _I2C_PageSize 8
#define EEP_Firstpage 0x90
#define EEP_SIZE 0xFF
#define EEPROM_ADDRESS 0xA0
void _I2C_EE_Init(void);
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite);
#endif
建立I2C硬件传输的 头文件 I2C_book.c
代码如下 :
#include "I2C_book.h"
#include "Systick_book.h"
static void I2C_GPIO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_EEPROM_I2C_APBxClock_FUN(_EEPROM_I2C_CLK,ENABLE);
_EEPROM_I2C_GPIO_APBxClock_FUN(_EEPROM_I2C_GPIO_CLK,ENABLE);
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(_EEPROM_I2C_SCL_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _EEPROM_I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(_EEPROM_I2C_SDA_PORT,&GPIO_InitStructure);
}
static void I2C_Mode_Config(void){
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = _I2Cx_OWN_ADDRESS7;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = _I2C_Speed;
I2C_Init(_EEPROM_I2Cx,&I2C_InitStructure);
I2C_Cmd(_EEPROM_I2Cx,ENABLE);
}
static uint32_t I2C_TIMEOUT_UserCallback(uint8_t errorCode){
fn_Usart_SendString(_DEBUG_USARTx,"I2C 等待超时!errorCode =");
printf("%d\n",errorCode);
return 0;
}
#define I2CT_FLAG_TIMEOUT ((uint32_t)0x6000)
#define I2CT_LONG_TIMEOUT ((uint32_t)(10*I2CT_FLAG_TIMEOUT))
static uint16_t I2CTimeout;
static uint32_t I2C_EE_ByteWrite(u8* pBuffer, uint8_t WriteAddr ){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(2);}
}
I2C_SendData(_EEPROM_I2Cx,*pBuffer);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
I2C_SendData(_EEPROM_I2Cx,ENABLE);
return 1;
}
static void I2C_EE_WaitEepromStandbyState(void){
vu16 SR1_Tmp = 0;
do{
I2C_GenerateSTART(_EEPROM_I2Cx,ENABLE);
SR1_Tmp = I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1);
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
}while(!(I2C_ReadRegister(_EEPROM_I2Cx, I2C_Register_SR1) & 0x0002));
I2C_ClearFlag(_EEPROM_I2Cx, I2C_FLAG_AF);
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
}
static uint8_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , ENABLE)){
if((I2CTimeout--) == 0){return I2C_TIMEOUT_UserCallback(4);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(5);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx,EEPROM_ADDRESS,I2C_Direction_Transmitter);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == ERROR){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(6);}
}
I2C_SendData(_EEPROM_I2Cx,WriteAddr);
I2CTimeout = I2CT_LONG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(7);}
}
while(NumByteToWrite--){
I2C_SendData(_EEPROM_I2Cx,*pBuffer++);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(!I2C_CheckEvent(_EEPROM_I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(8);}
}
}
I2C_GenerateSTOP(_EEPROM_I2Cx,ENABLE);
return 1;
}
#define I2C_PageSize 8
static void I2C_EE_BufferWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u8 NumOfPage = 0, NumOfSingle = 0 , Addr = 0 , count = 0,temp = 0;
Addr = WriteAddr % I2C_PageSize;
count = I2C_PageSize - Addr;
NumOfPage = NumByteToWrite / I2C_PageSize;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if(Addr == 0){
if(NumOfPage==0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
else{
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
if(NumOfSingle != 0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
else{
if(NumOfPage == 0){
if(NumOfSingle > count){
temp = NumOfSingle - count;
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count ;
pBuffer += count ;
I2C_EE_PageWrite(pBuffer , WriteAddr, temp);
I2C_EE_WaitEepromStandbyState();
}else{
I2C_EE_PageWrite(pBuffer , WriteAddr, NumByteToWrite);
I2C_EE_WaitEepromStandbyState();
}
}
else{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / I2C_PageSize ;
NumOfSingle = NumByteToWrite % I2C_PageSize;
if(count!=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, count);
I2C_EE_WaitEepromStandbyState();
WriteAddr += count ;
pBuffer += count ;
}
while(NumOfPage--){
I2C_EE_PageWrite(pBuffer , WriteAddr, I2C_PageSize);
I2C_EE_WaitEepromStandbyState();
WriteAddr += I2C_PageSize ;
pBuffer += I2C_PageSize ;
}
if(NumOfSingle !=0){
I2C_EE_PageWrite(pBuffer , WriteAddr, NumOfSingle);
I2C_EE_WaitEepromStandbyState();
}
}
}
}
static uint8_t I2C_EE_BufferRead(uint8_t* pBuffer, uint8_t ReadAddr, uint16_t NumByteToRead){
I2CTimeout = I2CT_LONG_TIMEOUT ;
while(I2C_GetFlagStatus(_EEPROM_I2Cx , I2C_FLAG_BUSY)){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(9);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(10);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Transmitter);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(11);}
}
I2C_Cmd(_EEPROM_I2Cx ,ENABLE );
I2C_SendData(_EEPROM_I2Cx, ReadAddr);
I2CTimeout = I2CT_FLAG_TIMEOUT ;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_TRANSMITTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(12);}
}
I2C_GenerateSTART(_EEPROM_I2Cx , ENABLE);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_MODE_SELECT)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(13);}
}
I2C_Send7bitAddress(_EEPROM_I2Cx , EEPROM_ADDRESS , I2C_Direction_Receiver);
I2CTimeout = I2CT_FLAG_TIMEOUT;
while(! I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)){
if((I2CTimeout--)==0){ return I2C_TIMEOUT_UserCallback(14);}
}
while(NumByteToRead){
if(NumByteToRead == 1){
I2C_AcknowledgeConfig(_EEPROM_I2Cx , DISABLE);
}
I2CTimeout = I2CT_LONG_TIMEOUT;
while(I2C_CheckEvent(_EEPROM_I2Cx , I2C_EVENT_MASTER_BYTE_RECEIVED)==0){
if((I2CTimeout--)==0){return I2C_TIMEOUT_UserCallback(3);}
}
*pBuffer = I2C_ReceiveData(_EEPROM_I2Cx);
pBuffer++;
NumByteToRead--;
}
I2C_GenerateSTOP(_EEPROM_I2Cx , ENABLE);
I2C_AcknowledgeConfig(_EEPROM_I2Cx , ENABLE);
return 1;
}
void _I2C_EE_Init(void){
I2C_GPIO_Config();
I2C_Mode_Config();
}
void I2C_Write_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_写入数据 \n");
I2C_EE_WaitEepromStandbyState();
I2C_EE_PageWrite(pBuffer,WriteAddr, NumByteToWrite);
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", *pBuffer++);
if(i%16 == 15)
printf("\n\r");
}
printf("\nI2C_写入数据完成 \n");
I2C_EE_WaitEepromStandbyState();
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
}
void I2C_Read_fun(uint8_t* pBuffer, uint8_t WriteAddr, uint16_t NumByteToWrite){
u16 i;
printf("I2C_数据检测 \n");
I2C_EE_BufferRead(pBuffer,WriteAddr,NumByteToWrite);
printf("\nI2C_数据读取完毕 \n");
for(i=0 ;i<NumByteToWrite ;i++ ){
printf("%d ", pBuffer[i]);
if(i%16 == 15)
printf("\n\r");
}
printf("\n--->I2C_数据检测完成\n");
}
建立USART传输的 头文件 USART_book.h
代码如下 :
#ifndef __USART_BOOK_H_
#define __USART_BOOK_H_
#include "stm32f10x.h"
#include <stdio.h>
#include "stm32f10x_usart.h"
#include "stm32f10x_rcc.h"
#define _DEBUG_USARTx USART1
#define _DEBUG_USART_CLK RCC_APB2Periph_USART1
#define _DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_BAUDRATE 115200
#define _DEBUG_USART_GPIO_CLK RCC_APB2Periph_GPIOA
#define _DEBUG_USART_GPIO_APBxCLKCmd RCC_APB2PeriphClockCmd
#define _DEBUG_USART_TX_GPIO_PORT GPIOA
#define _DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
#define _DEBUG_USART_TX_GPIO_MODE GPIO_Mode_AF_PP
#define _DEBUG_USART_RX_GPIO_PORT GPIOA
#define _DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
#define _DEBUG_USART_RX_GPIO_MODE GPIO_Mode_IN_FLOATING
#define _DEBUG_NVIC_USART_IRQ USART1_IRQn
#define _DRBUG_USART_IRQHandler USART1_IRQHandler
void fn_USART_IO_Config(void);
void fn_USART_Config(void);
void fn_USART_Init(void);
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch );
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str);
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch);
int fputc (int ch , FILE *f);
int fgetc(FILE *f);
void _DRBUG_USART_IRQHandler(void);
#endif
建立USART传输的C文件 USART_book.c
代码如下 :
#include "USART_book.h"
static void NVIC_Configuration(void){
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = _DEBUG_NVIC_USART_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void fn_USART_IO_Config(void){
GPIO_InitTypeDef GPIO_InitStructure;
_DEBUG_USART_GPIO_APBxCLKCmd(_DEBUG_USART_GPIO_CLK , ENABLE);
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_TX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_TX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_TX_GPIO_PORT,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = _DEBUG_USART_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = _DEBUG_USART_RX_GPIO_MODE;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(_DEBUG_USART_RX_GPIO_PORT,&GPIO_InitStructure);
}
void fn_USART_Config(void){
USART_InitTypeDef USART_InitStructure;
_DEBUG_USART_APBxClkCmd(_DEBUG_USART_CLK , ENABLE);
USART_InitStructure.USART_BaudRate = _DEBUG_USART_BAUDRATE;
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_Init(_DEBUG_USARTx , &USART_InitStructure);
NVIC_Configuration();
USART_ITConfig(_DEBUG_USARTx , USART_IT_RXNE , ENABLE);
USART_Cmd(_DEBUG_USARTx , ENABLE);
}
void fn_Usart_Send_Byte(USART_TypeDef * pUSARTx , uint8_t ch ){
USART_SendData(pUSARTx , ch);
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TXE)==RESET);
}
void fn_Usart_SendString(USART_TypeDef *pUSARTx , char * str){
unsigned int k = 0;
do{
fn_Usart_Send_Byte(pUSARTx,*(str + k++));
}while(*(str + k)!='\0');
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
void Usart_SendHalf_32_Word( USART_TypeDef * pUSARTx, uint32_t ch){
uint32_t temp_Half32;
uint8_t temp_Half=0,i_Half=4;
temp_Half32 =ch;
while(i_Half-->0){
temp_Half=(temp_Half32 & 0xFF000000)>>24;
temp_Half32<<=8;
fn_Usart_Send_Byte(pUSARTx,temp_Half);
}
while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC));
}
void fn_USART_Init(void){
fn_USART_IO_Config();
fn_USART_Config();
}
int fputc (int ch , FILE *f){
USART_SendData(_DEBUG_USARTx , (uint8_t)ch);
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
return (ch);
}
int fgetc(FILE *f){
while(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)==RESET);
return (int)USART_ReceiveData(_DEBUG_USARTx);
}
void _DRBUG_USART_IRQHandler(void){
uint8_t ucTemp = 0;
if(USART_GetITStatus(_DEBUG_USARTx,USART_IT_RXNE)!=RESET){
ucTemp = USART_ReceiveData(_DEBUG_USARTx);
USART_SendData(_DEBUG_USARTx ,ucTemp );
}
}
建立DMA传输的 头文件 DMA_book.h
代码如下 :
#ifndef __DMA_BOOK_H_
#define __DMA_BOOK_H_
#include "stm32f10x.h"
#define DMA_CLOCK RCC_AHBPeriph_DMA1
#define Map_DMA_CHANNEL DMA1_Channel6
#define Map_BUFFER_SIZE 20
#define DMA_FLAG_TC DMA1_FLAG_TC6
extern const uint32_t aSRC_Cont_Buffer[Map_BUFFER_SIZE] ;
extern uint32_t aDST_Buffer[Map_BUFFER_SIZE];
#define USART_DMA_CHANNEL DMA1_Channel4
#define USART_Source_ADDR (USART1_BASE+0x04)
extern uint32_t USART_BUFFER_SIZE ;
extern uint32_t* USART_DMA_Buffer ;
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_OutSource_ADDR, uint32_t _DMA_InSource_ADDR , uint32_t _DMA_DIR);
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength);
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength);
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR );
#define _Map_DMA_Config_ _DMA_Config(Map_DMA_CHANNEL ,Map_BUFFER_SIZE ,aSRC_Cont_Buffer , aDST_Buffer , DMA_DIR_PeripheralSRC)
#define _USART_DMA_Config_ _USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,USART_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST)
#define _DMA_InnerChange_ _Buffercmp(aSRC_Cont_Buffer , aDST_Buffer, Map_BUFFER_SIZE)
#define _RMA_InnerShow_ _Buffer_Show(aDST_Buffer, Map_BUFFER_SIZE)
#endif
建立DMA传输的C文件 DMA_book.c
代码如下 :
#include "DMA_book.h"
#include "USART_book.h"
#include "Systick_book.h"
const uint32_t aSRC_Cont_Buffer [Map_BUFFER_SIZE]={
'W','E','L','L',
'C','O','M','E',
' ','S','T','M',
'3','2',' ','S',
'T','U','D','Y',
};
uint32_t aDST_Buffer[Map_BUFFER_SIZE] ;
uint32_t* USART_DMA_Buffer ;
uint32_t USART_BUFFER_SIZE ;
void _DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
void _USART_DMA_Config(DMA_Channel_TypeDef* _DMAy_Channelx , uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR , uint32_t _DMA_DIR){
DMA_InitTypeDef DMA_InitStructure ;
RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)_DMA_Source_ADDR ;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)_DMA_AIM_ADDR;
DMA_InitStructure.DMA_DIR = _DMA_DIR ;
DMA_InitStructure.DMA_BufferSize = _BUFFER_SIZE;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(_DMAy_Channelx , &DMA_InitStructure);
DMA_Cmd(_DMAy_Channelx , ENABLE);
}
uint8_t _Buffercmp(const uint32_t *pBuffer, uint32_t * pBuffer1 , uint16_t BufferLength){
while(BufferLength--){
if(*pBuffer != *pBuffer1){
return 0;
}
pBuffer++;
pBuffer1++;
}
return 1;
}
void _Buffer_Show(uint32_t * pBuffer , uint16_t BufferLength){
while(BufferLength--){
Usart_SendHalf_32_Word(_DEBUG_USARTx,*pBuffer++);
}
}
void _DMA_ROM_TO_RAM(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
printf("开始 ROM内存到RAM内存的DMA操作 \n");
_DMA_Config(Map_DMA_CHANNEL ,_BUFFER_SIZE ,_DMA_Source_ADDR , _DMA_AIM_ADDR , DMA_DIR_PeripheralSRC);
while(DMA_GetFlagStatus(DMA_FLAG_TC) == RESET);
if(_DMA_InnerChange_== 0 ){
printf("ROM内存到DMA操作异常 \n");
}else{
printf("ROM内存到DMA操作正常 \n");
}
_RMA_InnerShow_;
}
void _DMA_RAM_TO_USART(uint32_t _BUFFER_SIZE , uint32_t _DMA_Source_ADDR, uint32_t _DMA_AIM_ADDR ){
printf("\n开始 ROM到USART的传送初始化\n");
USART_BUFFER_SIZE = _BUFFER_SIZE;
USART_DMA_Buffer = _DMA_AIM_ADDR;
_USART_DMA_Config(USART_DMA_CHANNEL ,USART_BUFFER_SIZE ,_DMA_Source_ADDR , USART_DMA_Buffer , DMA_DIR_PeripheralDST);
USART_DMACmd(_DEBUG_USARTx , USART_DMAReq_Tx , ENABLE);
fn_Systick_Delay(250,_Systick_ms);
while(USART_GetFlagStatus(_DEBUG_USARTx,USART_FLAG_TXE)==RESET);
printf("\rROM内存到USART外设的DMA操作完毕\n");
}
建立EXIT的 头文件 Exit_book.h
代码如下 :
#ifndef __EXIT_BOOK_H_
#define __EXIT_BOOK_H_
#include "stm32f10x.h"
#define _KEY_EXTI_IN_GPIO_Port GPIOA
#define _KEY_EXTI_IN_GPIO_Pin GPIO_Pin_0
#define _EXTI_IN_GPIO_PortSource GPIO_PortSourceGPIOA
#define _EXTI_IN_GPIO_PinSource GPIO_PinSource0
#define _EXTI_IN_EXTI_Line EXTI_Line0
#define _EXTI_IN_EXTI_Trigger EXTI_Trigger_Rising
#define _EXTI_IN_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN_EXTI_LineCmd ENABLE
#define _NVIC_IN_EXTI_IRQChannel EXTI0_IRQn
#define _NVIC_IN_EXTI_IRQChannelCmd ENABLE
#define _KEY2_EXTI_IN_GPIO_Port GPIOC
#define _KEY2_EXTI_IN_GPIO_Pin GPIO_Pin_13
#define _EXTI_IN2_GPIO_PortSource GPIO_PortSourceGPIOC
#define _EXTI_IN2_GPIO_PinSource GPIO_PinSource13
#define _EXTI_IN2_EXTI_Line EXTI_Line13
#define _EXTI_IN2_EXTI_Trigger EXTI_Trigger_Falling
#define _EXTI_IN2_GPIO_Clock RCC_APB2Periph_AFIO
#define _EXTI_IN2_EXTI_Mode EXTI_Mode_Interrupt
#define _EXTI_IN2_EXTI_LineCmd ENABLE
#define _NVIC_IN2_EXTI_IRQChannel EXTI15_10_IRQn
#define _NVIC_IN2_EXTI_IRQChannelCmd ENABLE
void fn_EXTI_GPIO_Config(void);
void fn_NVIC_Config(void);
void EXTI0_IRQHandler(void);
#endif
建立EXIT的C文件 Exit_book.c
代码如下 :
#include "Exit_book.h"
#include "Led_book.h"
void fn_EXTI_GPIO_Config(void){
EXTI_InitTypeDef EXIT_InitStruck;
RCC_APB2PeriphClockCmd(_EXTI_IN_GPIO_Clock , ENABLE);
GPIO_EXTILineConfig(_EXTI_IN_GPIO_PortSource | _EXTI_IN2_GPIO_PortSource , _EXTI_IN_GPIO_PinSource | _EXTI_IN2_GPIO_PinSource);
EXIT_InitStruck.EXTI_Line = _EXTI_IN_EXTI_Line ;
EXIT_InitStruck.EXTI_Mode = _EXTI_IN_EXTI_Mode;
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN_EXTI_Trigger ;
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd;
EXTI_Init(&EXIT_InitStruck);
EXIT_InitStruck.EXTI_Line = _EXTI_IN2_EXTI_Line;
EXIT_InitStruck.EXTI_Mode = _EXTI_IN2_EXTI_Mode;
EXIT_InitStruck.EXTI_Trigger = _EXTI_IN2_EXTI_Trigger;
EXIT_InitStruck.EXTI_LineCmd = _EXTI_IN_EXTI_LineCmd;
EXTI_Init(&EXIT_InitStruck);
fn_NVIC_Config();
}
void fn_NVIC_Config(void){
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN_EXTI_IRQChannel;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = _NVIC_IN_EXTI_IRQChannelCmd;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = _NVIC_IN2_EXTI_IRQChannel;
NVIC_Init(&NVIC_InitStruct);
}
void EXTI0_IRQHandler(void){
if(EXTI_GetITStatus(_EXTI_IN_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY_EXTI_IN_GPIO_Port, _KEY_EXTI_IN_GPIO_Pin)==1){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN_EXTI_Line);
}
void EXTI15_10_IRQHandler(void){
if(EXTI_GetITStatus(_EXTI_IN2_EXTI_Line)!= RESET){
if(GPIO_ReadInputDataBit(_KEY2_EXTI_IN_GPIO_Port, _KEY2_EXTI_IN_GPIO_Pin)==0){
__LED_Change__;
}
}
EXTI_ClearITPendingBit(_EXTI_IN2_EXTI_Line);
}
建立Key传输的 头文件 Key_book.h
代码如下 :
#ifndef __KEY_BOOK_H_
#define __KEY_BOOK_H_
#include "stm32f10x.h"
#include "Led_book.h"
#define KEY_IN_GPIO_Port GPIOA
#define KEY_IN_GPIO_Clock RCC_APB2Periph_GPIOA
#define KEY_IN_GPIO_Pin GPIO_Pin_0
#define KEY_IN_GPIO_Pin_Bit 0
#define Key_IN_GPIO_Modle GPIO_Mode_IN_FLOATING
#define KEY2_IN_GPIO_Port GPIOC
#define KEY2_IN_GPIO_Clock RCC_APB2Periph_GPIOC
#define KEY2_IN_GPIO_Pin GPIO_Pin_13
#define KEY2_IN_GPIO_Pin_Bit 13
#define Key2_IN_GPIO_Modle GPIO_Mode_IN_FLOATING
typedef union {
struct{
unsigned char BIT0:1;unsigned char BIT1:1;unsigned char BIT2:1;unsigned char BIT3:1;
unsigned char BIT4:1;unsigned char BIT5:1;unsigned char BIT6:1;unsigned char BIT7:1;
}DATA_BIT;
uint8_t DATA_BYTE;
}Per_key_type;
extern volatile Per_key_type key_flag;
#define bkey_10ms key_flag.DATA_BIT.BIT0
#define bkey_judge key_flag.DATA_BIT.BIT1
#define bkey_judge_long key_flag.DATA_BIT.BIT2
#define bkey_Effect key_flag.DATA_BIT.BIT3
#define bkey_LongEffect key_flag.DATA_BIT.BIT4
#define bkey_Effect_Lose key_flag.DATA_BIT.BIT5
#define bkey_Effect_LLose key_flag.DATA_BIT.BIT6
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef );
void fn_Key_Init(void);
void fn_key_judge(void);
void fn_key_Effect(void);
void fn_key_Check(void);
#endif
建立Key的C文件 Key_book.c
代码如下 :
#include "Key_book.h"
volatile Per_key_type key_flag;
void fn_Key_GPIO_Config( GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock , uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef ){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
RCC_APB2PeriphClockCmd(_GPIO_Clock,ENABLE);
GPIO_Init(_GPIO_x , &GPIO_InitStruct);
}
void fn_Key_Init(void){
fn_Key_GPIO_Config(KEY_IN_GPIO_Port,KEY_IN_GPIO_Clock,KEY_IN_GPIO_Pin,Key_IN_GPIO_Modle);
fn_Key_GPIO_Config(KEY2_IN_GPIO_Port,KEY2_IN_GPIO_Clock,KEY2_IN_GPIO_Pin,Key2_IN_GPIO_Modle);
}
#define _LONG_key 30
static uint16_t count_key ;
void fn_key_judge(void){
if(!bkey_10ms){return;}
bkey_10ms = 0;
if(GPIO_ReadInputDataBit(KEY_IN_GPIO_Port,KEY_IN_GPIO_Pin)){
if(count_key++<3){return;}
if(!bkey_judge){
bkey_judge = 1;
bkey_Effect = 1;
}else{
if(count_key>_LONG_key){
bkey_judge_long = 1;
bkey_LongEffect = 1;
}
}
}
else{
count_key = 0;
if(bkey_judge){
bkey_judge = 0;
if(bkey_judge_long){
bkey_judge_long = 0;
bkey_Effect_LLose = 1;
}else{
bkey_judge_long = 0;
bkey_Effect_Lose = 1;
}
}else{
bkey_judge = 0;
}
}
}
void fn_key_Effect(void){
if(bkey_Effect){
bkey_Effect = 0;
fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle);
}
}
void fn_key_Check(void){
fn_key_judge();
fn_key_Effect();
}
建立LED 的头文件 Led_book.h
代码如下 :
#ifndef __LED_BOOK_H_
#define __LED_BOOK_H_
#include "stm32f10x.h"
#define LED_OUT_GPIO_Port GPIOB
#define LED_OUT_GPIO_Clock RCC_APB2Periph_GPIOB
#define LED_OUT_GPIO_Pin GPIO_Pin_5
#define LED_OUT_GPIO_Pin_Bit 5
#define LED_OUT_GPIO_Modle GPIO_Mode_Out_PP
#define LED_R_OUT_GPIO_Pin GPIO_Pin_5
#define LED_G_OUT_GPIO_Pin GPIO_Pin_0
#define LED_B_OUT_GPIO_Pin GPIO_Pin_1
typedef enum {
LED_Corporate_On = 1,
LED_Corporate_OFF = 2,
LED_Corporate_Toggle = 3,
} LED_Corporate_state_t;
void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,\
uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef);
void fn_Led_Init(void);
void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , \
LED_Corporate_state_t _LED_Corporate_state_t );
void fn_LED_ALL_OFF(void);
#define __LED_Change__ fn_LED_Corporate(LED_OUT_GPIO_Port,LED_OUT_GPIO_Pin,LED_Corporate_Toggle)
#define __R_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_R_OUT_GPIO_Pin)
#define __G_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_G_OUT_GPIO_Pin)
#define __B_OUT__ GPIO_ResetBits(LED_OUT_GPIO_Port,LED_B_OUT_GPIO_Pin)
#endif
建立LED 的 文件 Led_book.c
代码如下 :
#include "Led_book.h"
#define LED_GPIO_Speed GPIO_Speed_10MHz
void fn_LED_GPIO_Config(GPIO_TypeDef* _GPIO_x , uint32_t _GPIO_Clock ,uint16_t _GPIO_Pin_x , GPIOMode_TypeDef _GPIOMode_TypeDef){
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = _GPIOMode_TypeDef;
GPIO_InitStruct.GPIO_Pin = _GPIO_Pin_x;
GPIO_InitStruct.GPIO_Speed = LED_GPIO_Speed;
RCC_APB2PeriphClockCmd(_GPIO_Clock ,ENABLE);
GPIO_Init(_GPIO_x , &GPIO_InitStruct) ;
GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
}
void fn_Led_Init(void){
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_R_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_G_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_GPIO_Config (LED_OUT_GPIO_Port,LED_OUT_GPIO_Clock,LED_B_OUT_GPIO_Pin,LED_OUT_GPIO_Modle);
fn_LED_ALL_OFF();
}
void fn_LED_Corporate(GPIO_TypeDef* _GPIO_x , uint16_t _GPIO_Pin_x , LED_Corporate_state_t _LED_Corporate_state_t ){
switch(_LED_Corporate_state_t){
case LED_Corporate_On :
GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
break;
case LED_Corporate_OFF:
GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x);
break;
case LED_Corporate_Toggle:
GPIO_ReadOutputDataBit(_GPIO_x,_GPIO_Pin_x)?GPIO_ResetBits(_GPIO_x,_GPIO_Pin_x):GPIO_SetBits(_GPIO_x,_GPIO_Pin_x);
break;
}
}
void fn_LED_ALL_OFF(void){
GPIO_SetBits(LED_OUT_GPIO_Port,LED_R_OUT_GPIO_Pin);
GPIO_SetBits(LED_OUT_GPIO_Port,LED_G_OUT_GPIO_Pin);
GPIO_SetBits(LED_OUT_GPIO_Port,LED_B_OUT_GPIO_Pin);
}
建立 Systick传输的 头文件 Systick_book.h
代码如下 :
#ifndef __SYSTIC_BOOK_H_
#define __SYSTIC_BOOK_H_
#include "stm32f10x.h"
#include "Key_book.h"
typedef enum {
_Systick_us = 1,
_Systick_ms = 2,
_Systick_s = 3,
} Systick_time_state_t;
void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t);
void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t);
void fn_SysTick_delay_decrement(void);
void SysTick_Handler(void);
#define __Systick_Delay_Handler_set__ fn_Systick_Delay_Handler_set(10,_Systick_ms)
#endif
建立 Systick的C文件 Systick_book.c
代码如下 :
#include "Systick_book.h"
void fn_Systick_Delay(uint32_t _Delay_time , Systick_time_state_t _Systick_time_state_t){
uint32_t i;
if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);}
if(_Systick_time_state_t == _Systick_ms){
SysTick_Config(SystemCoreClock/1000);
}
else{SysTick_Config(SystemCoreClock);}
for( i=0;i<_Delay_time ; i++){
while(!((SysTick->CTRL)&(1<<16)));
}
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}
static uint32_t _SysTick_delay = 0 ;
void fn_Systick_Delay_Handler_set(uint32_t _Delay_ms , Systick_time_state_t _Systick_time_state_t){
if(_Systick_time_state_t == _Systick_us){SysTick_Config(SystemCoreClock/1000000);}
if(_Systick_time_state_t == _Systick_ms){
SysTick_Config(SystemCoreClock/1000);
}
else{SysTick_Config(SystemCoreClock);}
_SysTick_delay = _Delay_ms ;
}
static uint32_t SysTick_delay = 0 ;
void fn_SysTick_delay_decrement(void){
if(SysTick_delay++ > _SysTick_delay){
SysTick_delay = 0;
bkey_10ms = 1;
}
}
void SysTick_Handler(void){
fn_SysTick_delay_decrement();
}
建立 头文件函数 头文件 PROJ_book.h
代码如下 :
#ifndef __PROJ_BOOK_H__
#define __PROJ_BOOK_H__
#include "stm32f10x.h"
#include "Led_book.h"
#include "Key_book.h"
#include "RCC_book.h"
#include "Systick_book.h"
#include "Exit_book.h"
#include "USART_book.h"
#include "DMA_book.h"
#include "I2C_book.h"
#include "I2C_soft_book.h"
#endif
|