[PIC®/AVR®/dsPIC®产品] 谁能帮忙用PIC16或者PIC18跑一下分数?代码很简单的

[复制链接]
1894|16
 楼主| panxiaoyi 发表于 2021-4-24 21:39 | 显示全部楼层 |阅读模式
我也是刚刚接触PIC18,发现它的运行速度很慢,比新型的国产51单片机还要慢几倍,不知道是不是我的代码有问题,所以请教一下大家。
要求如下:
使用PIC跑下面的 for() 语句,比如 6400 000(6400K) 个时钟(振荡器时钟,或者说是CPU时钟),跑够时间后,然后看看for()语句可以运行多少次
国产新型的51大约可以运行9000次,但是,我发现PIC18才运行1600次左右

  1. unsigned char test(unsigned char dat)
  2. {
  3.     unsigned char yy;
  4.     yy=dat;
  5.     return yy;
  6. }


  7.     while(1)
  8.     {
  9.         for(ii=0; ii<65535; ii++)             //全部语句可以运行8988次
  10.         {
  11.             xx=test(37);                      //注释这条可以运行9580次
  12.             out=xx;
  13.             
  14.             if(xx>47) xx=57; else xx=67;      //注释这条可以运行9998次
  15.             out=xx;
  16.             
  17.             xx<<=1;                           //注释这条可以运行9248次
  18.             out=xx;
  19.             
  20.             xx>>=1;                           //注释这条可以运行9248次
  21.             out=xx;
  22.             
  23.             xx|=1;                            //注释这条可以运行9142次
  24.             out=xx;
  25.             
  26.             xx&=1;                            //注释这条可以运行9142次
  27.             out=xx;
  28.             
  29.             xx=~xx;                            //注释这条可以运行9142次
  30.             out=xx;
  31.             
  32.             xx=xx^1;                           //注释这条可以运行9142次
  33.             out=xx;
  34.             
  35.             xx+=1;                            //注释这条可以运行9090次
  36.             out=xx;
  37.             
  38.             xx-=1;                            //注释这条可以运行9090次
  39.             out=xx;
  40.             
  41.             xx*=3;                            //注释这条可以运行9523次
  42.             out=xx;
  43.             
  44.             xx/=3;                            //注释这条可以运行9523次
  45.             out=xx;
  46.             
  47.             xx%=3;                            //注释这条可以运行9638次
  48.             out=xx;
  49.         }
  50.         while(1);
  51.     }
 楼主| panxiaoyi 发表于 2021-4-24 21:41 | 显示全部楼层
上面的 out 是  #define out LATB
 楼主| panxiaoyi 发表于 2021-4-24 21:43 | 显示全部楼层
这个帖子有详细的说明

https://bbs.21ic.com/icview-1209482-1-1.html
 楼主| panxiaoyi 发表于 2021-4-24 21:44 | 显示全部楼层
每次我都用 out=xx; 只是简单的 IO 口操作,防止编译器优化删除部分代码
lcczg 发表于 2021-4-26 11:34 | 显示全部楼层
我建议直接在循环中加一定数目的NOP,然后翻转IO,然后示波器观测。像上面的代码,不同的编译器编译的效果不同,产生的汇编指令的多寡不同,变量太多了。真要比较的话,还是要看具体的反汇编指令执行数目,加以计算。
 楼主| panxiaoyi 发表于 2021-4-26 13:33 来自手机 | 显示全部楼层
我用的是  MPLAB X ide 4.20 ,xc8-2.32,汇编真的不懂,只是感觉运行的比较慢,所以才来个对比比较的
systemchip 发表于 2021-4-26 14:12 | 显示全部楼层
不要纠结了,你用来作对比的那个增强型51内核的器件是有乘数法指令的.
 楼主| panxiaoyi 发表于 2021-4-26 18:11 来自手机 | 显示全部楼层
@systemchip,你上个贴回复图片,图片说:HC89F0541的 寄存器B 是专门为乘法和除法运算设置的寄存器,用于存放乘法和除法运算的操作数和运算结果, 在不进行乘除运算时,可以作为通用寄存器使用。。请问这句话就是说这个芯片有硬件乘法和硬件除法是吗,汇编我真的不懂喔,但是它在芯片特性这里并没有标注说明,不会是这么低调吧?。我看其它芯片有这个功能的都会特别标注说明的
 楼主| panxiaoyi 发表于 2021-4-26 18:18 来自手机 | 显示全部楼层
还有一个我不明白,标准51是不是没有硬件乘法除法器的,如果没有,那么Keil C51是否会对这些有硬件乘除法的器件进行特别的优化呢?
systemchip 发表于 2021-4-27 09:45 | 显示全部楼层
你看一下数据手册里面的指令集就知道了
 楼主| panxiaoyi 发表于 2021-4-29 01:06 | 显示全部楼层
在百度查到了51的确有乘除法指令的

51单片机乘法指令

这个指令的作用是把累加器A和寄存器B中的8位无符号数相乘,所得到的是16位乘积,这个结果低8位存在累加器A,而高8位存在寄存器B中。如果OV=1,说明乘积大于0FFFFH(65536),否则OV=0,但进位标志位CY总是等于0。

MUL  AB       ;(A)×(B)→(A)和(B) 累加器A中的内容与寄存器B中的内容相乘,结果存在A、B中   

例:(A)=4EH,(B)=5DH,执行指令MUL  AB后,乘积是1C56H,所以在B中放的是1CH,而A中放的则是56H。

51单片机除法指令

这个指令的作用是把累加器A的8位无符号整数除以寄存器B中的8位无符号整数,所得到的商存在累加器A,而余数存在寄存器B中。除法运算总是使OV和进位标志位CY等于0。如果OV=1,表明寄存器B中的内容为00H,那么执行结果为不确定值,表示除法有溢出。

DIV  AB       ;(A)÷(B)→(A)和(B) 累加器A中的内容除以寄存器B中的内容,所得到的商存在累加器A,而余数存在寄存器B中。

例如:13/5,其商是2,余数是3。除了以后,商会放在A中,余数放在B中,CU和OV都是0。如果在做除法前B中的值是00H,也就是除数为0,那么OV=1。
aple0807 发表于 2021-4-29 11:19 | 显示全部楼层
正常。   PIC18指令集本来就比51指令集弱。 在加上51现在都是1T指令,PIC18是4T指令,四五倍差距很正常。
 楼主| panxiaoyi 发表于 2021-4-29 17:04 | 显示全部楼层
在百度查到如下片段

51单片机乘法指令(1条)

这个指令的作用是把累加器A和寄存器B中的8位无符号数相乘,所得到的是16位乘积,这个结果低8位存在累加器A,而高8位存在寄存器B中。如果OV=1,说明乘积大于0FFFFH(65536),否则OV=0,但进位标志位CY总是等于0。

MUL  AB       ;(A)×(B)→(A)和(B) 累加器A中的内容与寄存器B中的内容相乘,结果存在A、B中   

例:(A)=4EH,(B)=5DH,执行指令MUL  AB后,乘积是1C56H,所以在B中放的是1CH,而A中放的则是56H。

51单片机除法指令(1条)有例子

这个指令的作用是把累加器A的8位无符号整数除以寄存器B中的8位无符号整数,所得到的商存在累加器A,而余数存在寄存器B中。除法运算总是使OV和进位标志位CY等于0。如果OV=1,表明寄存器B中的内容为00H,那么执行结果为不确定值,表示除法有溢出。

DIV  AB       ;(A)÷(B)→(A)和(B) 累加器A中的内容除以寄存器B中的内容,所得到的商存在累加器A,而余数存在寄存器B中。

例如:13/5,其商是2,余数是3。除了以后,商会放在A中,余数放在B中,CU和OV都是0。如果在做除法前B中的值是00H,也就是除数为0,那么OV=1。
 楼主| panxiaoyi 发表于 2021-4-29 17:12 | 显示全部楼层
根据实测, 上面的 PIC18 慢,的确是因为除法、求余拖累所致的,乘法倒是不慢
 楼主| panxiaoyi 发表于 2021-4-30 12:06 | 显示全部楼层
AVR 的 ATmega48 使用 CodeVisionAVR V2.05.0
HC89F0541 使用 Keil C51 9.60A
PIC 使用 MPLAB X IDE v4.20 加 xc8 Free V2.32
全部都是默认优化,业余爱好测试,结果如图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
shizaigaole 发表于 2021-5-3 18:34 | 显示全部楼层
其实考虑性能的话,基本上什么pic,51,甚至avr,stm8之类的都不用考虑了,毕竟他们的性能一般都不高,比如pic18只有0.11DMIPS/MHZ。

而现在的cm0,CM3核的arm满天飞,即使要用microchip的产品,考虑性能最起码pic24起步,其实不少pic32价格也不贵,pic32的性能基本上25MHZ能跑77DMIPS
您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

417

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部