找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6566|回复: 22
收起左侧

单片机串口初始化时TI为什么要置1?

  [复制链接]
回帖奖励 5 黑币 回复本帖可获得 5 黑币奖励! 每人限 1 次(中奖概率 70%)
ID:716794 发表于 2020-4-4 22:31 | 显示全部楼层 |阅读模式
具体代码如上,为什么在串口初始化函数里,TI要被置为1呢?还有,在Uart_SendB函数里,为什么要开头清零一次TI,末尾再清零一次TI?

单片机源程序如下:
  1. #include <stc15f2k60s2.h>
  2. #include <absacc.h>
  3. #include <intrins.h>
  4. #include <stdio.h>
  5. void UartInit(void);//串口初始化函数。
  6. void Uart_SendB(unsigned char us);//串口单个字节发送函数。
  7. void main(void)
  8. {
  9.         XBYTE[0xA000]=0;
  10.         UartInit();
  11.         EA=1;
  12.         while(1)
  13.         {
  14.                 Uart_SendB('a');
  15.         }
  16. }
  17. void UartInit(void)                //9600bps@12.000MHz
  18. {
  19.         SCON = 0x50;                //8位数据,可变波特率
  20.         AUXR &= 0xBF;                //定时器1时钟为Fosc/12,即12T
  21.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  22.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  23.         TL1 = 0xE6;                //设定定时初值
  24.         TH1 = 0xFF;                //设定定时初值
  25.         ET1 = 0;                //禁止定时器1中断
  26.         TR1 = 1;                //启动定时器1
  27.         TI=1;                                
  28.         ES=1;                                //开启串口中断。
  29. }
  30. void Uart_SendB(unsigned char us)
  31. {
  32.         TI=0
  33.         SBUF=us;
  34.         while(TI==0);//等待发送结束。
  35.         TI=0;
  36. }
复制代码


回复

使用道具 举报

ID:213173 发表于 2020-4-5 06:25 | 显示全部楼层
27、32行多余。TI为串口发送完成中断请求标志,由硬件置1,软件清0。只有在特殊使用串口情况才会在初始化时置TI为1。通常来讲,如果想一次发送多个数据的时候,就需要把第一个字节写入SBUF,然后再等待发送中断,再在后续中断中在发送剩余的数据,但是数据发送过程就被拆分到了两个地方——主循环内和中断服务函数内,无疑就使得程序结构变得零散了。这个时候,为了使程序结构尽量紧凑,在启动发送的时候,不是向SBUF中写入第一个待发的字节,而是直接让TI=1,注意,这时候会马上进入串口中断,因为中断标志位置1了,但是串口线上并没有发送任何数据,于是,我们所有的数据发送都可以在中断中进行,而不用再分为两部分了。
回复

使用道具 举报

ID:123289 发表于 2020-4-5 12:27 | 显示全部楼层
楼主能不能说说TI是干什么用的呢?
回复

使用道具 举报

ID:722839 发表于 2020-4-5 15:17 | 显示全部楼层
中断请求
回复

使用道具 举报

ID:716794 发表于 2020-4-5 15:58 | 显示全部楼层
yzwzfyz 发表于 2020-4-5 12:27
楼主能不能说说TI是干什么用的呢?

发送中断标志位,发送完毕后,该位硬件置一,但是需要软件清零,这个我还是知道的,就是不懂它为什么要初始化置1,然后清零两次,我觉得只要留一个清零语句就可以了。
回复

使用道具 举报

ID:716794 发表于 2020-4-5 16:00 | 显示全部楼层
wulin 发表于 2020-4-5 06:25
27、32行多余。TI为串口发送完成中断请求标志,由硬件置1,软件清0。只有在特殊使用串口情况才会在初始化时 ...

那我发的这个程序是属于特殊情况吗?如果不是,那需要将T1初始化为1的特殊情况是怎样的?方便举个例子吗?
不是很懂,麻烦了。
回复

使用道具 举报

ID:722903 发表于 2020-4-5 16:12 | 显示全部楼层
TI为串口发送完成中断请求标志,由硬件置1,软件清0.
发送前先清零,等待发送完成后硬件置1
回复

使用道具 举报

ID:213173 发表于 2020-4-5 16:20 | 显示全部楼层
程鹏 发表于 2020-4-5 16:00
那我发的这个程序是属于特殊情况吗?如果不是,那需要将T1初始化为1的特殊情况是怎样的?方便举个例子吗 ...

参阅此链接,C语言指向数组元素的指针
https://www.sohu.com/a/122492626_119709
回复

使用道具 举报

ID:716794 发表于 2020-4-5 22:43 | 显示全部楼层
wulin 发表于 2020-4-5 16:20
参阅此链接,C语言指向数组元素的指针
https://www.sohu.com/a/122492626_119709

了解了,多谢
回复

使用道具 举报

ID:716794 发表于 2020-4-5 22:44 | 显示全部楼层

谢谢回答,但是我的问题不是这个
回复

使用道具 举报

ID:716794 发表于 2020-4-5 22:45 | 显示全部楼层
fishen 发表于 2020-4-5 16:12
TI为串口发送完成中断请求标志,由硬件置1,软件清0.
发送前先清零,等待发送完成后硬件置1

多谢回答,但是我的问题不是这个。
回复

使用道具 举报

ID:123289 发表于 2020-4-11 11:51 | 显示全部楼层
你的想法是对的,我很赞同!
回复

使用道具 举报

ID:716794 发表于 2020-4-12 12:36 | 显示全部楼层
yzwzfyz 发表于 2020-4-11 11:51
你的想法是对的,我很赞同!

好吧,多谢。
回复

使用道具 举报

ID:830954 发表于 2021-2-2 22:34 | 显示全部楼层
这个串口初始化配置可以移植到STC8上吗?
回复

使用道具 举报

ID:235954 发表于 2021-2-3 08:04 | 显示全部楼层
TI为串口发送完成中断请求标志,由硬件置1,软件清0. 发送前先清零,等待发送完成后硬件置1
回复

使用道具 举报

ID:600405 发表于 2021-9-14 19:37 | 显示全部楼层
初始化TI被置1,为多字节发送时实现“发了不管”,利用等待TI标志出现的时间干点事情。
回复

使用道具 举报

ID:964308 发表于 2021-9-14 21:00 来自手机 | 显示全部楼层
那个是一个发送中断标志,1代表发生完了,由硬件置1,需要软件置0,第一个置0我觉得可以省略
回复

使用道具 举报

ID:964308 发表于 2021-9-16 08:14 | 显示全部楼层
不应该啊,TI是串口中断标志位,是用来标志有没有发送完成的,一般都是由硬件置1,软件置0
回复

使用道具 举报

ID:514901 发表于 2021-9-17 09:20 | 显示全部楼层
TI在串口初始化时置1,一般是为了使用printf函数。一般情况下不置1
回复

使用道具 举报

ID:959346 发表于 2021-9-17 10:17 | 显示全部楼层
程鹏 发表于 2020-4-5 16:00
那我发的这个程序是属于特殊情况吗?如果不是,那需要将T1初始化为1的特殊情况是怎样的?方便举个例子吗 ...

如果不开发送中断,要发送字符串时,通过判断TI为1来发送下一位。所以在开始时置1,表示可以发送下一位。
回复

使用道具 举报

ID:419909 发表于 2021-9-17 10:19 | 显示全部楼层
还有一个原因为是如果调用printf函数时。那个TI一定要置1.不然发不了。
回复

使用道具 举报

ID:959346 发表于 2021-9-17 17:31 | 显示全部楼层
wfqxgw 发表于 2021-9-17 10:19
还有一个原因为是如果调用printf函数时。那个TI一定要置1.不然发不了。

那你这个printf函数应该就是根据TI为1判断一个字节发送完成了,可以开始发送下一个字节的数据了。
回复

使用道具 举报

ID:624769 发表于 2021-9-17 18:22 | 显示全部楼层
串口初始化程序中 TI = 1; 一般是用来针对 不开 串口中断,对程序优化的操作。

大多不开串口中断的串口发送函数,都是如下的写法:
SBUF = xxxx;
while(!TI);
TI = 0;

如上这样的写法,会造成让串口发送数据后,傻等串口传输完成,才会继续其他其他操作,那么如果初始化时TI = 1; 就可以如下写发送函数:
while(!TI);
TI = 0;
SBUF = xxxxxx;

这样写的好处是: 往SBUF 里面放了数据,就能继续做别的事情,只在发送前判断上一次发送有没有完成,在非连续数据传送时,有非常高的效率。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表