STM32L15系列IO模拟串口失败,请教

最近在做一个项目,因为需要用到多个串口,硬件串口就显得不够用了,所以 就打起了IO口模拟串口的主意,然后通过将IO口设置为下降沿中断来捕获串口传送开始的信号

TIM截图20190318084126.png

于是做了入图的配置,之所以设置为下拉,是因为我发现,如果设置为上拉,如果是因为不小心触发的中断则会导致接收到 FF 的数据,而且这样也并不会影响到下降沿中断的触发。

TIM截图20190318084906.png

然后也是最重要的就是IO口时序的模拟接收了,根据波特率定时查看IO口状态并进行记录程序如下(使用HAL库编写,CUBEMX 进行配置):

TIM截图20190318085528.png

这个时候问题就出来了,数据总是不能正确接收,delay_us的延时是通过定时器实现的,这个延时同时也在模拟I2C接口中有用到,系统时钟和定时器配置如下

sysCONF.png

sysCONFG.png

时钟配置为内部MSI  2M频率,不分频,则外设时钟和系统定时器都应该同样是2M频率

TIM6_INIT.png

TIM6的TIME_OUT = (period+1)/(prescaler+1)/clock = 2 / 1 / 2 = 1us ;  这里的计算应该没有问题吧,然后定时器回调函数做了如下处理

TIM6_callbacck.png

Nconter 是一个全局变量,下面是延时函数

delay_us.png


搞了好几天还是没搞明白是哪里出了问题导致接收到的数据总是不准确,我用示波器看了传入到芯片  IO  的数据的波形没有任何问题,所以烦请哪位大神看到了帮忙解惑一下是哪里出了问题,或者我该怎么测试去找出问题所在。






已邀请:

自带腹肌的西装

赞同来自:

有没有大佬来帮忙看一下

1、首先感觉延时1us最好不要使用定时器中断,中断的太频繁了,使用定时器的查询模式好点

2、当MCU检测到串口的起始位后应该关闭对应IO口的边沿中断检测否则当数据位中存在1-0的变化会再次触发中断的调用你的程序的形成了嵌套吧

3、当检测到下降沿后你通过延时10us来跳过起始位,但是对应波特率为115200的话一个bit位的时间大概8us,你延时10us后此时IO口的电平已经对应了串口数据中的D0位了,但是你的程序里面又延时了一个波特率对应的时间才读取D0位,那时IO口上的电平状态应该是D1位的电平吧,当然前面的10us延时取决于你的波特率也许你的波特率下合适本处只是分析下有这种可能引发的不正确,模拟的话推荐当检测到起始位的下降沿后应该延时1.5bit位时间立马读取第一位D0,然后循环延时1个bit位的时间读取后续位的数据,这样保证每次读取的都是一个bit位时间中间时刻对应的IO口数据干扰较小。

4、你应该调试下你接受的数据与你发送的数据一个字节的时候差多少,可以看看是那边出问题了

自带腹肌的西装

赞同来自:

首先感谢您的详细回答

1:1us的定时器只有在需要进行通讯并且需要延时的时候才会打开,其他时候都是关闭的,不过我可以去试一下你说的查询模式。

2:我是这样理解的不知道对不对:中断发生后进入到了  HAL_GPIO_EXTI_IRQHandler  然后会调用回调函数,回调函数还没有结束的话它不会再被自己或者比自己优先级低的中断打断,我现在设置的这个的中断等级是比较高的。不过您说的这一点我好像的确是忘记考虑了。

3:我用的是2400的Band一个bit 420us,那个10us是为了防止在下降沿过程中读取引脚电平,循环中的延时是延时420us的,第1次进来延时420us就跳过了开始信号的低电平,到达了bit0,然后读取引脚电平,第2次bit1,读取电平,第3次bit2,读取电平,

第4次bit3,读取电平,第5次bit4,读取电平,第6次bit5,读取电平,第7次bit6,读取电平,第8次bit7,读取电平,我之前也测试过在 bit 中间去读取,但是结果还是不正确。

4:一个byte的数据会偶尔错位一个 bit ,波形我也用示波器看了,有的 bit 位它的电平宽度也是有波动的。


我先试着改动一下您说的几点我没有注意到的地方,再测试一下,之后再回复您。

自带腹肌的西装

赞同来自:

今天用这个延时函数进行发送尝试,之前一直在拿接收进行尝试(因为我们只需要接收东西),我通过操作IO口高低电平然后通过示波器观察波形发现,延时函数100us 电平宽度在250左右,将延时时间进行相应放大后就能正常发送某 Band 的数据了,我又考虑了下导致这样结果的原因,我的SYSCLK和APB1和APB2均是2M的频率,再考虑语句执行时间和延时时间混在一起就导致了这种情况。所以我得到的经验教训就是,在主频比较低而你又要求定时单位比较小的时候(我现在是us级的定时),建议使用示波器看下,可能会存在很大误差。除非迫不得已,否则少用IO口模拟串口,帖子就到这里吧,问题找到了。


要回复问题请先登录注册