找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2403|回复: 14
打印 上一主题 下一主题
收起左侧

一个简单的单片机串口发送程序问题

  [复制链接]
跳转到指定楼层
楼主
ID:825883 发表于 2021-3-16 07:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请教一个简单的串口发送问题,无关的语句没有写。
unsigned char i;
unsigned char a[9]={1,2,3,4,5,6,7,8,9};
SCON=0X40;
TMOD=0X20;
TH1=0xfd;//@11.0592MHz,波特率9600
TL1=0xfd;
delay();
TR1=1;//启动发送
for(i=0;i<9;i++)
{         SBUF=a[ i][ i];
          while(TI==0)//开始检测TI是否为零,表示未完成发送,等待,直到为1,跳出while循环
          ;//这2行抄教材的,感觉不太对,因为没有发送完成时,TI也为0
        TI=0;       if(i==8)
         TR1=0;
}

问题1:第一次循环,i=0,将数组的第一个元素赋值给SBUF,开始发送,然后等待发送完成,i++,进行第二次for循环。最后一次for循环,关闭计时器停止发送,整个程序作用是发送一遍01~09给计算机串口助手。现在是不停的发送01~09,i==8的语句不起作用,请问是为什么???
问题2:SBUF未赋值前内容未定,是否应该先赋值,再启动定时器,还是像上述程序一样先启动后赋值也可以?


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:18297 发表于 2021-3-16 09:05 | 只看该作者
你这个需要完整的程序,上传以下,我们大家可以给你分析。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:390416 发表于 2021-3-16 09:27 | 只看该作者
串口1打印程序 可以打印3个十六位的变量 波特率9600 http://www.51hei.com/bbs/dpj-201660-1.html
可以用这个贴子的代码,
回复

使用道具 举报

地板
ID:390416 发表于 2021-3-16 09:27 | 只看该作者
还可以用这个贴子的代码,需要发送的信息存入数组就行
串口发送 不需要while死等 串口接收执行软件复位 http://www.51hei.com/bbs/dpj-200927-1.html
回复

使用道具 举报

5#
ID:892488 发表于 2021-3-16 10:27 | 只看该作者
你看看是不是程序一直在重启启动

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

6#
ID:160197 发表于 2021-3-16 10:52 | 只看该作者
TI = 0;
SBUF = a[i];
while(!TI);
我知道这么写,就只发一次

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

7#
ID:693038 发表于 2021-3-16 11:00 | 只看该作者
首先a是数组首地址,不是元素元素应该是a[i],第二for里面i的值是从0-8所以当你判断i==8的时候其实所有的东西都已经执行完了,第三初始化完后赋值给SBUF就会开始发送数据了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

8#
ID:881998 发表于 2021-3-16 14:46 | 只看该作者
没有数据缓冲吧!
回复

使用道具 举报

9#
ID:340765 发表于 2021-3-16 15:39 | 只看该作者
#include "reg52.h"

typedef unsigned int u16;
typedef unsigned char u8;

u16 i,j;

void Usartinit()
{
        TMOD = 0x20;//9600=(2÷32)×((12M/12)/(256-TH1))    1M=10E6
        TH1 = 0xf3;
        TL1 = 0xf3;
        PCON = 0x80;
        SCON = 0x50;
        EA = 1;
        ES = 1;
        TR1 = 1;
}

void main()
{
        Usartinit();
        while(1)
        {
                if(j == 1)
                {
                        ES = 0;
                        j = 0;
                        SBUF = i;
                        while(!TI);
                        TI = 0;
                        ES = 1;                 
                       
                }
        }
}

void Sart() interrupt 4
{
        RI = 0;
        P0 = SBUF;
        i = SBUF;
        j = 1;
}
回复

使用道具 举报

10#
ID:123289 发表于 2021-3-16 15:56 | 只看该作者
你要知道串口在硬件上就是一个移位寄存器!
1、移位寄存器要工作必须有CLK才能移位。这个CLK可以从几个地方获取,手册上有说明,你要看书。
你这里的CLK取自于:T1定时器的输出。而起动T1的命令是TR1=1。
2、移位需要一个起动命令,当你向SBUF中送数时,起动命令就下达了。
了解以上两点你就明白是先做TR1=1,还是先做SBUF=N了。
回复

使用道具 举报

11#
ID:422684 发表于 2021-3-16 15:58 | 只看该作者
先用例程测试。
回复

使用道具 举报

12#
ID:123289 发表于 2021-3-16 16:05 | 只看该作者
当I=8时,你关闭了TR1,这样移位寄存器(串口)就无法移位了。理论上串口也就无法工作了。
FOR语句执行完之后,TR1=0了。
但是,程序再回头时,TR1又被你打开了,就是FOR语句前的[TR1=1;//启动发送],当然如果你的程序不回头不(大循环)也就不会再发送了。
你调试看看,在何处TR1又被置1了。
回复

使用道具 举报

13#
ID:814525 发表于 2021-3-16 16:31 | 只看该作者
a[9]和a[i][i]不是一个概念,a[9]是一维数组,a[i][i]是二维数组。所以正确调用为SBUF = a[i];
回复

使用道具 举报

14#
ID:743654 发表于 2021-3-17 08:52 | 只看该作者
要看主函数,串口中断是否一直打开,或者有死循环。
回复

使用道具 举报

15#
ID:304608 发表于 2021-3-18 11:22 | 只看该作者
SBUF=a[ i][ i];  此处有问题,a不能当二维数组使用(你竟然可以编译通过,诡异。。)
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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