找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2737|回复: 10
收起左侧

51单片机如何通过串口发送DS18B20数据到电脑并且显示在晶体管上

[复制链接]
ID:964694 发表于 2021-9-7 22:53 | 显示全部楼层 |阅读模式
小白求助,如何通过串口发送DS18B20数据至电脑?
上位机通过C#接收并且处理数据

/*串口初始化,比特率9600*/
void UART_Init()
{
   SM0 = 0;        SM1 = 1;//串口工作方式1,8位UART波特率可变
        TR1 = 1;//启动定时器1
        TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;//设置比特率9600
}

void main()
{                 

        uint i;
                uchar L, M;
        UART_Init(); //串口初始化
        TI = 1;//使用printf()puts()前都应软件置位TI = 1;

        ds_init();//初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x44);//发送温度转换指令
        Delay_Ms(1000);
          while(1)
        {         
                ds_init();//初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x44);//发送温度转换指令
        ds_init();//初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0xbe);//读取DS18B20暂存器值
               L = read_byte();
                M = read_byte();
                i = M;
                x[0]=M;
                x[1]=L;
                i <<= 8;
                i |= L;                                       
                i = i * 0.625  + 0.5;
                Display(i);         //数码管显像
    //此处代码怎么可以设置定时发送
                  SBUF=M;
                while(TI==0);
                        TI=0;
                SBUF=L;
                while(TI==0);
                        TI=0;               
}  
}

回复

使用道具 举报

ID:624769 发表于 2021-9-8 00:33 | 显示全部楼层
你要定时发送, 可以放到定时器中断中去发, 但是不建议在 定时器中断中 while(!TI); 毕竟 9600的波特率 发送一个字节还是蛮久的。可以定时器发掉一个后,置位 busy, 下次进入后 判断busy是否清除,如果清除了 就发下一个,没清除,就先回去,下次再说。   同时开串口 中断, 如果 TI == 1, 清TI 清busy。 这样比较好。
回复

使用道具 举报

ID:964694 发表于 2021-9-8 00:43 | 显示全部楼层
188610329 发表于 2021-9-8 00:33
你要定时发送, 可以放到定时器中断中去发, 但是不建议在 定时器中断中 while(!TI); 毕竟 9600的波特率 发送 ...

能不能一次发送完这两个数据啊,因为是DS18B20的数据,需要定时传到电脑上,思路是怎样呢,我试了几种方法,HEX模式下只能发送一个过去,定时发送是用定时器中断就可以了嘛?
回复

使用道具 举报

ID:624769 发表于 2021-9-8 01:14 | 显示全部楼层
clvlxl 发表于 2021-9-8 00:43
能不能一次发送完这两个数据啊,因为是DS18B20的数据,需要定时传到电脑上,思路是怎样呢,我试了几种方 ...

串口一次只能发送一个字节, 因为SBUF只有一个字节。发完后 TI 置 1 告诉你发送完成。你要连续发,就只能按你写的那样来发送。我不知道你的定时发,是什么定义,通常可以做一个标志比如:Send_Flag
那个你把你的发送代码,依然留在原地,但是,用这个标志包起来:
if(Send_Flag)
{
                  SBUF=M;
                 while(!TI);
                         TI=0;
                 SBUF=L;
                 while(!TI);
                         TI=0
                Send_Flag = 0;
}

然后定时器中断随便你定多少时间,时间到了,就把 Send_Flag = 1;
那么,定时发送的目的就达到了。
回复

使用道具 举报

ID:748788 发表于 2021-9-8 08:24 | 显示全部楼层
并且显示在晶体管上——你这是啥用意?
回复

使用道具 举报

ID:584195 发表于 2021-9-8 08:37 | 显示全部楼层
网上有很多示例的。现在比皎流行的是用python写了,C#。。。
回复

使用道具 举报

ID:964694 发表于 2021-9-8 10:08 | 显示全部楼层
wwh2382 发表于 2021-9-8 08:24
并且显示在晶体管上——你这是啥用意?

使用晶体管显示出温度
回复

使用道具 举报

ID:123289 发表于 2021-9-9 15:09 | 显示全部楼层
1、学会【51单片机如何通过串口收发据】
2、学会【DS18B20数据采集】
3、至少学会一种【电脑工具软件,与外设进行串口数据交换,及数据显示】,如EXCEL、VB、C++、……
4、学会【单片机控制LED显示】
这样就可以达成目的了。
回复

使用道具 举报

ID:401564 发表于 2021-9-9 18:04 | 显示全部楼层
是我对晶体管有什么误解吗?还是叫法不一样,我觉得晶体管不应该是8050之类的三极管吗?
8051一次只能发送一个字节
好像串口协议就是只发送一个字节而已的呀,多出来的位都是什么停止位,校验位之类的
硬件不同的,只有缓冲器大小不同而已的吧
回复

使用道具 举报

ID:213173 发表于 2021-9-10 07:05 | 显示全部楼层
clvlxl 发表于 2021-9-8 00:43
能不能一次发送完这两个数据啊,因为是DS18B20的数据,需要定时传到电脑上,思路是怎样呢,我试了几种方 ...

/*串口初始化,比特率9600*/
void UART_Init()
{
        SM0 = 0;
        SM1 = 1;//串口工作方式1,8位UART波特率可变
        TR1 = 1;//启动定时器1
        TMOD |= 0x20;//定时器1,工作模式2 8位自动重装
        TH1 = 0xfd;
        TL1 = 0xfd;//设置比特率9600
}
void Timer0Init()                //50毫秒@11.0592MHz
{
        TMOD &= 0xf0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x00;                //设置定时初值
        TH0 = 0x4C;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
}

void main()
{                 
        uint i,j;
        uchar L, M;
        UART_Init(); //串口初始化
        TI = 1;//使用printf()puts()前都应软件置位TI = 1;       
        ds_init();//初始化DS18B20
        write_byte(0xcc);//发送跳跃ROM指令
        write_byte(0x44);//发送温度转换指令
        Delay_Ms(1000);
        Timer0Init(); //定时器初始化
        while(1)
        {         
                ds_init();//初始化DS18B20
                write_byte(0xcc);//发送跳跃ROM指令
                write_byte(0x44);//发送温度转换指令
                ds_init();//初始化DS18B20
                write_byte(0xcc);//发送跳跃ROM指令
                write_byte(0xbe);//读取DS18B20暂存器值
                L = read_byte();
                M = read_byte();
                i = M;
                x[0]=M;
                x[1]=L;
                i <<= 8;
                i |= L;
                i = i * 0.625  + 0.5;
                Display(i);         //数码管显像
                if(TF0)
                {
                        TF0 = 0;
                        j++;
                        if(j>=600)//30秒定时发送
                        {
                                j=0;
                                SBUF=(M<<4)|(L>>4);//保留整数,舍弃小数。
                                while(!TI);
                                TI=0;  
                        }
                }
        }  
}
回复

使用道具 举报

ID:964694 发表于 2021-9-12 09:46 | 显示全部楼层
wulin 发表于 2021-9-10 07:05
/*串口初始化,比特率9600*/
void UART_Init()
{

感谢回复
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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