什么引起串口中断

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了什么引起串口中断相关的知识,希望对你有一定的参考价值。

我是个菜鸟,请问什么情况会引起串口中断,比如是否只要SBUF有数据就会引发串口中断,还是设置ES=1就会引起一次串口中断,还是TI或RI=1引发串口中断,不要复制别人答案,谢谢!

SBUF中的数据发送完毕,TI传送结束标志置1,如果设置了ES=1(串口中断是允许的),就进入串口中断服务程序。解决方法如下:

1、首先打开Cube工程,在Pinout页使能需要使用的串口。

2、切换到“Configuration”页,找到并点击需要使用的串口,比如之前选择的USART2。

3、在弹出的“xxx Configuration”对话框中选择“NVIC Settings”,勾选“xxx global interrupt”的Enabled,其中xxx为目标串口名称。

4、回到“Configuration”页,在“NVIC Configuration”对话框点击“Code generation”,勾选“xxx global interrupt”的Generate IRQ handler和“Select for init sequence ord...”。

5、点击“Project ->Generate Code”生成代码。

6、重写HAL_UART_RxCpltCallback回调函数,这里的代码通过判断huart ->Instance是否为USART2,然后将接收的data使用阻塞方式发送出去,接着再启动接收就可以了。

参考技术A 1、 你要发送的数据,经串行口发送后,SCON中的TI会置1,这时候就会有串行口中断,通知单片机数据已经发送成功,单片机就可以进入串行口中断程序(汇编中入口地址0023H),这时候你就可以再一次发送数据,也就是将数据写到SBUF中,发送后中断返回,等到发送成功后会再一次产生串行口中断,这时你就可以再次进入中断处理程序,发送数据。
流程是: (主程序中)发送数据--等待中断--发送成功产生中断--进入中断清除TI,再次发送--中断返回---等待中断---发送成功产生中断--进入中断清除TI,再次发送。。。。 循环而已

2、如果你想定时发送,比如每隔一段时间发送一次,这时你可以用定时器,在定时器的中断处理程序中发送数据,而不去理会串行口中断(可以关闭串行口中断或者在串行口中断中什么也不做直接返回)。
需要注意的是:如果你用串行口工作方式1或者3,那么定时器1就被作为波特率发生器,是不能开定时器1的中断的。定时器0不受影响,可以用。如果你选的是方式2,则两个定时器都可以用,也可以组合使用,产生较长时间定时。

3、你想用外中断触发,来发送数据的话,和2情况相同,此时可以由你自己手工控制什么时候发送,只需要关闭串行口中断(默认为关闭),开外中断,在外中断处理程序中发送数据,要想知道发送成功了没有,可以检查TI,不影响外中断。

综合来说就是中断可开可闭,也可以同时用两个甚至多个,但这样容易引起数据发不到就被另一个中断打断,最好根据实际情况选择其中一种

关于计数结束
你的计数结束表述不明确啊,是计数器溢出了计数结束呢,还是说后面没有脉冲了(即外部脉冲结束了)计数结束呢?如果是前者,很简单只要在计数器的中断处理程序中完成你所需的操作,如果是后者,就没那么简单了,因为单片机不可能知道什么时候外部脉冲什么时候结束,除非用外部中断的方式通知单片机,你可以在外部中断处理程序中,完成取数,给上位机通过串口送数,这时候你必须做出选择 1,如果某次计数结束,你上一次经过串口发送的数据,还没发送成功,你放弃本次发送 2,如果某次计数结束,你上一次经过串口发送的数据,还没发送成功,你继续发送,覆盖原来数据。

其实你应该把你的东西详细说出来,你只说一个方面,可能你的想法不太对路,我还要按照你的不太对路的想法给你解释,这样不太方便。 如果你想计数的话,一般的方法是,给一个定时器设定一个时间,另一个做计数器,定时器时间一到,就在段中取数,给上位机送数,定时器可工作在方式2,循环送数。不知道你是不是想做这个。
如果你是发送数据,你不应该把注意力放在串口中断上,除非你过分追求发送的成功率,一般情况下都能发送成功。
你说的“用串口中断传数给上位机”,这句话本身就有问题,TI是在发送完毕后产生中断,你甚至可以不理它,用定时器中断的处理程序来完成取数,送数。所以说你必须明确到底是发送完毕后立即再次发送(利用TI),还是每次你所谓的“计数结束”后发送数据(此时劝你不要在意TI)。
你问的最后一句,我不太清楚,不敢贸然回答。
参考技术B

我遇到了跟题主一样的问题,我感觉题主跟我的疑惑是一样的,下面来说说我的看法。(51系列,因为我也是刚接触,遇到很多问题,搜索的答案大多没有讲解这些很模糊的概念。希望大家能够共同进步吧)

首先ES = 1是串口中断的必要不充分条件,即想要发生串口中断ES必须置1,但是除此之外,串口中断还需要其它的条件才能触发。

其实TI与RI什么时候置一STC芯片上说得很清楚

主要关注方式1,其它方式基本用不到(可直接搜索所用芯片的芯片手册,如STC89C52)


其实到这里题主的问题已经解决了:串口中断的条件是TI/RI置1。

除此之外我想补充一下回答

以单片机接收数据为例,在电脑上输入1点击【发送数据】,单片机就开始接收数据了,这是由单片机硬件决定的(了解IO口模拟通信或许可以帮助理解),当数据接收到停止位1的中间位置时(怎么一位一位接收自行搜索……),RI由硬件置1,这时进入串口中断,你可以对接收的数据做出相应的操作。

参考技术C SBUF中的数据发送完毕,TI传送结束标志置1,如果设置了ES=1(串口中断是允许的),就进入串口中断服务程序

串口uart发送出错

大家好!我在做单片机串口的驱动。串口接收还好,但是发送只要波特率一高,就会出错。

我设置9600波特率,发送数据基本正确,但是如果调到115200,发送数据基本上全错了。

我是用中断写的,每发完一个数据就会产生一个中断,由中断服务程序负责将要发送的数据依次送出。

中断服务程序:
1.关中断
2.tx_buf++; (要发送的数据存在tx_buf里)
tx_cnt--; (要发送的数据个数)
3.开中断
4.IO_HSC1BUF=*tx_buf;

不知道我这样做对不对,为什么波特率一高,就出错?是不是应该加上一些延时,如果是的话,加哪呢?
麻烦大家指点下哦~

用示波器量一下波形,是否规整,如果信号失真太大。那么不能用高的波特率。
一般来讲,115200对于一般的单片机都能达到。
再就是传输距离,如果串口总线信号电压是12V,20m没什么太大问题。如果没有电压转换,距离太长了,波特率高了,信号失真太大。接收就会有问题
参考技术A 那 就用 9600波特率

可能 存在 误差
参考技术B 收发的波特率是否一致?最好贴出程序。
另外,太高的波特率会有误差的
参考技术C 你要看看你的晶振电路是不是有问题,先把晶振换个好的试试再说,如果不行,再看单片机的硬件设计是不是有问题,当然也可考虑程序

以上是关于什么引起串口中断的主要内容,如果未能解决你的问题,请参考以下文章

STM32L051低功耗STOP模式串口中断唤醒

怎么用C语言中断方式实现串口的读写?

STM32HAL 串口发送(中断方式)

串口中断优先级最高的是

关于Arduino的串口中断

STM32串口之空闲中断