0
点赞
收藏
分享

微信扫一扫

【联盛德W806上手笔记】六、7816/UART 控制器

大南瓜鸭 2022-01-23 阅读 123

目录

Windows 10 20H2
HLK-W806-V1.0-KIT
WM_SDK_W806_v0.6.0


       摘自《W806 芯片设计指导书 V1.0》、《W806 MCU 芯片规格书 V2.0》

7816/UART 控制器

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述

兼容 UART 以及 7816 接口功能

串口功能

7816 接口功能

下载口

       W806 芯片默认 UART0 为下载口,芯片无固件初始下载时,直接连接 UART0 接口,通过相关下载软件即可实现固件下载。当芯片内有固件,再次进入下载模式,可以通过拉低 BOOTMODE,然后上电进入下载模式。下载完成后去掉 BOOTMODE 拉低的操作,需要重启,固件才能运行。

库函数

函数

       打开wm_uart.h,有如下的函数声明:

//初始化所用串口的波特率、数据位、停止位、校验位、模式等
HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef *huart);

//将初始化之后的串口恢复成默认的状态–各个寄存器复位时的值
HAL_StatusTypeDef HAL_UART_DeInit(UART_HandleTypeDef *huart);

//串口发送数据,使用超时管理机制 
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

//串口接收数据,使用超时管理机制
HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

//串口中断模式发送  
HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

/**
  * 以中断方式接收一定长度的数据.
  * 注意:pData指向的地址,空间长度必须大于等于32字节
  * 	  Size大于0,则接收够Size长度的数据执行一次HAL_UART_RxCpltCallback(huart);
  * 	  Sized等于0,则接收不定长的数据就执行一次HAL_UART_RxCpltCallback(huart);
  *       两种情况下,数据都存放在huart->pRxBuffPtr或者pData中,数据长度存放在huart->RxXferCount中
  */
HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

//串口中断服务函数,用来响应各种串口中断。
//函数实体里面有两个功能,一是清除中断标记位,二是调用相应的回调函数,
//如UART_Receive_IT、UART_Transmit_IT、UART_EndTransmit_IT
void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);

//串口发送中断回调函数,被UART_EndTransmit_IT调用
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);

//串口接收中断回调函数,被UART_Receive_IT调用
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

参数

结构体和枚举类型
看到STM32绷不住了

typedef struct
{
	uint32_t BaudRate;                  /*!< This member configures the UART communication baud rate.
										   The baud rate is computed using the following formula:
										   - IntegerDivider = ((PCLKx) / (16 * (huart->Init.BaudRate)))
										   - FractionalDivider = ((IntegerDivider - ((uint32_t) IntegerDivider)) * 16) + 0.5 */

	uint32_t WordLength;                /*!< Specifies the number of data bits transmitted or received in a frame.
										   This parameter can be a value of @ref UART_Word_Length */

	uint32_t StopBits;                  /*!< Specifies the number of stop bits transmitted.
										   This parameter can be a value of @ref UART_Stop_Bits */

	uint32_t Parity;                    /*!< Specifies the parity mode.
										   This parameter can be a value of @ref UART_Parity
										   @note When parity is enabled, the computed parity is inserted
												 at the MSB position of the transmitted data (9th bit when
												 the word length is set to 9 data bits; 8th bit when the
												 word length is set to 8 data bits). */

	uint32_t Mode;                      /*!< Specifies whether the Receive or Transmit mode is enabled or disabled.
										   This parameter can be a value of @ref UART_Mode */

	uint32_t HwFlowCtl;                 /*!< Specifies whether the hardware flow control mode is enabled or disabled.
										   This parameter can be a value of @ref UART_Hardware_Flow_Control */

	uint32_t OverSampling;              /*!< Specifies whether the Over sampling 8 is enabled or disabled, to achieve higher speed (up to fPCLK/8).
										   This parameter can be a value of @ref UART_Over_Sampling. This feature is only available 
										   on STM32F100xx family, so OverSampling parameter should always be set to 16. */
} UART_InitTypeDef;

typedef enum
{
	HAL_UART_STATE_RESET             = 0x00U,    /*!< Peripheral is not yet Initialized
												   Value is allowed for gState and RxState */
	HAL_UART_STATE_READY             = 0x20U,    /*!< Peripheral Initialized and ready for use
												   Value is allowed for gState and RxState */
	HAL_UART_STATE_BUSY              = 0x24U,    /*!< an internal process is ongoing
												   Value is allowed for gState only */
	HAL_UART_STATE_BUSY_TX           = 0x21U,    /*!< Data Transmission process is ongoing
												   Value is allowed for gState only */
	HAL_UART_STATE_BUSY_RX           = 0x22U,    /*!< Data Reception process is ongoing
												   Value is allowed for RxState only */
	HAL_UART_STATE_BUSY_TX_RX        = 0x23U,    /*!< Data Transmission and Reception process is ongoing
												   Not to be used for neither gState nor RxState.
												   Value is result of combination (Or) between gState and RxState values */
	HAL_UART_STATE_TIMEOUT           = 0xA0U,    /*!< Timeout state
												   Value is allowed for gState only */
	HAL_UART_STATE_ERROR             = 0xE0U     /*!< Error
												   Value is allowed for gState only */
} HAL_UART_StateTypeDef;

typedef struct __UART_HandleTypeDef
{
	USART_TypeDef                 *Instance;        /*!< UART registers base address        */

	UART_InitTypeDef              Init;             /*!< UART communication parameters      */

	uint8_t                       *pTxBuffPtr;      /*!< Pointer to UART Tx transfer Buffer */

	uint16_t                      TxXferSize;       /*!< UART Tx Transfer size              */

	__IO uint16_t                 TxXferCount;      /*!< UART Tx Transfer Counter           */

	uint8_t                       *pRxBuffPtr;      /*!< Pointer to UART Rx transfer Buffer */

	uint16_t                      RxXferSize;       /*!< UART Rx Transfer size              */

	__IO uint16_t                 RxXferCount;      /*!< UART Rx Transfer Counter           */

	HAL_LockTypeDef               Lock;             /*!< Locking object                     */

	__IO HAL_UART_StateTypeDef    gState;           /*!< UART state information related to global Handle management
													   and also related to Tx operations.
													   This parameter can be a value of @ref HAL_UART_StateTypeDef */

	__IO HAL_UART_StateTypeDef    RxState;          /*!< UART state information related to Rx operations.
													   This parameter can be a value of @ref HAL_UART_StateTypeDef */

	__IO uint32_t                 ErrorCode;        /*!< UART Error code                    */

}UART_HandleTypeDef;

typedef enum
{
	UART_FIFO_TX_NOT_FULL,
	UART_FIFO_TX_EMPTY,
	UART_FIFO_RX_NOT_EMPTY,
} HAL_UART_WaitFlagDef;

宏参数

#define UART0		((USART_TypeDef *)UART0_BASE)
#define UART1		((USART_TypeDef *)UART1_BASE)
#define UART2		((USART_TypeDef *)UART2_BASE)
#define UART3		((USART_TypeDef *)UART3_BASE)
#define UART4		((USART_TypeDef *)UART4_BASE)
#define UART5		((USART_TypeDef *)UART5_BASE)

#define UART_FIFO_FULL 32

#define HAL_UART_ERROR_NONE              0x00000000U   /*!< No error            */
#define HAL_UART_ERROR_FE                0x00000040U   /*!< Frame error         */
#define HAL_UART_ERROR_PE                0x00000080U   /*!< Parity error        */
#define HAL_UART_ERROR_ORE               0x00000100U   /*!< Overrun error       */

#define UART_WORDLENGTH_5B                  ((uint32_t)UART_LC_DATAL_5BIT)
#define UART_WORDLENGTH_6B                  ((uint32_t)UART_LC_DATAL_6BIT)
#define UART_WORDLENGTH_7B                  ((uint32_t)UART_LC_DATAL_7BIT)
#define UART_WORDLENGTH_8B                  ((uint32_t)UART_LC_DATAL_8BIT)

#define UART_STOPBITS_1                     0x00000000
#define UART_STOPBITS_2                     ((uint32_t)UART_LC_STOP)

#define UART_PARITY_NONE                    0x00000000
#define UART_PARITY_EVEN                    ((uint32_t)UART_LC_PCE)
#define UART_PARITY_ODD                     ((uint32_t)(UART_LC_PCE | UART_LC_PS))

#define UART_HWCONTROL_NONE                  0x00000000U
#define UART_HWCONTROL_RTS                   ((uint32_t)UART_FC_AFCE)
#define UART_HWCONTROL_CTS                   ((uint32_t)UART_FC_AFCE)
#define UART_HWCONTROL_RTS_CTS               ((uint32_t)UART_FC_AFCE)

#define UART_MODE_RX                        ((uint32_t)UART_LC_RE)
#define UART_MODE_TX                        ((uint32_t)UART_LC_TE)
#define UART_MODE_TX_RX                     ((uint32_t)(UART_LC_RE | UART_LC_TE))

#define UART_STATE_DISABLE                  0x00000000U
#define UART_STATE_ENABLE                   ((uint32_t)(UART_LC_RE | UART_LC_TE))

#define __HAL_UART_ENABLE(__HANDLE__)               ((__HANDLE__)->Instance->LC |= (UART_LC_RE | UART_LC_TE))

#define __HAL_UART_DISABLE(__HANDLE__)              ((__HANDLE__)->Instance->LC &= ~(UART_LC_RE | UART_LC_TE))

#define __HAL_UART_GET_FLAG(__HANDLE__, __FLAG__, __OPERATING__) (__OPERATING__(__HANDLE__, __FLAG__))

#define IS_UART_INSTANCE(INSTANCE) (((INSTANCE) == UART0) || \
                                    ((INSTANCE) == UART1) || \
                                    ((INSTANCE) == UART2) || \
                                    ((INSTANCE) == UART3)  || \
									((INSTANCE) == UART4)  || \
                                    ((INSTANCE) == UART5))
									
#define IS_UART_WORD_LENGTH(LENGTH) (((LENGTH) == UART_WORDLENGTH_5B) || \
                                     ((LENGTH) == UART_WORDLENGTH_6B) || \
									 ((LENGTH) == UART_WORDLENGTH_7B) || \
                                     ((LENGTH) == UART_WORDLENGTH_8B))
									 
#define IS_UART_BAUDRATE(BAUDRATE) (((BAUDRATE) == 2000000) || \
                                    ((BAUDRATE) == 1500000) || \
                                    ((BAUDRATE) == 1250000) || \
                                    ((BAUDRATE) == 1000000) || \
									((BAUDRATE) == 921600)  || \
									((BAUDRATE) == 460800) || \
                                    ((BAUDRATE) == 230400) || \
                                    ((BAUDRATE) == 115200) || \
                                    ((BAUDRATE) == 57600) || \
									((BAUDRATE) == 38400)  || \
									((BAUDRATE) == 19200) || \
                                    ((BAUDRATE) == 9600) || \
                                    ((BAUDRATE) == 4800) || \
                                    ((BAUDRATE) == 2400) || \
									((BAUDRATE) == 1800)  || \
									((BAUDRATE) == 1200)  || \
                                    ((BAUDRATE) == 600))
									
#define IS_UART_STOPBITS(STOPBITS) (((STOPBITS) == UART_STOPBITS_1) || \
                                    ((STOPBITS) == UART_STOPBITS_2))
									
#define IS_UART_PARITY(PARITY) (((PARITY) == UART_PARITY_NONE) || \
                                ((PARITY) == UART_PARITY_EVEN) || \
                                ((PARITY) == UART_PARITY_ODD))
								
#define IS_UART_MODE(MODE) (((MODE) == UART_MODE_RX) || \
                               ((MODE) == UART_MODE_TX) || \
                               ((MODE) == UART_MODE_TX_RX))

#define IS_UART_HARDWARE_FLOW_CONTROL(CONTROL)\
                              (((CONTROL) == UART_HWCONTROL_NONE) || \
                               ((CONTROL) == UART_HWCONTROL_RTS) || \
                               ((CONTROL) == UART_HWCONTROL_CTS) || \
                               ((CONTROL) == UART_HWCONTROL_RTS_CTS))
											
							   
#define UART_RX_INT_FLAG (UART_INTS_OE | UART_INTS_PE | UART_INTS_FE |\
        UART_INTS_RL | UART_INTS_RTO | UART_INTS_BD)
		
#define UART_RX_ERR_INT_FLAG (UART_INTS_BD | UART_INTS_FE | \
        UART_INTS_PE)

#define UART_TX_INT_FLAG (UART_INTM_TL | UART_INTM_TEMPT)
									
#define __HAL_UART_ENABLE_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->INTM &= ~ __INTERRUPT__)

#define __HAL_UART_DISABLE_IT(__HANDLE__, __INTERRUPT__)  ((__HANDLE__)->Instance->INTM |= __INTERRUPT__)

#define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->INTS |= __FLAG__)

Demo中的测试程序

串口1收发实验:PB6: UART1_TX,PB7: UART1_RX

main.c


#include <stdio.h>
#include <string.h>
#include "wm_hal.h"
#include "fifo.h"

UART_HandleTypeDef huart1;

static void UART1_Init(void);
void Error_Handler(void);

#define IT_LEN 0 	// 大于等于0,0:接收不定长数据即可触发中断回调;大于0:接收N个长度数据才触发中断回调
static uint8_t buf[32] = {0}; // 必须大于等于32字节
#define LEN 2048
static uint8_t pdata[LEN] = {0};
int main(void)
{
	volatile int tx_len = 0;
	uint8_t tx_buf[100] = {0};
	
	SystemClock_Config(CPU_CLK_160M);
	printf("enter main\r\n");
	
	UART1_Init();
	FifoInit(pdata, LEN);
	HAL_UART_Receive_IT(&huart1, buf, IT_LEN);		// 只需调用一次,接收够设定的长度,进入中断回调,用户需要在中断回调中取走数据,此处设置了
												// 0个字节,即不定长
	while(1)
	{	
		tx_len = FifoDataLen();
		if (tx_len > 0)
		{
			tx_len = (tx_len > 100) ? 100 : tx_len;
			FifoRead(tx_buf, tx_len);
			HAL_UART_Transmit(&huart1, tx_buf, tx_len, 1000);
		}
	}
	
    return 0;
}

static void UART1_Init(void)
{
	huart1.Instance = UART1;
	huart1.Init.BaudRate = 115200;
	huart1.Init.WordLength = UART_WORDLENGTH_8B;
	huart1.Init.StopBits = UART_STOPBITS_1;
	huart1.Init.Parity = UART_PARITY_NONE;
	huart1.Init.Mode = UART_MODE_TX | UART_MODE_RX;
	huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
	if (HAL_UART_Init(&huart1) != HAL_OK)
	{
		Error_Handler();
	}
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (FifoSpaceLen() >= huart->RxXferCount)
	{
		FifoWrite(huart->pRxBuffPtr, huart->RxXferCount);
	}
}

void Error_Handler(void)
{
	while (1)
	{
	}
}

void assert_failed(uint8_t *file, uint32_t line)
{
	printf("Wrong parameters value: file %s on line %d\r\n", file, line);
}

wm_hal_msp.c


#include "wm_hal.h"

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
	if (huart->Instance == UART1)
	{
		__HAL_RCC_UART1_CLK_ENABLE();
		__HAL_RCC_GPIO_CLK_ENABLE();
		
	//	PB6: UART1_TX
	//	PB7: UART1_RX
		__HAL_AFIO_REMAP_UART1_TX(GPIOB, GPIO_PIN_6);
		__HAL_AFIO_REMAP_UART1_RX(GPIOB, GPIO_PIN_7);
		HAL_NVIC_SetPriority(UART1_IRQn, 0);
		HAL_NVIC_EnableIRQ(UART1_IRQn);
	}
}

void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
	if (huart->Instance == UART1)
	{
		__HAL_RCC_UART1_CLK_DISABLE();
		HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
	}

}

wm_it.c


#include "wm_hal.h"

#define readl(addr) ({unsigned int __v = (*(volatile unsigned int *) (addr)); __v;})
__attribute__((isr)) void CORET_IRQHandler(void)
{
	readl(0xE000E010);
	HAL_IncTick();
}

extern UART_HandleTypeDef huart1;

__attribute__((isr)) void UART1_IRQHandler(void)
{
	HAL_UART_IRQHandler(&huart1);
}

fifo.c


#include "fifo.h"
#include "string.h"

_fifo_str fifo_str;

int FifoInit(uint8_t *fifo_addr, uint32_t fifo_size)
{
	_fifo_str *p = &fifo_str;
	
	if(fifo_addr == NULL || fifo_size == 0)
		return -1;

	memset((char *)p, 0, sizeof(_fifo_str));
	p->buf = fifo_addr;
    p->in = 0;
    p->out = 0;
    p->size = fifo_size;
	return 0;
}

int FifoDataLen(void)
{
	_fifo_str *p = &fifo_str;
	
	return (p->in - p->out);
}

int FifoSpaceLen(void)
{
	_fifo_str *p = &fifo_str;
	
	return (p->size - (p->in - p->out));
}

int FifoRead(uint8_t *buf, uint32_t len)
{
	uint32_t i = 0, j = 0;
	_fifo_str *p = &fifo_str;

	j = (p->out % p->size);
	len = min(len, p->in - p->out);
	i = min(len, p->size - j);
	memcpy(buf, p->buf + j, i);
	memcpy(buf + i, p->buf, len - i);
	p->out += len;
	return len;
}

int FifoWrite(uint8_t *buf, uint32_t len)
{
	uint32_t i = 0, j = 0;
	_fifo_str *p = &fifo_str;

	j = p->in % p->size;
	len = min(len, p->size - p->in + p->out);
	i = min(len, p->size - j);
	memcpy(p->buf + j, buf, i);
	memcpy(p->buf, buf + i, len - i);
	p->in += len;

	return len;
}

void FifoClear(void)
{
	_fifo_str *p = &fifo_str;
	
    p->in = 0;
    p->out = 0;
}

fifo.h

#ifndef _FIF0_H_
#define _FIFO_H_

#include "wm_hal.h"

typedef struct fifo_t {
    uint8_t *buf;
	uint32_t size;
	uint32_t in;
	uint32_t out;
} _fifo_str;

#define min(x,y) ((x) < (y)?(x):(y))

int FifoInit(uint8_t *fifo_addr, uint32_t fifo_size);

int FifoDataLen(void);

int FifoSpaceLen(void);

int FifoRead(uint8_t *buf, uint32_t len);

int FifoWrite(uint8_t *buf, uint32_t len);

void FifoClear(void);


#endif

在这里插入图片描述

举报

相关推荐

0 条评论