简单认认识一下uart串口(附51代码与stm32标准库代码)

uart我们称为通用异步收发器(Universal Asynchronous Receiver/Transmitter)

在使用之前,我们先认识一下他的结构

 我们可以看到,RX,TX,GND,在实际使用中还要加上VCC

引脚介绍

VCC:供电pin,一般是3.3v

GND:接地pin,一般可不接,但是为了接受数据的稳定,还是要接上

RX(Receive):接收数据pin,与第二个设备接TX

TX(Transmit):发送数据pin,与第二个设备接RX(一定要注意,经常有人插反)

设备间通信有3种模式:

单工(仅在一个方向)

全双工(两个设备同时发送和接收)

半双工(设备轮流发送和接收)

uart双向通信,可以实现全双工!

通信也分为同步和异步

同步通信:一方发送,另一方应答,否则不进行下一次传输

异步通信:一方发送,不考虑另一方是否收到,直接进行下一次传输

为了不让uart串口在传输数据时出错,设备间通信时会提前人为规定好速率(波特率)

常用波特率是9600和115200,意为在一秒内传输9600个或115200个bit位(0或1)

我随便想一个波特率行不行

当然不行,主要是因为

一,通信双方必须事先设定相同的波特率这样才能成功通信,如果发送方个接受方按照不同的波特率通信则根本收不到有效信息,因此波特率最好是大家熟知的而不是随意指定。

二,经过了长久的发展形成了共识,大家常用的是9600或115200。

下面放代码

8051

/*9600 11.0592mhz*/
void UART_Init()
{
	SCON=0x40;
	PCON |= 0x80;
	TMOD &= 0x0F;		//设置定时器模式
	TMOD |= 0x20;		//设置定时器模式
	TL1 = 0xFD;		//设定定时初值
	TH1 = 0xFD;		//设定定时器重装值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
}


void UART_SendByte(unsigned char Byte)//串口发送一个字节数据
{
	SBUF=Byte;
	while(TI==0);
	TI=0;
}

void UART_Routine() interrupt 4
{
	if(RI==1)//如果收到了数据
	{
		//这里加入自己想实现的功能
		RI=0;
	}
}

 stm32代码,这里放江科大的代码,他做的功能比较多适合大家使用

#include "stm32f10x.h"                  // Device header
#include <stdio.h>
#include <stdarg.h>

uint8_t Serial_RxData;
uint8_t Serial_RxFlag;

void Serial_Init(void)//串口初始化
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//开启串口1时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启gpioa时钟
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//配置gpioa9为复用推挽输出
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//配置gpioa为上拉输入
	
	USART_InitTypeDef USART_InitStructure;
	USART_InitStructure.USART_BaudRate = 9600;//9600波特率
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//禁用串口流控制
	USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//RX,TX双模式
	USART_InitStructure.USART_Parity = USART_Parity_No;//0奇偶校验位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;//1停止位
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8数据位
	USART_Init(USART1, &USART_InitStructure);
	
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口1中断,读寄存器非空产生中断
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_InitTypeDef NVIC_InitStructure;
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//选择串口1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ 通道使能
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级1
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//子优先级1
	NVIC_Init(&NVIC_InitStructure);
	
	USART_Cmd(USART1, ENABLE);
}

void Serial_SendByte(uint8_t Byte)//发送字节
{
	USART_SendData(USART1, Byte);
	while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void Serial_SendArray(uint8_t *Array, uint16_t Length)//发送数组
{
	uint16_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Array[i]);
	}
}

void Serial_SendString(char *String)//发送字符串
{
	uint8_t i;
	for (i = 0; String[i] != '\0'; i ++)
	{
		Serial_SendByte(String[i]);
	}
}

uint32_t Serial_Pow(uint32_t X, uint32_t Y)//乘方
{
	uint32_t Result = 1;
	while (Y --)
	{
		Result *= X;
	}
	return Result;
}

void Serial_SendNumber(uint32_t Number, uint8_t Length)//发送数字
{
	uint8_t i;
	for (i = 0; i < Length; i ++)
	{
		Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0');
	}
}

int fputc(int ch, FILE *f)//重定向printf
{
	Serial_SendByte(ch);
	return ch;
}

void Serial_Printf(char *format, ...)//重定向printf
{
	char String[100];
	va_list arg;
	va_start(arg, format);
	vsprintf(String, format, arg);
	va_end(arg);
	Serial_SendString(String);
}

uint8_t Serial_GetRxFlag(void)//获取接收标志位
{
	if (Serial_RxFlag == 1)
	{
		Serial_RxFlag = 0;
		return 1;
	}
	return 0;
}

uint8_t Serial_GetRxData(void)//获取接收数据
{
	return Serial_RxData;
}

void USART1_IRQHandler(void)//串口一 中断服务函数
{
	if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
	{
		Serial_RxData = USART_ReceiveData(USART1);
		Serial_RxFlag = 1;
		USART_ClearITPendingBit(USART1, USART_IT_RXNE);
	}
}

  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用标准STM32F407和OpenMV之间进行串口通信的示例代码: 在STM32F407上的代码(使用HAL): ```c #include "stm32f4xx.h" #include "stm32f4xx_hal.h" UART_HandleTypeDef huart2; void UART_Init(void) { // 初始化串口2 huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(&huart2); } void UART_SendData(uint8_t *data, uint16_t size) { HAL_UART_Transmit(&huart2, data, size, HAL_MAX_DELAY); } void UART_ReceiveData(uint8_t *data, uint16_t size) { HAL_UART_Receive(&huart2, data, size, HAL_MAX_DELAY); } int main(void) { // 初始化串口 UART_Init(); uint8_t txBuffer[] = "Hello from STM32F407!"; uint8_t rxBuffer[100]; while (1) { // 发送数据到OpenMV UART_SendData(txBuffer, sizeof(txBuffer)); // 接收来自OpenMV的数据 UART_ReceiveData(rxBuffer, sizeof(rxBuffer)); // 处理接收到的数据 // ... HAL_Delay(1000); } } ``` 在OpenMV上的代码(使用MicroPython语言): ```python import pyb uart = pyb.UART(3, 115200) while(True): # 接收来自STM32F407的数据 rx_data = uart.read(100) if rx_data is not None: # 处理接收到的数据 # ... # 发送数据到STM32F407 tx_data = "Hello from OpenMV!" uart.write(tx_data) ``` 请注意,以上代码仅为示例,具体的实现方式可能根据你的需求和硬件连接而有所调整。还需要确保双方串口通信参数的一致性,例如波特率、数据位、停止位和校验位等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值