STM32F407模拟串口实现

本文介绍了在STM32F407项目中因串口数量限制,采用IO口模拟串口通信的方法。发送部分通过延时函数实现,接收部分则利用外部中断和定时器中断来检测电平变化。详细阐述了模拟串口发送和接收的实现思路,包括波特率计算、延时问题以及接收状态机的设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景

最近做一个项目,需要用STM32F407来做7路串口通信,由于芯片最多只有6路,所以只能用IO口来模拟串口通信。在网上查找了很多模拟串口的资料,决定串口发送采用延时的方式,串口接收采用外部中断+定时器中断来实现。外部中断检测第一次检测下降沿表明接收到了起始位,通过定时器中断定时检测接收IO口上的电平,从而判断接收的是0还是1.

二、正文

1)、串口发送:

由于串口发送的函数比较简单,所以先从发送开始做起,首先咱们来熟悉一下串口协议,1位起始位+8位数据位+1位奇偶校验位+1位停止位(其中停止位可能为0.5,1,1.5位或2位,可以选择)。串口异步传输在空闲状态时都必须是高电平。 

由于现在是模拟串口,暂时不考虑复杂的奇偶校验位,所以采用的格式为:1位起始位+8位数据位+1位奇偶校验位+1位停止位。项目需要采用的波特率为115200,所以每发送1bit数据需要的时间:1/115200=8.68us.

模拟串口发送发送函数:

 1 #define COM1_TX_PORT   GPIOA
 2 
 3 #define COM1_TX_PIN    GPIO_Pin_9
 4 
 5 void Virtual_Uart_Bytesend(u8 val)
 6 
 7 {
 8 
 9 u8 i=0;
10 
11 COM1_TX_DATA_LOW();  // 起始位,低电平,IO口初始化时应该置为高电平
12 
13 delay_us(baudRate);
14 
15     for(i = 0;i<8;i++)          // 8位数据位
16 
17 {
18 
19     if (val & 0x01)
20 
21 {
22 
23     COM1_TX_DATA_HIGH();
24 
25 }
26 
27 else
28 
29 {
30 
31     COM1_TX_DATA_LOW();
32 
33 }
34 
35 delay_us(baudRate);
36 
37 val >>= 1;
38 
39 }
40 
41 COM1_TX_DATA_HIGH();    // 停止位 高电平
42 
43 delay_us(baudRate);
44 
45 }

以上代码完全是根据协议的格式来写的,思路很简单,里面最重要的一个参数是这个baundRate;这个参数根据不同的波特率而不同,并且实际值和理论值算出来的时间可能有些差别,调试发现STM32F4的误差比较小,基本上理论值和实际值一样就可以正常通信。波特率为115200,延时理论上为8.68us。但是问题就来了,STM32F407例程delay.c里给的延时函数最小单位为us,设置baundRate=8或者9通信偶尔能够正常接收,但是很多时候是乱码,如下图:

 

如何解决这一问题呢,首先想到是设计一个延时0.1us

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值