711|1

504

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

【ST多款开发板返场测评】STM32F767 Nucleo-144 基于FIFO的串口驱动 [复制链接]

前言

为了方便后面USB调试,所以先实现串口通讯接口,前面进行了串口测试,但是接口不方便使用,需要实现方便应用层使用的串口收发接口。通过实现FIFO方式来实现串口的中断接收,发送为了简单使用查询发送方式。

 

过程

Bsp层

先实现bsp层的串口接口

Bsp_uart.c/h

 

初始化

void bsp_uart_init(void)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

	
	/* IO Cfg  
	 * PD9 USART3_RX
	 * PD8 USART3_TX
	 */
	__HAL_RCC_GPIOD_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
  /* Enable USART3 clock */
  __HAL_RCC_USART3_CLK_ENABLE(); 
	
	/* USART3 Cfg */
  UartHandle.Instance        = USART3;

  UartHandle.Init.BaudRate   = 115200;
  UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits   = UART_STOPBITS_1;
  UartHandle.Init.Parity     = UART_PARITY_NONE;
  UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode       = UART_MODE_TX_RX;
	HAL_UART_Init(&UartHandle);
	
	/* NVIC */
	HAL_NVIC_EnableIRQ(USART3_IRQn);
	HAL_NVIC_SetPriority(USART3_IRQn,0,1);
	
	LL_USART_EnableIT_RXNE(USART3);
}

 

发送


void uart_sendbyte(uint8_t ch)
{
	uint8_t tmp =ch;
	HAL_UART_Transmit(&UartHandle,&ch,1,0xFFFFFFFF);
	//LL_USART_TransmitData8(USART3,ch);
}

void bsp_uart_send(uint8_t* p, uint32_t len)
{
	HAL_UART_Transmit(&UartHandle,p,len,0xFFFFFFFF);
}

串口接收中断处理

extern void uart_rx_handler(const uint8_t *buffer, uint32_t length);

void USART3_IRQHandler(void)
{
	uint8_t ch;
  if(LL_USART_IsActiveFlag_RXNE(USART3) && LL_USART_IsEnabledIT_RXNE(USART3))
  {
    /* RXNE flag will be cleared by reading of RDR register (done in call) */
		ch = LL_USART_ReceiveData8(USART3);
		//LL_USART_TransmitData8(USART3,ch);
		//while(LL_USART_IsActiveFlag_TC(USART3) == 0);
		uart_rx_handler(&ch, 1);
  }
}

代码详见

bap_uart.c

#include "stm32f7xx_hal.h"
#include "stm32f7xx_ll_usart.h"


UART_HandleTypeDef UartHandle;


extern void uart_rx_handler(const uint8_t *buffer, uint32_t length);

void USART3_IRQHandler(void)
{
	uint8_t ch;
  if(LL_USART_IsActiveFlag_RXNE(USART3) && LL_USART_IsEnabledIT_RXNE(USART3))
  {
    /* RXNE flag will be cleared by reading of RDR register (done in call) */
		ch = LL_USART_ReceiveData8(USART3);
		//LL_USART_TransmitData8(USART3,ch);
		//while(LL_USART_IsActiveFlag_TC(USART3) == 0);
		uart_rx_handler(&ch, 1);
  }
}

void uart_sendbyte(uint8_t ch)
{
	uint8_t tmp =ch;
	HAL_UART_Transmit(&UartHandle,&ch,1,0xFFFFFFFF);
	//LL_USART_TransmitData8(USART3,ch);
}

void bsp_uart_send(uint8_t* p, uint32_t len)
{
	HAL_UART_Transmit(&UartHandle,p,len,0xFFFFFFFF);
}
	
void bsp_uart_init(void)
{
  GPIO_InitTypeDef  GPIO_InitStruct;

	
	/* IO Cfg  
	 * PD9 USART3_RX
	 * PD8 USART3_TX
	 */
	__HAL_RCC_GPIOD_CLK_ENABLE();
  GPIO_InitStruct.Pin = GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
	
  /* Enable USART3 clock */
  __HAL_RCC_USART3_CLK_ENABLE(); 
	
	/* USART3 Cfg */
  UartHandle.Instance        = USART3;

  UartHandle.Init.BaudRate   = 115200;
  UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
  UartHandle.Init.StopBits   = UART_STOPBITS_1;
  UartHandle.Init.Parity     = UART_PARITY_NONE;
  UartHandle.Init.HwFlowCtl  = UART_HWCONTROL_NONE;
  UartHandle.Init.Mode       = UART_MODE_TX_RX;
	HAL_UART_Init(&UartHandle);
	
	/* NVIC */
	HAL_NVIC_EnableIRQ(USART3_IRQn);
	HAL_NVIC_SetPriority(USART3_IRQn,0,1);
	
	LL_USART_EnableIT_RXNE(USART3);
}

bap_uart.h

#ifndef BSP_UART_H
#define BSP_UART_H

void bsp_uart_init(void);
void bsp_uart_send(uint8_t* p, uint32_t len);

#endif

驱动层

实现FIFO数据结构

typedef struct
{
        uint32_t datalen_u32;
        uint32_t maxlen_u32;
        uint32_t in_u32;
        uint32_t out_u32;
        uint8_t* buffer_pu8;
}ring_buffer_t;

 
uint8_t uart_ring_buffer[128];

ring_buffer_t s_ring_buffer_t=
{
	.datalen_u32 = 0,
	.maxlen_u32 = sizeof(uart_ring_buffer),
  .in_u32 = 0,
  .out_u32 = 0,
  .buffer_pu8 = uart_ring_buffer,
};

临界段处理

#define Alloc_Critical()  
#define Enter_Critical()  __disable_irq()
#define Exit_Critical()   __enable_irq

 

接收处理,接收中断服务函数中调用

void uart_rx_handler(const uint8_t *buffer, uint32_t length)
{
    uint32_t i;
    for(i=0;i<length; i++)
    {
        if(s_ring_buffer_t.datalen_u32 < s_ring_buffer_t.maxlen_u32)
        {
            s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.in_u32] = buffer[i];
            s_ring_buffer_t.datalen_u32++;
            s_ring_buffer_t.in_u32++;
            s_ring_buffer_t.in_u32 %= s_ring_buffer_t.maxlen_u32;
        }
        else
        {
            /* full */
            break;
        }
    }
}

接收API

uint32_t uart_read(uint8_t *buff, uint32_t len)
{
    uint32_t readlen = 0;
    //uint32_t mask;
    if(s_ring_buffer_t.datalen_u32 == 0)
    {
        return 0;
    }
		Alloc_Critical();
    Enter_Critical();
    uint32_t i;
    for(i=0;i<len;i++)
    {
			if(s_ring_buffer_t.datalen_u32 > 0)
      {
				buff[i] = s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.out_u32];
				s_ring_buffer_t.datalen_u32--;
				s_ring_buffer_t.out_u32++;
				s_ring_buffer_t.out_u32 %= s_ring_buffer_t.maxlen_u32;
				readlen++;
			}
			else
			{
				break;
			}
    }
    Exit_Critical();
    return readlen;
}

 

发送API

int uart_write(uint8_t *buff, uint32_t len)
{
	uint32_t i;
	for(i=0; i<len ;i++)
	{
		uart_sendbyte(buff[i]);
	}
	return 0;
}

 

代码详见

uart.c

#include "uart.h"
#include "bsp_uart.h"
#include "stm32f7xx.h"

#define Alloc_Critical()  
#define Enter_Critical()  __disable_irq()
#define Exit_Critical()   __enable_irq()
			 
typedef struct
{
        uint32_t datalen_u32;
        uint32_t maxlen_u32;
        uint32_t in_u32;
        uint32_t out_u32;
        uint8_t* buffer_pu8;
}ring_buffer_t;

 
uint8_t uart_ring_buffer[128];

ring_buffer_t s_ring_buffer_t=
{
	.datalen_u32 = 0,
	.maxlen_u32 = sizeof(uart_ring_buffer),
  .in_u32 = 0,
  .out_u32 = 0,
  .buffer_pu8 = uart_ring_buffer,
};

void uart_rx_handler(const uint8_t *buffer, uint32_t length)
{
    uint32_t i;
    for(i=0;i<length; i++)
    {
        if(s_ring_buffer_t.datalen_u32 < s_ring_buffer_t.maxlen_u32)
        {
            s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.in_u32] = buffer[i];
            s_ring_buffer_t.datalen_u32++;
            s_ring_buffer_t.in_u32++;
            s_ring_buffer_t.in_u32 %= s_ring_buffer_t.maxlen_u32;
        }
        else
        {
            /* full */
            break;
        }
    }
}

uint32_t uart_read(uint8_t *buff, uint32_t len)
{
    uint32_t readlen = 0;
    //uint32_t mask;
    if(s_ring_buffer_t.datalen_u32 == 0)
    {
        return 0;
    }
		Alloc_Critical();
    Enter_Critical();
    uint32_t i;
    for(i=0;i<len;i++)
    {
			if(s_ring_buffer_t.datalen_u32 > 0)
      {
				buff[i] = s_ring_buffer_t.buffer_pu8[s_ring_buffer_t.out_u32];
				s_ring_buffer_t.datalen_u32--;
				s_ring_buffer_t.out_u32++;
				s_ring_buffer_t.out_u32 %= s_ring_buffer_t.maxlen_u32;
				readlen++;
			}
			else
			{
				break;
			}
    }
    Exit_Critical();
    return readlen;
}

int uart_write(uint8_t *buff, uint32_t len)
{
	uint32_t i;
	for(i=0; i<len ;i++)
	{
		uart_sendbyte(buff[i]);
	}
	return 0;
}

 

uart.h

#ifndef UART_H
#define UART_H

#include <stdint.h>

void uart_rx_handler(const uint8_t *buffer, uint32_t length);
uint32_t uart_read(uint8_t *buff, uint32_t len);
int uart_write(uint8_t *buff, uint32_t len);

extern void uart_sendbyte(uint8_t ch);

#endif

 

测试

main.c中

#include "bsp_uart.h"
#include "uart.h"


bsp_uart_init();

  uint8_t tx_buffer[2]={0xAA,0x55};

  /* Infinite loop */

  while (1)

  {

uint8_t buffer[128];

for(;;)

{

uint32_t len=0;

  if((len = uart_read(buffer, sizeof(buffer))) >0)

  {

     uart_write(buffer, len);

  }

  }

  }

 

使用串口调试助手发送数据,开发板收到原样返回

 

 

 

总结

基于bsp层的串口收发,实现了基于FIFO的串口驱动,给应用层提供串口收发接口,uart.c和uart.h具备可移植性,方便移植到不同平台。方便后面的调试使用。

此帖出自stm32/stm8论坛

最新回复

谢谢分享,期待后续评测!   详情 回复 发表于 2023-10-30 15:52
点赞 关注
 

回复
举报

7608

帖子

18

TA的资源

五彩晶圆(高级)

沙发
 

谢谢分享,期待后续评测!

此帖出自stm32/stm8论坛
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表