561|3

502

帖子

4

TA的资源

纯净的硅(高级)

楼主
 

【DigiKey创意大赛】基于STM32H7B3I-DK的智能家居助手+串口通讯驱动与测试 [复制链接]

 
  • 串口通讯与驱动

为了方便与其他外设和上位机交互,先实现灵活好用的串口驱动接口。

原理

设计环形缓冲区。接收中断将数据写u人缓冲区,读API查询缓冲区。

环形缓冲区读写需要做临界段保护处理。

 

代码

bsp_uart.h

#ifndef BSP_UART_H

#define BSP_UART_H

 

#ifdef __cplusplus

extern "C" {

#endif

 

void bsp_uart_init(void);

 

#ifdef __cplusplus

}

#endif

 

#endif

 

Bsp_uart.c

#include <stdio.h>

#include "main.h"

 

#define USARTx                           USART1

#define USARTx_CLK_ENABLE()              __USART1_CLK_ENABLE()

#define USARTx_RX_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE()

#define USARTx_TX_GPIO_CLK_ENABLE()      __GPIOA_CLK_ENABLE()

 

#define USARTx_FORCE_RESET()             __USART1_FORCE_RESET()

#define USARTx_RELEASE_RESET()           __USART1_RELEASE_RESET()

 

/* Definition for USARTx Pins */

#define USARTx_TX_PIN                    GPIO_PIN_9

#define USARTx_TX_GPIO_PORT              GPIOA

#define USARTx_TX_AF                     GPIO_AF7_USART1

#define USARTx_RX_PIN                    GPIO_PIN_10

#define USARTx_RX_GPIO_PORT              GPIOA

#define USARTx_RX_AF                     GPIO_AF7_USART1

 

UART_HandleTypeDef UartHandle;

 

void bsp_uart_init(void)

{

  GPIO_InitTypeDef  GPIO_InitStruct;

 

  RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;

 

  /*##-1- Enable peripherals and GPIO Clocks #################################*/

  /* Enable GPIO TX/RX clock */

  USARTx_TX_GPIO_CLK_ENABLE();

  USARTx_RX_GPIO_CLK_ENABLE();

 

  /* Select SysClk as source of USART1 clocks */

  RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;

  RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;

  HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);

 

  /* Enable USARTx clock */

  USARTx_CLK_ENABLE();

 

 

  /*##-2- Configure peripheral GPIO ##########################################*/

  /* UART TX GPIO pin configuration  */

  GPIO_InitStruct.Pin       = USARTx_TX_PIN;

  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;

  GPIO_InitStruct.Pull      = GPIO_PULLUP;

  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;

  GPIO_InitStruct.Alternate = USARTx_TX_AF;

 

  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

 

  /* UART RX GPIO pin configuration  */

  GPIO_InitStruct.Pin = USARTx_RX_PIN;

  GPIO_InitStruct.Alternate = USARTx_RX_AF;

 

  HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);

 

/*##-1- Configure the UART peripheral ######################################*/

  /* Put the USART peripheral in the Asynchronous mode (UART Mode) */

  /* UART configured as follows:

      - Word Length = 8 Bits (7 data bit + 1 parity bit) :

                  BE CAREFUL : Program 7 data bits + 1 parity bit in PC HyperTerminal

      - Stop Bit    = One Stop bit

      - Parity      = ODD parity

      - BaudRate    = 9600 baud

      - Hardware flow control disabled (RTS and CTS signals) */

  UartHandle.Instance            = USARTx;

 

  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;

  UartHandle.Init.OverSampling   = UART_OVERSAMPLING_16;

  UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

  if(HAL_UART_Init(&UartHandle) != HAL_OK)

  {

    /* Initialization Error */

    Error_Handler();

  }

__HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);

  HAL_NVIC_SetPriority(USART1_IRQn, 5 ,0U);

  HAL_NVIC_EnableIRQ(USART1_IRQn);

}

 

/**

  * @brief  Retargets the C library printf function to the USART.

  * @param  None

  * @retval None

  */

int fputc(int ch, FILE *f)

{

  /* Place your implementation of fputc here */

  /* e.g. write a character to the USART1 and Loop until the end of transmission */

  HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 0xFFFF);

 

  return ch;

}

 

 

void uart_sendbyte(uint8_t val)

{

  HAL_UART_Transmit(&UartHandle, (uint8_t *)&val, 1, 0xFFFF);

}

 

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

 

void USART1_IRQHandler(void)

{

uint8_t ch;

ch = (uint16_t) READ_REG(UartHandle.Instance->RDR);

uart_api_rx_handler(&ch, 1);

}

 

 

Uart_api.c

#include "uart_api.h"

 

extern void uart_sendbyte(uint8_t val);

 

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;

 

static uint8_t uart_ring_buffer[UART_RING_BUFFER_SIZE];

 

static 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_api_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;

            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_api_read(uint8_t *buff, uint32_t len)

{

    uint32_t readlen = 0;

    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 = 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;

}

 

void uart_api_write(uint8_t *buff, uint32_t len)

{

uint32_t i;

for(i=0; i<len ;i++)

{

uart_sendbyte(buff);

}

}

 

 

Uart_api.h

 

#ifndef UART_API_H

#define UART_API_H

 

#ifdef __cplusplus

extern "C" {

#endif

 

#include <stdint.h>

#include "cmsis_os.h"

 

#define Alloc_Critical()    

#define Enter_Critical()    taskENTER_CRITICAL();

#define Exit_Critical()     taskEXIT_CRITICAL();

 

#define UART_RING_BUFFER_SIZE (1024+64)

 

void uart_api_rx_handler(const uint8_t *buffer, uint32_t length);

uint32_t uart_api_read(uint8_t *buff, uint32_t len);

void uart_api_write(uint8_t *buff, uint32_t len);

 

#ifdef __cplusplus

}

#endif

 

#endif

 

测试

使用上位机发送数据,板子原样返回,测试收发完全正确。

uint8_t buffer[64];

uint32_t  len;

while((len = uart_api_read(buffer, sizeof(buffer))) > 0)

  {

uart_api_read(buffer,len);

}

 

最新回复

期待看实物图  详情 回复 发表于 2023-12-14 10:17
点赞 关注
 
 

回复
举报

6628

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

期待后面的测试项目

 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

 /* Place your implementation of fputc here */,,,,,单片机编程的话用什么软件,谢谢

 
 
 

回复

223

帖子

3

TA的资源

一粒金砂(高级)

4
 

期待看实物图


 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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