矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2308|回复: 23

请教:以下三种单片机传输8字节数的方法,有何区别??

[复制链接]
     
发表于 2022-6-9 16:26:36 | 显示全部楼层 |阅读模式
void Sendbyte (unsigned char dat)         //送数据,高位在前
{
         unsigned char i;
         _nop_();
         for (i=0;i<8;i++)
        {
        if(dat&0x80)                                  //方法1
            DIN=1;
        else
            DIN=0;
        dat<<=1;


              DIN=(bit)(dat&0x80);          //方法2
              dat<<=1;


              dat<<=1;
              DIN=CY;                                  //方法3

        CLK=0;
        _nop_();
        CLK=1;
    }
}

补充内容 (2022-6-9 20:21):
不是字节,是位
     
发表于 2022-6-9 16:58:45 | 显示全部楼层
本帖最后由 ChrisLove 于 2022-6-9 17:05 编辑

1.最普通的,每一次移位只取最高位的值判断是1还是0,然后发出去,这个在任何处理器上都能做.
2.原理上和1一样,但利用了keil的bit关键字,编译器直接帮你把最高位移出的结果转成了0或者1,只能在KEIL C51编译器上使用。
3.利用了8051里面的进位标志CY,这个是8051 CPU里面的硬件标志,左移的时候如果最高位是1那就等于进位了,CY也置1,于是可以把这个位直接赋值给IO。这种方法只能在8051上用,别的CPU不一定能得到相同的结果。

从程序耗费的开销考虑,3是最低的,因为靠硬件完成了一部分判断,1和2不好说,因为我不清楚2具体是怎么实现的,得看汇编的结果

评分

2

查看全部评分

回复 支持 1 反对 0

使用道具 举报

     
 楼主| 发表于 2022-6-9 17:04:19 | 显示全部楼层
ChrisLove 发表于 2022-6-9 16:58
1.最普通的,就是循环移位,每一次移位只取最高位的值判断是1还是0,然后发出去,这个在任何处理器上都能做.
2 ...

谢谢,那就多用方法3。
回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 17:32:48 | 显示全部楼层
本帖最后由 w6955 于 2022-6-9 17:34 编辑
乙猪 发表于 2022-6-9 17:04
谢谢,那就多用方法3。


用1为好,最通用的最好。如果SPI 232口可以使用最简单。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 17:35:08 | 显示全部楼层
w6955 发表于 2022-6-9 17:32
用1为好,最通用的最好。

其实也不要紧,把发送这部分单独做一个函数出来,移植到别的处理器上的时候改一下这个函数就行了。这种移位-判断-赋值的操作还是比较浪费时间的
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-9 17:59:20 来自手机 | 显示全部楼层
大家继续讨论~
回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 18:38:22 | 显示全部楼层
ChrisLove 发表于 2022-6-9 17:35
其实也不要紧,把发送这部分单独做一个函数出来,移植到别的处理器上的时候改一下这个函数就行了。这种移 ...

通讯就不是快的事,所以简单可靠最好,越标准的越好。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 19:54:22 | 显示全部楼层
见过这种方法,
static unsigned char BH[] ={128,64,32,16,8,4,2,1};//高位在前
//static unsigned char BL[] ={1,2,4,8,16,32,64,128};//低位在前

void Sendbyte (unsigned char dat)         //送数据,高位在前
{
         unsigned char i;
         _nop_();
         for (i=0;i<8;i++)
        {
        DIN = (bit)(dat&BH[i]); //方法4
        //DIN = (bit)(dat&BL[i]); //方法4
        CLK=0;
        _nop_();
        CLK=1;
    }
}

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 20:13:44 | 显示全部楼层
本帖最后由 ssffzz1 于 2022-6-9 20:14 编辑

8字节,应该是8bit吧!

衡量一个算法好坏, 1)性能为上.2)耗资源其次.3)复杂程度最次.

以2 3为好. 1 2思路无本质区别,但1更麻烦,分支不是好东西.

8楼虽好,但浪费一点空间.

性能3最高,但不是所有CPU通用,移植不好.  以  2  胜出.

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 20:15:27 | 显示全部楼层
第一种方法,
if(dat&0x80)                                  //方法1
    DIN=1;
else
    DIN=0;
有一种变体写法:
DIN = !!(dat&0x80);
只是不知移植性如何,gcc和vc是可以的

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 20:18:17 | 显示全部楼层
for( int i=0;i<8;++i){
  din = (dat << i) &0x80;  或 din = (dat >> i) & 0x01 ;


一句即可. 我没测试,大致这个思路即可,不需要那么麻烦.
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-9 20:20:23 来自手机 | 显示全部楼层
ssffzz1 发表于 2022-6-9 20:13
8字节,应该是8bit吧!

衡量一个算法好坏, 1)性能为上.2)耗资源其次.3)复杂程度最次.

你说的对。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-9 20:25:00 来自手机 | 显示全部楼层
ssffzz1 发表于 2022-6-9 20:18
for( int i=0;i i) & 0x01 ;



你这个应该也可行,最终生成的代码量是不是会更少?今晚试试。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2022-6-9 20:28:14 来自手机 | 显示全部楼层
w6955 发表于 2022-6-9 17:32
用1为好,最通用的最好。如果SPI 232口可以使用最简单。

用1容易理解,但感觉有点脱裤子放屁。
回复 支持 反对

使用道具 举报

     
发表于 2022-6-9 20:43:13 | 显示全部楼层
ssffzz1 发表于 2022-6-9 20:18
for( int i=0;i i) & 0x01 ;

这个写法是错的,没有转为bit,
需要用(bit)//C51 或 !!转为bit
放在一句的思路是对的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-5-15 20:07

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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