华润微CS32ME10 MCU使用教程(2)---CS32ME10之UART串口模块使用

文章目录


一、UART串口协议简介;

串口协议(UART)是一种异步串行通信协议 ,仅需TX(发送)、RX(接收)和GND(地线)三根线即可实现全双工通信。通信连线示意图如下所示:

UART核心特征是"异步 ",即没有独立的时钟线收发双方需事先约定相同的波特率(如9600、57600、115200)来同步每位数据 。数据传输以一帧为单位:空闲时总线为高电平,发一个低电平起始位通知对方开始,随后依次发送5-9位数据(通常最低位在前 ),可选添加一位校验位用于简单检错,最后以1或2位高电平停止位结束。由于协议简单、接线少,串口被广泛用于单片机与传感器、GPS模块、蓝牙模块及电脑调试之间的通信。UART时序图如下所示:

二、CS32ME10串口模块使用;

2.1.UART普通输出模式;

设置好串口在主循环里轮询发送数据,可以用逻辑分析仪抓取验证。

CS32ME10串口模块配置步骤:

1、打开IO端口和串口时钟;

2、配置IO口的输入输出方向;

3、使能IO复用为串口功能;

4、配置串口模块(CS32ME10芯片默认串口输出使能);

c 复制代码
/* 普通串口输出测试*/
uint8_t uart_data[]={0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a};
void uart_send_test(void)
{
	uint8_t count = 0;
	UART_InitTypeDef uart0_initstruct;
	/*打开端口和外设时钟*/
	Rcc_Periph_config(RCC_Periph_GPIOA|RCC_Periph_UART0, ENABLE);
	/*配置TX,RX的方向*/
	Gpio_out_config(GPIOA_MODULE, GPIO_PIN_7, ENABLE);//TX
	Gpio_in_config(GPIOA_MODULE, GPIO_PIN_6, ENABLE);//RX
	/*配置IO口的复用功能*/
	Gpio_af_uart_config(GPIOA_MODULE, GPIO_PIN_6|GPIO_PIN_7, ENABLE);
	/*配置串口*/
	uart0_initstruct.UART_BaudRate	= 115200;
	uart0_initstruct.UART_Mode 	   	= UART_Mode_RXTX;
	uart0_initstruct.UART_Parity 	= UART_Parity_Odd;
	uart0_initstruct.UART_StopBits	= UART_Stop_bit1;
	uart0_initstruct.UART_WordLength= UART_WorldLength_bit8;
	Uart_Init(UART0_MODULE, &uart0_initstruct);
	/*发送数据*/
	while(1)
	{
		for(count=0;count<10;count++)
		{
			while(Uart_Get_Status(UART0_MODULE,UART_FLAG_TFF)){}	//等待发送完成
			Uart_SendData(UART0_MODULE, uart_data[count]);			//发送数据
		}
		delay_ms(50);												//50ms发送一次
	}
}

2.2.UART重定向至printf输出;

通过配置串口模块重定向至printf,可以直接使用c库函数的printf输出字符,可以通过串口助手验证。

CS32ME10串口模块配置步骤:

1、打开IO端口和串口时钟;

2、配置IO口的输入输出方向(;

3、使能IO复用为串口功能;

4、配置串口模块;

5、重定向printf函数;

7、记得使用keil自带的微库

c 复制代码
/* printf打印测试*/
void uart_printf_test(void)
{
	UART_InitTypeDef uart0_initstruct;
	/*打开端口和外设时钟*/
	Rcc_Periph_config(RCC_Periph_GPIOA|RCC_Periph_UART0, ENABLE);
	/*配置TX,RX的方向*/
	Gpio_out_config(GPIOA_MODULE, GPIO_PIN_7, ENABLE);//TX
	Gpio_in_config(GPIOA_MODULE, GPIO_PIN_6, ENABLE);//RX
	/*配置IO口的复用功能*/
	Gpio_af_uart_config(GPIOA_MODULE, GPIO_PIN_6|GPIO_PIN_7, ENABLE);
	/*配置串口*/
	uart0_initstruct.UART_BaudRate	= 115200;
	uart0_initstruct.UART_Mode 	   	= UART_Mode_RXTX;
	uart0_initstruct.UART_Parity 	= UART_Parity_Odd;
	uart0_initstruct.UART_StopBits	= UART_Stop_bit1;
	uart0_initstruct.UART_WordLength= UART_WorldLength_bit8;
	Uart_Init(UART0_MODULE, &uart0_initstruct);
	while(1)
	{
		printf("hello world \r\n");
		delay_ms(500);	
	}
}
/*串口重定向*/
int fputc(int ch,FILE *f)
{
	Uart_SendData(UART0_MODULE,(unsigned char)ch);
	while(Uart_Get_Status(UART0_MODULE,UART_FLAG_TFF)){}	//等待发送完成
	return (ch);
}

2.3.UART中断接收串口数据;

通过串口助手或者别的芯片发送数据到CS32ME10,ME10在中断接收后通过printf打印出来(在实际项目中最好不要在中断中使用printf)。

CS32ME10串口模块配置步骤:

1、打开IO端口和串口时钟;

2、配置IO口的输入输出方向(因为串口总是要输入输出);

3、使能IO复用为串口功能;

4、配置串口模块(华润的芯片默认就是串口输出使能);

5、开启串口接收中断并编程中断处理函数;

7、设置串口对应中断的优先级;

8、使能中断;

c 复制代码
void uart_int_receive_XCOM_data(void)
{
	UART_InitTypeDef uart0_initstruct;
	/*打开端口和外设时钟*/
	Rcc_Periph_config(RCC_Periph_GPIOA|RCC_Periph_UART0, ENABLE);
	/*配置TX,RX的方向*/
	Gpio_out_config(GPIOA_MODULE, GPIO_PIN_7, ENABLE);//TX
	Gpio_in_config(GPIOA_MODULE, GPIO_PIN_6, ENABLE);//RX
	/*配置IO口的复用功能*/
	Gpio_af_uart_config(GPIOA_MODULE, GPIO_PIN_6|GPIO_PIN_7, ENABLE);
	/*配置串口*/
	uart0_initstruct.UART_BaudRate	= 115200;
	uart0_initstruct.UART_Mode 	   	= UART_Mode_RXTX;
	uart0_initstruct.UART_Parity 	= UART_Parity_Odd;
	uart0_initstruct.UART_StopBits	= UART_Stop_bit1;
	uart0_initstruct.UART_WordLength= UART_WorldLength_bit8;
	Uart_Init(UART0_MODULE, &uart0_initstruct);
	/*打开串口接收中断*/
	Uart_interrupt_config(UART0_MODULE,UART_IT_RFNE,ENABLE);
	/*设置串口中断优先级*/
	NVIC_SetPriority(UART0_IRQn, 2);
	/*使能串口中断*/
	NVIC_EnableIRQ(UART0_IRQn);
	//.....具体处理过程见中断处理函数
	while(1)
	{

	}
}

/**
	* @name :UART0_IRQHandler
	* @功能 :UART0中断服务函数
	* @param :无
	* @retval: 无
*/
void UART0_IRQHandler(void)
{
	uint8_t a;
	if(Uart_Get_Status(UART0_MODULE, UART_IT_RFNE)!=UART_IT_RFNE)
	{
		a = Uart_ReadData(UART0_MODULE);
		printf("a=%x \r\n",a);
	}
}

三、UART模块重构版库函数;

c 复制代码
#include "me10_uart.h"

/**
	* @name Uart_config
	* @功能 :串口模块配置
	* @param uart_module 需要配置的UART模块
		@arg UART0_MODULE
		@arg UART1_MODULE
	* @param uart_initstruct 
	* @retval: 无
*/
void Uart_Init(UART_REG * uart_module, UART_InitTypeDef* uart_initstruct)
{
	uint32_t reg_value = uart_module->UART_CR;
	uint32_t DIV;
	/* 计算波特率分频系数*/
	#if SYSCLK_48MHZ
		DIV = 48000000/uart_initstruct->UART_BaudRate;
	#elif SYSCLK_24MHZ
		DIV = 24000000/uart_initstruct->UART_BaudRate;
	#elif SYSCLK_12MHZ
		DIV = 12000000/uart_initstruct->UART_BaudRate;
	#elif SYSCLK_6MHZ
		DIV = 6000000/uart_initstruct->UART_BaudRate;
	#endif
	/* 获取串口的基本配置*/
	reg_value = (uint32_t)( uart_initstruct->UART_Mode|\
							uart_initstruct->UART_Parity|\
							uart_initstruct->UART_StopBits|\
							uart_initstruct->UART_WordLength);
	/* 最终要写入寄存器的值*/
	reg_value |= (DIV<<8);
	/* 将配置信息写入寄存器*/
	uart_module->UART_CR |= reg_value;
}

/**
	* @name Uart_SendData
	* @功能 :串口发送数据接口
	* @param uart_module 需要发送数据的UART模块
		@arg UART0_MODULE
		@arg UART1_MODULE
	* @param data 		 需要发送的数据
	* @retval: 无
*/
void Uart_SendData(UART_REG * uart_module, uint8_t data)
{
	uart_module->UART_DO = data;
}

/**
	* @name Uart_ReadData
	* @功能 :串口读取数据接口
	* @param uart_module 需要读取数据的UART模块
		@arg UART0_MODULE
		@arg UART1_MODULE
	* @retval: ret_value 返回读出的数据
*/
uint8_t Uart_ReadData(UART_REG * uart_module)
{
	uint8_t ret_value;
	ret_value = uart_module->UART_DI;
	return ret_value;
}

/**
	* @name Uart_Get_Status
	* @功能 :获取串口状态(由用户去判断何种状态是否发生)
	* @param uart_module	 需要获取状态的UART模块
		@arg UART0_MODULE
		@arg UART1_MODULE
	* @param uart_flag 		 需要获取的状态
		 @arg UART_FLAG_RBSY   ((uint32_t)0x00000001)	//接收忙标识, 1 表示正在接收
 		 @arg UART_FLAG_TBSY   ((uint32_t)0x00000002)	//发送忙标识, 1 表示正在发送
  		 @arg UART_FLAG_RFF    ((uint32_t)0x00000004)	//接收 FIFO 满标识, 1 表示满
  		 @arg UART_FLAG_TFF    ((uint32_t)0x00000008)	//发送 FIFO 满标识, 1 表示满
  		 @arg UART_FLAG_TFE    ((uint32_t)0x00000010)	//发送 FIFO 空标识, 1 表示空
  		 @arg UART_IT_PE       ((uint32_t)0x01000000)	//校验错中断标志位,1:表示校验出错 写"0"清零
  		 @arg UART_IT_ROV      ((uint32_t)0x02000000)	//接收 FIFO 溢出中断标志位,1:表示接收 FIFO 溢出, 写"0"清零
  		 @arg UART_IT_RFNE     ((uint32_t)0x04000000)	//接收到数据中断标志位,"1"表示空,"0"表示有接收到数据,数据读完自动恢复 1
  		 @arg UART_IT_TC       ((uint32_t)0x08000000)	//数据发送完成 中断标志位 (每发送完一个 数据 产生中断),"1"表示 一个数据发送已经完成,写"0"清零
  		 @arg UART_IT_TFE      ((uint32_t)0x10000000)	//TXFIFO空中断标志位,1:表示 TXFIFO 空 ,写入数据后自动清零
  		 @arg UART_IT_RFF      ((uint32_t)0x20000000)	//RXFIFO满中断标志位,1:表
	* @retval: ret_value 	返回对应状态的bit值,由用户判断状态是否发生
*/
uint32_t Uart_Get_Status(UART_REG * uart_module, uint32_t uart_flag)
{
	uint32_t ret_value;
	ret_value = uart_module->UART_SR & uart_flag;
	return ret_value;
}

/**
	* @name Uart_interrupt_config
	* @功能 :设置相应的串口中断是否开启
	* @param uart_module	 需要设置中断的UART模块
		@arg UART0_MODULE
		@arg UART1_MODULE
	* @param uart_it 		 需要设屏蔽或者开启的中断
  		 @arg UART_IT_PE       ((uint32_t)0x01000000)	//校验错中断标志位,1:表示校验出错 写"0"清零
  		 @arg UART_IT_ROV      ((uint32_t)0x02000000)	//接收 FIFO 溢出中断标志位,1:表示接收 FIFO 溢出, 写"0"清零
  		 @arg UART_IT_RFNE     ((uint32_t)0x04000000)	//接收到数据中断标志位,"1"表示空,"0"表示有接收到数据,数据读完自动恢复 1
  		 @arg UART_IT_TC       ((uint32_t)0x08000000)	//数据发送完成 中断标志位 (每发送完一个 数据 产生中断),"1"表示 一个数据发送已经完成,写"0"清零
  		 @arg UART_IT_TFE      ((uint32_t)0x10000000)	//TXFIFO空中断标志位,1:表示 TXFIFO 空 ,写入数据后自动清零
  		 @arg UART_IT_RFF      ((uint32_t)0x20000000)	//RXFIFO满中断标志位,1:表
	* @param: flag 	
		 @arg ENABLE	开启
		 @arg DISABLE   屏蔽
*/
void Uart_interrupt_config(UART_REG * uart_module, uint32_t uart_it , FunctionalState flag)
{
	if(flag)
	{
		uart_module->UART_CR |= uart_it;		//开启相应的中断
	}
	else
	{
		uart_module->UART_CR &= (~uart_it);		//屏蔽相应的中断
	}
}

*此教程仅记录个人使用过程,仅供参考学习,且本教程使用的库函数均为重构的版本,不代表官方文档,谢谢!

相关推荐
神一样的老师1 小时前
【兆易创新GD32VW553开发板试用】天气时钟设计与调试实战
单片机·嵌入式硬件·物联网
国科安芯2 小时前
核电站仪控与监测系统中抗辐射 MCU 芯片应用研究
单片机·嵌入式硬件·macos·无人机·cocos2d·核电站
黑白园2 小时前
STM32系统时钟由72M修改为36M验证示例
stm32·单片机·嵌入式硬件
LCG元3 小时前
基于ARM7的LCD设计与实现:S3C4510B通用IO口控制液晶模块
stm32·单片机·嵌入式硬件
山后太阳3 小时前
Keil5(MDK-ARM)完整下载安装教程+入门教程:从零搭建STM32开发环境
arm开发·stm32·嵌入式硬件
The_superstar64 小时前
衡山派学习之串口
单片机·嵌入式硬件·串口·衡山派
Ww.xh4 小时前
STM32按键去抖动软件实现详解
stm32·单片机·嵌入式硬件
ghie90904 小时前
基于STM32的CAN通信完整例程(HAL库实现)
stm32·单片机·嵌入式硬件
lzj_pxxw4 小时前
W25Q64存储芯片 软件设计刚需常识
stm32·单片机·嵌入式硬件·mcu·学习