【求助】看似简单的串口程序搞了一下午,请帮忙看看吧

2020-01-30 14:02发布

本帖最后由 tim4146 于 2013-3-21 17:57 编辑

硬件连接:笔记本端是FT232,出来的TTL电平,将RXD,TXD交叉连接到单片机的TXD,RXD,杜邦线连的。晶振12M,调试助手设置的是9600的波特率,对应程序重装初值0XFD.
程序如下:

#include <reg51.h>
#include <intrins.h>
sbit P33=P3^3;
unsigned char tmp;
void send_char(unsigned char txd);

void delay20ms(void)   //误差 0us
{
    unsigned char a,b;
    for(b=215;b>0;b--)
        for(a=45;a>0;a--);
    _nop_();  //if Keil,require use intrins.h
    _nop_();  //if Keil,require use intrins.h
}
main()
{        unsigned char TEMP=0X00;  //临时
        TMOD = 0x20;                        // 定时器1工作于8位自动重载模式, 用于产生波特率
        TH1 = 0xFD;                                // 波特率4800
        TL1 = 0xFD;
       
        SCON = 0x50;                        // 设定串行口工作方式
        PCON &= 0xef;                        // 波特率不倍增
               
        TR1 = 1;                                // 启动定时器1
        IE = 0x00;                                // 禁止任何中断
        //P0=0X00;
        while(1)
        {
       
        if(RI)                                                // 是否有数据到来
                {
                        RI = 0;                                          //清零
                        tmp = SBUF;                                // 暂存接收到的数据
                send_char(tmp);                        // 回传接收到的数据
                }
       
       if(!P33)           //开发板上有个按钮,扫描按钮是否按下
                {
                 delay20ms();          //延时去抖动
                 while(!P33);         //松开时执行下一步
                 P0=~P0;                 //取反,使LED灯亮暗交替变换 这步能执行。
                 send_char(TEMP);  //发送一个0X00回去,发现收到的是乱码
                }
               
        }
}
void send_char(unsigned char txd)
// 传送一个字符
{
        SBUF = txd;
        while(!TI);                                // 等特数据传送
        TI = 0;                                        // 清除数据传送标志
}

实现目标:1、在串口调试助手中发送一个字节的字符,单片机收到之后将其发送回去让电脑的串口收到;
               2、检测一个按钮,在按钮松开时改变P0的电平达到LED亮暗交替的效果,并且随后给上位机发送0X00。

悲催的现实:调试助手发送一个字节之后发现单片机那边没反应;按钮按下松开之后LED灯正常切换状态,但是调试助手收到的一个字节的 内容是乱码(十六进制显示不是我预先设定的0x00)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
zjsxwc
1楼-- · 2020-01-30 19:05
楼主你没贴你单片机具体晶振是多少。。。
tim4146
2楼-- · 2020-01-30 22:01
zjsxwc 发表于 2013-3-21 17:50
楼主你没贴你单片机具体晶振是多少。。。

晶振12M,调试助手设置的是9600的波特率,对应程序重装初值0XFD.
刚刚吃过晚饭,还的继续弄出来,本来是调试蓝牙模块的,发现串口直接相连都调不出来...哎
zjsxwc
3楼-- · 2020-01-31 03:58
 精彩回答 2  元偷偷看……
binaimei2007
4楼-- · 2020-01-31 04:12
12M晶振,9600的误差太大,根本无法通信
tim4146
5楼-- · 2020-01-31 06:38
zjsxwc 发表于 2013-3-21 18:04
12M晶振用9600Bps误差很大的,一般用4800Bps,保险点用更低的波特率试试
11.0592MHz的晶振的才能用9600Bp ...

查表得知12M和11.0592M晶振相对9600波特率的初值都是FDH,所以直接换了晶振再试的,发现还是有问题,改成4800波特率下(TH1 = 0xF9;        TL1 = 0xF9;),还是乱了。兄台,你手上有开发板吗,直接烧进去帮我看看吧
tim4146
6楼-- · 2020-01-31 07:07
binaimei2007 发表于 2013-3-21 18:12
12M晶振,9600的误差太大,根本无法通信

为了做纯粹的通信,也为了降低波特率,我采用1200波特率,定时器初值E6。
程序:
#include <reg51.h>
#include <intrins.h>
void send_char(unsigned char txd);
void delay500ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=23;c>0;c--)
        for(b=152;b>0;b--)
            for(a=70;a>0;a--);
}
main()
{        unsigned char TEMP=0XAA;  //临时
        TMOD = 0x20;                        // 定时器1工作于8位自动重载模式, 用于产生波特率
        TH1 = 0xe6;                                // 波特率1200
        TL1 = 0xe6;
        SCON = 0x50;                        // 设定串行口工作方式
        PCON &= 0xef;                        // 波特率不倍增       
        TR1 = 1;                                // 启动定时器1
        IE = 0x00;                                // 禁止任何中断
        while(1)
        {
                 delay500ms();
             send_char(TEMP);          //这步没效果,不懂               
        }
}
void send_char(unsigned char txd)
// 传送一个字符
{
        SBUF = txd;
        while(!TI);                                // 等特数据传送
        TI = 0;                                        // 清除数据传送标志
}

结果:
按理是500ms发送一次,实际收到的频率发现有丢失的现象,收到的内容不是预先设定的值...

一周热门 更多>