STM32F4 USART1 TX RX FIFO

发布者:温柔心情最新更新时间:2019-04-12 来源: eefocus关键字:STM32F4  USART1  FIFO 手机看文章 扫描二维码
随时随地手机看文章

USART1 TX RX FIFO


/*

*********************************************************************************************************

*                                   

* 模块名称 : 串口驱动模块    

* 文件名称 : bsp_uart.c

* 版    本 : V1.0

* 说    明 : 实现printf和scanf函数重定向到串口1,即支持printf信息到USART1

* 实现重定向,只需要添加2个函数:

* int fputc(int ch, FILE *f);

* int fgetc(FILE *f);

* 对于KEIL MDK编译器,编译选项中需要在MicorLib前面打钩,否则不会有数据打印到USART1。

* 修改记录 :

* 版 本 库 : ST固件库V1.0.2版本。

*

*********************************************************************************************************

*/

//#include "stm32f4xx.h"

#include "bspdebug_usartbsp_debug_uart.h"

#include "bsp.h"

#include

#define  debug_uart_tx_buf_size  1*1024

#define  debug_uart_rx_buf_size  1*1024

static uint8_t g_TxBuf[debug_uart_tx_buf_size];  //发送缓冲区

static uint8_t g_RxBuf[debug_uart_rx_buf_size];  //接受缓冲区

/* 串口设备结构体 */

typedef struct

{

  USART_TypeDef *uart; /* STM32内部串口设备指针*/

uint8_t *pTxBuf;   /* 发送缓冲区 */

uint8_t *pRxBuf; /* 接收缓冲区 */

uint16_t usTxBufSize; /* 发送缓冲区大小 */

uint16_t usRxBufSize; /* 接收缓冲区大小 */


uint16_t usTxWrite; /* 发送缓冲区写指针 */

uint16_t usTxRead; /* 发送缓冲区读指针 */

uint16_t usTxCount; /* 等待发送的数据个数 */

 

uint16_t usRxWrite; /* 接收缓冲区写指针 */

uint16_t usRxRead; /* 接收缓冲区读指针 */

uint16_t usRxCount; /* 还未读取的新数据个数 */

 

void (*SendBefor)(void); /* 开始发送之前的回调函数指针(主要用于RS485切换到发送模式) */

void (*SendOver)(void); /* 发送完毕的回调函数指针(主要用于RS485将发送模式切换为接收模式) */

void (*ReciveNew)(void); /* 串口收到数据的回调函数指针 */

}UART_T;

 

static UART_T g_tDebugUart;

 

static void UartVarInit(void)

{

g_tDebugUart.uart=USART1;

g_tDebugUart.pTxBuf = g_TxBuf; /* 发送缓冲区指针 */

g_tDebugUart.pRxBuf = g_RxBuf; /* 接收缓冲区指针 */

g_tDebugUart.usTxBufSize = debug_uart_tx_buf_size; /* 发送缓冲区大小 */

g_tDebugUart.usRxBufSize = debug_uart_rx_buf_size; /* 接收缓冲区大小 */


g_tDebugUart.usTxWrite = 0; /* 发送FIFO写索引 */

g_tDebugUart.usTxRead = 0; /* 发送FIFO读索引 */

g_tDebugUart.usRxWrite = 0; /* 接收FIFO写索引 */

g_tDebugUart.usRxRead = 0; /* 接收FIFO读索引 */

g_tDebugUart.usRxCount = 0; /* 接收到的新数据个数 */

g_tDebugUart.usTxCount = 0; /* 待发送的数据个数 */


g_tDebugUart.SendBefor = 0; /* 发送数据前的回调函数 */

g_tDebugUart.SendOver = 0; /* 发送完毕后的回调函数 */

g_tDebugUart.ReciveNew = 0; /* 接收到新数据后的回调函数 */

}

 

static void ConfigUartNVIC(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

 

 

 

/*

*********************************************************************************************************

* 函 数 名: bsp_InitUart

* 功能说明: 初始化CPU的USART1串口硬件设备。未启用中断。

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void bsp_InitDebugUart(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDef USART_InitStructure;


UartVarInit();

ConfigUartNVIC();

/* 串口1 TX = PA9   RX = PA10 */

 

/* 第1步: 配置GPIO */

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);/* 打开 GPIO 时钟 */

/* 打开 UART 时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* 将 PA9 映射为 USART1_TX */

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);

/* 将 PA10 映射为 USART1_RX */

GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);

 

/* 配置 USART Tx 为复用功能 */

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; /* 输出类型为推挽 */

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; /* 内部上拉电阻使能 */

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; /* 复用模式 */

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

 

/* 配置 USART Rx 为复用功能 */

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_Init(GPIOA, &GPIO_InitStructure);

 

/* 第2步: 配置串口硬件参数 */

USART_InitStructure.USART_BaudRate = 115200; /* 波特率 */

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(USART1, &USART_InitStructure);

  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /* 使能接收中断 */

USART_Cmd(USART1, ENABLE); /* 使能串口 */

 

/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去

如下语句解决第1个字节无法正确发送出去的问题 */

USART_ClearFlag(USART1, USART_FLAG_TC);     /* 清发送完成标志,Transmission Complete flag */   

}

 

void comSendChar(int ch)

{

if(g_tDebugUart.SendBefor!=0)//开始回调前调用回调函数

{

g_tDebugUart.SendBefor();

}

while(1)

{

uint16_t usRead;

DISABLE_INT();

usRead = g_tDebugUart.usTxCount;

ENABLE_INT();

if( usRead < g_tDebugUart.usTxBufSize)//如果发送缓冲区域的满则等待

{

break;

}

}

g_tDebugUart.pTxBuf[g_tDebugUart.usTxWrite]= ch;//向发送缓存区写入数值

DISABLE_INT();

if (++g_tDebugUart.usTxWrite >= g_tDebugUart.usTxBufSize)//发送指针加一

{

g_tDebugUart.usTxWrite = 0;

}

g_tDebugUart.usTxCount++;//发送数加一

ENABLE_INT();

USART_ITConfig(g_tDebugUart.uart, USART_IT_TXE, ENABLE);



 

 

}

/*

*********************************************************************************************************

* 函 数 名: UartGetChar

* 功能说明: 从串口接收缓冲区读取1字节数据 (用于主程序调用)

* 形    参: _pUart : 串口设备

*   _pByte : 存放读取数据的指针

* 返 回 值: 0 表示无数据  1表示读取到数据

*********************************************************************************************************

*/

uint8_t comGetChar( uint8_t *_pByte)

uint16_t usCount;

DISABLE_INT();

usCount = g_tDebugUart.usRxCount;

ENABLE_INT();

if(usCount==0)

{

return 0;

}

else

{

*_pByte = g_tDebugUart.pRxBuf[g_tDebugUart.usRxRead]; /* 从串口接收FIFO取1个数据 */

/* 改写FIFO读索引 */

DISABLE_INT();

if (++g_tDebugUart.usRxRead >= g_tDebugUart.usRxBufSize)

{

g_tDebugUart.usRxRead = 0;

}

g_tDebugUart.usRxCount--;

ENABLE_INT();

return 1;


}

 

}

/*

*********************************************************************************************************

* name: fputc 重定向printf

*********************************************************************************************************

*/

int fputc(int ch, FILE *f)

{

#if 1

comSendChar(ch);

return ch;

#else 

while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET){};

USART_SendData(USART1, (u16) ch);

return ch;

#endif 

}

 

/*

*********************************************************************************************************

*重定向getc

*********************************************************************************************************

*/

int fgetc(FILE *f)

{

#if 1

uint8_t ucData;

while(comGetChar(&ucData) == 0);

return ucData;


#else

while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);

return (int)USART_ReceiveData(USART1);

#endif 

}

 

 

 void USART1_IRQHandler(void)

{

/* 处理接收中断  */

if (USART_GetITStatus(g_tDebugUart.uart, USART_IT_RXNE) != RESET)

{

g_tDebugUart.pRxBuf[g_tDebugUart.usRxWrite] = USART_ReceiveData(g_tDebugUart.uart); /* 从串口接收数据寄存器读取数据存放到接收FIFO */

if (++g_tDebugUart.usRxWrite >= g_tDebugUart.usRxBufSize)

{

g_tDebugUart.usRxWrite = 0;

}

if (g_tDebugUart.usRxCount < g_tDebugUart.usRxBufSize)

{

g_tDebugUart.usRxCount++;

}

 

/* 回调函数,通知应用程序收到新数据,一般是发送1个消息或者设置一个标记 */

//if (_pUart->usRxWrite == _pUart->usRxRead)

if (g_tDebugUart.usRxCount == 1)

{

if (g_tDebugUart.ReciveNew)

{

g_tDebugUart.ReciveNew();

}

}

}

 

/* 处理发送缓冲区空中断 */

if (USART_GetITStatus(g_tDebugUart.uart, USART_IT_TXE) != RESET)

{

//if (_pUart->usTxRead == _pUart->usTxWrite)

if (g_tDebugUart.usTxCount == 0)

{

USART_ITConfig(g_tDebugUart.uart, USART_IT_TXE, DISABLE);/* 发送缓冲区的数据已取完时, 禁止发送缓冲区空中断 (注意:此时最后1个数据还未真正发送完毕)*/

USART_ITConfig(g_tDebugUart.uart, USART_IT_TC, ENABLE);/* 使能数据发送完毕中断 */

}

else

{

USART_SendData(g_tDebugUart.uart, g_tDebugUart.pTxBuf[g_tDebugUart.usTxRead]);/* 从发送FIFO取1个字节写入串口发送数据寄存器 */

if (++g_tDebugUart.usTxRead >= g_tDebugUart.usTxBufSize)

{

g_tDebugUart.usTxRead = 0;

}

g_tDebugUart.usTxCount--;

}

 

}

else if (USART_GetITStatus(g_tDebugUart.uart, USART_IT_TC) != RESET)/* 数据bit位全部发送完毕的中断 */

{

if (g_tDebugUart.usTxCount == 0)

{

USART_ITConfig(g_tDebugUart.uart, USART_IT_TC, DISABLE);/* 如果发送FIFO的数据全部发送完毕,禁止数据发送完毕中断 */

 

/* 回调函数, 一般用来处理RS485通信,将RS485芯片设置为接收模式,避免抢占总线 */

if (g_tDebugUart.SendOver)

{

g_tDebugUart.SendOver();

}

}

else

{

/* 正常情况下,不会进入此分支 */

/* 如果发送FIFO的数据还未完毕,则从发送FIFO取1个数据写入发送数据寄存器 */

USART_SendData(g_tDebugUart.uart, g_tDebugUart.pTxBuf[g_tDebugUart.usTxRead]);

if (++g_tDebugUart.usTxRead >= g_tDebugUart.usTxBufSize)

{

g_tDebugUart.usTxRead = 0;

}

g_tDebugUart.usTxCount--;

}

}

}

 

 

 

/***************************** (END OF FILE) *********************************/


关键字:STM32F4  USART1  FIFO 引用地址:STM32F4 USART1 TX RX FIFO

上一篇:STM32的USART中RTS、CTS的作用和意义
下一篇:STM32 串口详细讲解

推荐阅读最新更新时间:2024-03-16 16:27

基于STM32F4的小波分解(Mallat算法)程序说明
一、主要思路 原始信号:OrgSig 信号长度:DWT_SIG_LEN 小波分解层数:N 与MATLAB类似,小波分解后产生2个数组DWT_L和DWT_C,但定义与MATLAB不同。定义如下: DWT_L: ,其中xxx_LEN代表该数组的长度 DWT_C: ,其中cDx代表第x层的细节系数,cAN代表第N层的近似系数 二、函数原型 1、 小波变换函数DWT_Dwt 函数原型: /**************************************** **小波变换,即1层小波分解 //V1.00 实现基本功能 2016-9-18 21:41:50 * @原理: DWT_
[单片机]
基于<font color='red'>STM32F4</font>的小波分解(Mallat算法)程序说明
STM32F4 USART1 TX RX FIFO
USART1 TX RX FIFO /* ********************************************************************************************************* * * 模块名称 : 串口驱动模块 * 文件名称 : bsp_uart.c * 版 本 : V1.0 * 说 明 : 实现printf和scanf函数重定向到串口1,即支持printf信息到USART1 * 实现重定向,只需要添加2个函数: * int fputc(int ch, FILE *f); * int fgetc(FILE
[单片机]
stm32f407】窗口看门狗 wwdog
一.窗口看门狗 窗口看门狗(WWDG)通常被用来监测由外部干扰或不可预见的逻辑条件造成的应用程序背离正常的运行序列而产生的软件故障。除非递减计数器的值在T6位(WWDG- CR的第六位)变成0前被刷新,看门狗电路在达到预置的时间周期时,会产生一个MCU复位。在递减计数器达到窗口配置寄存器(WWDG- CFR)数值之前,如果7位的递减计数器数值(在控制寄存器中)被刷新, 那么也将产生一个MCU复位。这表明递减计数器需要在一个有限的时间窗口中被刷新。如图: T 就是WWDG_CR的低七位,W 即是WWDG- CFR的低七位。T 就是窗口看门狗的计数器,而W 则是窗口看门狗的上窗口,下窗口值是固定的(0X40)。当窗口
[单片机]
【<font color='red'>stm32f4</font>07】窗口看门狗 wwdog
STM32F4CubeMX学习笔记之USART1
开发板:普中PZ6808L-F4 开发环境:keil5+CnbeMx 硬件资源:2个LED 1个串口 功能说明:LED2闪烁表示系统在运行 LED1通过串口控制 CnbeMx配置为 int fputc(int ch,FILE *f)//重新定义串口输出使用printf功能 { uint8_t temp ={ch}; HAL_UART_Transmit(&huart1,temp,1,2); return(ch); } // 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx int fgetc(FILE * f) { uint8_t ch = 0; HAL_UAR
[单片机]
<font color='red'>STM32F4</font>CubeMX学习笔记之<font color='red'>USART1</font>
STM32F429 DMA串口数据发送
串口数据配置 void macUART4_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_AHB1PeriphClockCmd(macUART4_RX_GPIO_CLK|macUART4_TX_GPIO_CLK,ENABLE); RCC_APB1PeriphClockCmd(macUART4_CLK, ENABLE); GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Pu
[单片机]
FIFO程序设计解析(队列指针)
typedef struct { QUEUE_DATA_TYPE *Out; QUEUE_DATA_TYPE *In; QUEUE_DATA_TYPE *End; u16 NData; u16 MaxData; u8 (* ReadEmpty)(); u8 (* WriteFull)(); QUEUE_DATA
[单片机]
测试STM32F4 EVNETOUT
看到很多管脚都可以配置成EVENTOUT,刚好有个管脚要想要输出一个高电平脉冲,测试了一下: 环境:STM32F407, IAR 7.4, STM32CubeF4 GPIO配置代码: GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLDOWN; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Alternate = GPIO_AF15_EVENTOUT; HAL_GPIO_Init(GPIOB
[单片机]
测试<font color='red'>STM32F4</font> EVNETOUT
基于fifo存储器的声发射信号的数据传输及存储
 声发射技术是光纤传感技术和声发射技术相结合的产物,是目前声发射技术的发展趋势。它将高灵敏度声发射传感器安装于受力构件表面以形成一定数目的传感器阵列,实时接收和采集来自于材料缺陷的声发射信号,进而通过对这些声发射信号的识别、判断和分析来对材料损伤缺陷进行检测研究并对构件强度、损伤、寿命等进行分析和研究。   在实际的构件检测中,现场声源信号通常是在100~800 khz之间的微弱高频信号,而且材料损伤检测、声发射源定位往往需要多个传感器形成传感器阵列,而声发射信号的数据传输系统必须达到640 mbps以上的数据传输能力;并应具有应付突发或长时间数据接收和存储能力。本文就是利用CPLD来实现对声发射信号的采集,从而有效解决了数据的实时
[工业控制]
基于<font color='red'>fifo</font>存储器的声发射信号的数据传输及存储
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved