1.硬件条件:使用芯片stm32f407zg,使用usart1,SRAM bus总线A0~A18,D0~D15, debug:wire。
2.stm32cubemx时钟设定、usart1、fmc参数设定,生成初始化代码。
3.完善代码
3.1usart完善代码
usart.c增加以下代码:
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
//#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
//定义_sys_exit()以避免使用半主机模式
void _sys_exit(int x)
{
x = x;
}
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
USART1->DR = (uint8_t) ch;
return ch;
}
#endif
在MX_USART1_UART_Init中追加
/* USER CODE BEGIN USART1_Init 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
/* USER CODE END USART1_Init 2 */
增加回调函数和中断函数,并注释掉stm32f4xx_it.c文件中的void USART1_IRQHandler(void) 。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)//如果是串口1
{
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;//接收错误,重新开始
else USART_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
//串口1中断服务程序
void USART1_IRQHandler(void)
{
uint32_t timeout=0;
HAL_UART_IRQHandler(&huart1); //调用HAL库中断处理公用函数
timeout=0;
while (HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY)//等待就绪
{
timeout++;超时处理
if(timeout>HAL_MAX_DELAY) break;
}
timeout=0;
while(HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)//一次处理完成之后,重新开启中断并设置RxXferCount为1
{
timeout++; //超时处理
if(timeout>HAL_MAX_DELAY) break;
}
}
4.增加测试代码
在fmc.c文件中增加以下代码
uint32_t bsp_TestExtSRAM(void)
{
uint32_t i;
uint32_t *pSRAM;
uint8_t *pBytes;
uint32_t err;
const uint8_t ByteBuf[4] = {0x50, 0xB5, 0xC2, 0x5A};
/* 写SRAM */
pSRAM = (uint32_t *)EXT_SRAM_ADDR;
for (i = 0; i < EXT_SRAM_SIZE / 4; i++)
{
*pSRAM++ = i;
}
/* 读SRAM */
err = 0;
pSRAM = (uint32_t *)EXT_SRAM_ADDR;
for (i = 0; i < EXT_SRAM_SIZE / 4; i++)
{
if (*pSRAM++ != i)
{
err++;
}
}
printf("SDRAM check round 1 error = %d\n", err);
printf("\r\n");
if (err > 0)
{
return (4 * err);
}
#if 1
/* 对SRAM 的数据求反并写入 */
pSRAM = (uint32_t *)EXT_SRAM_ADDR;
for (i = 0; i < EXT_SRAM_SIZE/4; i++)
{
*pSRAM = ~*pSRAM;
pSRAM++;
}
/* 再次比较SRAM的数据 */
err = 0;
pSRAM = (uint32_t *)EXT_SRAM_ADDR;
for (i = 0; i<EXT_SRAM_SIZE/4;i++)
{
if (*pSRAM++ != (~i))
{
err++;
}
}
printf("SDRAM check round 2 error = %d\n", err);
printf("\r\n");
if (err>0)
{
return (4 * err);
}
#endif
/* 测试按字节方式访问, 目的是验证 FSMC_NBL0 、 FSMC_NBL1 口线 */
pBytes = (uint8_t *)EXT_SRAM_ADDR;
for (i = 0; i < sizeof(ByteBuf); i++)
{
*pBytes++ = ByteBuf[i];
}
/* 比较SRAM的数据 */
err = 0;
pBytes = (uint8_t *)EXT_SRAM_ADDR;
for (i = 0; i < sizeof(ByteBuf); i++)
{
if (*pBytes++ != ByteBuf[i])
{
err++;
}
}
printf("SDRAM check round 3 error = %d\n", err);
printf("\r\n");
if (err > 0)
{
return err;
}
return 0;
}
/**
* @}
*/
在main.c文件中增加以下代码
/* USER CODE BEGIN 2 */
printf("STM32F407ZG FSMC SRAM Test By margret\r\n");
if (bsp_TestExtSRAM() == 0) {
printf("SRAM Test success\r\n");
} else {
printf("SRAM Test fail\r\n");
}
/* 操作在SRAM的变量 */
// testValue = 0x5a;
// printf("testValue is %#x\r\n", testValue);
printf("\r\n");
printf("SRAM test begin...\n");
printf("\r\n");
*( uint8_t*) (EXT_SRAM_ADDR ) = (uint8_t)0x5A;
printf("Write Data: 0x5A\n");
printf("\r\n");
temp = *( uint8_t*) (EXT_SRAM_ADDR );
printf("Read Data: 0x%x \n",temp);
printf("\r\n");
printf("SRAM test end...\n");
printf("\r\n");
/* USER CODE END 2 */
5.验证结果
以下链接为全部代码
(51条消息) 使用stm32cubemx配置FMC,用uart串口验证CPU与SRAM通讯是否正常-C文档类资源-CSDN文库