目录
前言
现在网上有很多基于HT32配置串口的博客,但是很杂,有一些存在一些问题,对于绝大多数人来说,串口就是用来调试输出就行。但是还有大部分人还是要求串口中断接收的。比如说你有视觉模块,要求通过视觉那边传回来的数据经过串口接收来控制单片机实现相应功能,又或者要使用网络模块esp8266,通过物联网控制单片机来实现要求的功能。但是我只是提供最简单的中断函数,没有数据解析和处理:根据外部传感器发送的数据格式,解析接收到的数据。对接收到的数据进行适当的处理,比如数据转换、存储或触发其他操作。
错误处理和超时处理:考虑在串口通信过程中可能出现的错误,如数据丢失、校验错误等,编写相应的错误处理代码。
实现超时机制,以避免长时间等待数据导致系统响应缓慢。现在来对合泰这块板子的串口进行配置,调试。
简介
接下来对USART0和USART1进行配置,引脚如下表所示:
在USART1接收的时候跳线帽要接到RS232上,USART0就要跳回去
USART.c
void USART0_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
{
CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
CKCUClock.Bit.AFIO = 1;
CKCUClock.Bit.PA = 1;
CKCUClock.Bit.USART0 = 1;
CKCU_PeripClockConfig(CKCUClock, ENABLE);
}
GPIO_PullResistorConfig(HT_GPIOA, GPIO_PIN_3, GPIO_PR_UP);
AFIO_GPxConfig(GPIO_PA, AFIO_PIN_2, AFIO_FUN_USART_UART);
AFIO_GPxConfig(GPIO_PA, AFIO_PIN_3, AFIO_FUN_USART_UART);
/*
波特率: 9600
长度: 8bits
停止位: 1位
校验位: 无
模式: 正常模式
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
USART_InitStructure.USART_Parity = USART_PARITY_NO;
USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
USART_Init(HT_USART0, &USART_InitStructure);
//中断设置
NVIC_EnableIRQ(USART0_IRQn);
USART_IntConfig(HT_USART0, USART_INT_RXDR, ENABLE);
// 使能 COM1_PORT 发送和接收
USART_TxCmd(HT_USART0, ENABLE);
USART_RxCmd(HT_USART0, ENABLE);
// USART_RXTLConfig(COM1_PORT, USART_RXTL_04); 设置FIFO接收等级
}
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
{
CKCU_PeripClockConfig_TypeDef CKCUClock = {{0}};
CKCUClock.Bit.AFIO = 1;
CKCUClock.Bit.PA = 1;
CKCUClock.Bit.USART1 = 1;
CKCU_PeripClockConfig(CKCUClock, ENABLE);
}
GPIO_PullResistorConfig(HT_GPIOA, GPIO_PIN_5, GPIO_PR_UP);
AFIO_GPxConfig(GPIO_PA, AFIO_PIN_4, AFIO_FUN_USART_UART);
AFIO_GPxConfig(GPIO_PA, AFIO_PIN_5, AFIO_FUN_USART_UART);
/*
波特率: 9600
长度: 8bits
停止位: 1位
校验位: 无
模式: 正常模式
*/
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WORDLENGTH_8B;
USART_InitStructure.USART_StopBits = USART_STOPBITS_1;
USART_InitStructure.USART_Parity = USART_PARITY_NO;
USART_InitStructure.USART_Mode = USART_MODE_NORMAL;
USART_Init(HT_USART1, &USART_InitStructure);
//中断设置
NVIC_EnableIRQ(USART1_IRQn);
USART_IntConfig(HT_USART1, USART_INT_RXDR, ENABLE);
// 使能 COM1_PORT 发送和接收
USART_TxCmd(HT_USART1, ENABLE);
USART_RxCmd(HT_USART1, ENABLE);
// USART_RXTLConfig(COM1_PORT, USART_RXTL_04); 设置FIFO接收等级
}
下面是发送数据到串口和重定向C库函数printf
和scanf
到串口函数
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 data)
{
USART_SendData(USARTx, data);
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXDE) == RESET);
}
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num)
{
u8 i;
for( i = 0;i < num;i++)
{
Usart_Sendbyte(USARTx,*array);
array++;
}
}
void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str)
{
uint8_t i;
for(i = 0;str[i] != '\0';i++)
{
Usart_Sendbyte(USARTx,str[i]);
}
}
//重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
while (USART_GetFlagStatus(HT_USART1, USART_FLAG_TXC) == RESET);
USART_SendData(HT_USART1, ch);
return ch;
}
// 重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
/* 等待串口输入数据 */
while (USART_GetFlagStatus(HT_USART1, USART_FLAG_RXDNE) == RESET);
return (int)USART_ReceiveData(HT_USART1);
}
USART.h
#ifndef __USART_H__
#define __USART_H__
#include "ht32.h"
#include "ht32f5xxxx_01.h"
void USART0_Configuration(void);
void USART1_Configuration(void);
void Usart_Sendbyte(HT_USART_TypeDef* USARTx, u8 data);
void Usart_SendArray(HT_USART_TypeDef* USARTx, u8 *array,u8 num);
void Usart_SendStr(HT_USART_TypeDef* USARTx, uint8_t *str);
void Modbus_Send_Byte(u8 Modbus_byte);
int fputc(int ch, FILE *f);
int fgetc(FILE *f);
#endif
下面是主函数对串口1的串口中断函数
main.c
#include "ht32.h"
#include "ht32_board.h"
#include "led.h"
#include "delay.h"
#include "USART.h"
#include "IIC.h"
#include "SHT30.h"
//#include "modbus485.h"
#include "motor.h"
#include "DC_Motor.h"
//#include "Timer.h"
int main()
{
USART1_Configuration();
DCMotor_Init();
while(1)
{
}
}
//串口接收跳线帽要接到RS232上
void USART1_IRQHandler(void) //串口1中断
{
if( USART_GetFlagStatus(HT_USART1, USART_FLAG_RXDR ) ) //接收中断
{
u8 data0 = USART_ReceiveData(HT_USART1); //读取接收到的数据
//printf("Received data: %c\n", data0);
switch(data0)
{
case '1':
DCmotor_run(50);;
Usart_SendStr(HT_USART1,"run\r\n");
break;
case '0':
DCmotor_run(0);
Usart_SendStr(HT_USART1,"stop\r\n");
break;
}
}
USART_ClearFlag(HT_USART1,USART_FLAG_RXDR);
}