发新帖我要提问
12
返回列表
打印
[PIC®/AVR®/dsPIC®产品]

如何启用PIC18的扩展指令集?

[复制链接]
楼主: roalychen
手机看帖
扫描二维码
随时随地手机跟帖
21
我上面的如果有错,估计就是cpu时钟问题,中断和中断时间和中断所消耗的震荡时钟应该是正确的,经过了秒表测试求平均值的

使用特权

评论回复
22
panxiaoyi| | 2021-4-23 12:15 | 只看该作者
AVR比较简单,放假回去我也让ATmega48跑一遍试试,现在手头没有工具

使用特权

评论回复
23
panxiaoyi| | 2021-4-24 10:35 | 只看该作者
代码做了微调,没有使用系统生成的配置字,芯片使用 PIC18F26K83

使用特权

评论回复
24
panxiaoyi| | 2021-4-24 10:36 | 只看该作者
//PIC18F26K83
//配置字关闭了外部振荡器,启用内部64M时钟,其它的默认
//看门狗默认开启,使用内部31K时钟定时2s

//#include "Configuration.h"
#pragma config CONFIG1L=0b00000100            //配置字设置:时钟=内部64M,分频=1,外部振荡器关闭

#include <xc.h>

#include "BIT.h"
#include "DELAY_LONG.h"
#include "FONT0805.h"
#include "MCUIIC.h"
#include "SH1106.h"

#define out LATB

unsigned int ii, nn;
unsigned char xx, aa;

unsigned char test(unsigned char dat)
{
    unsigned char yy;
    yy=dat;
    return yy;
}

void __interrupt(irq(TMR0),high_priority) myTmrIsr(void)       //增强型PIC18有很多个中断向量
{
    nn++;
    LATC1=1;                                  //LED亮
    __asm("CLRWDT");                          //清狗
    TMR0IF=0;                                 //清零中断标记
    OLED_gotoxy(71,3);                        //显示时间
    OLED_show(nn);
    LATC1=0;
    if(aa)                                    //显示:程序在1600K个CPU时钟里运行for()语句的次数
    {
        aa=0;
        OLED_gotoxy(35,3);
        OLED_show(ii);
    }
}

void main(void)
{
    OSCCON1=0b01100000;                       //高4位是时钟选择,本例选择高频内部时钟HFINTOSC,低4位是“后”分配器选择,0000=1分频
    OSCFRQ=8;                                 //高频内部时钟HFINTOSC的频率选择,=8就是64MHz
    WDTCON1=7;                                //看门狗溢出时间=65536/31K=2s,窗口期100%,窗口期就是说什么时候可以清狗,什么时候清狗属于违规
   
    IIC_init();
    OLED_init();
    OLED_clear();
    OLED_gotoxy(11,1);
    OLED_string("PIC18F26K83>SH1106");
    OLED_gotoxy(11,5);
    OLED_string("21IC.COM PANXIAOYI");
   
    TRISC1=0;                                 //输出驱动LED,测试T0计数溢出中断
    TRISC2=0;                                 //输出驱动LED,测试T0输出,LED不会闪烁,不正常
    RC2PPS=0x25;                              //某端口定义为由计数器TMR0计数溢出输出驱动电平翻转

   
    TMR0H=195;

    TMR0IP=1;                                 //高级中断
    TMR0IE=1;                                 //中断允许
    ei();                                     //总中断使能
   
    T0CON1 B6H;                               //Fosc/4=16M时钟
    T0CON1 B3H;                               //预分频8192
    T0CON1 B2H;
    T0CON1 B1L;
    T0CON1 B0H;
    T0CON0 B4L;                               //使用8位模式
    T0CON0 B7H;                               //启动计时器
   
   
    aa=1;
    ii=1;
    nn=0;
    while(1)
    {
        for(ii=0; ii<65535; ii++)             //全部语句可以运行8988次
        {
            xx=test(37);                      //注释这条可以运行9580次
            out=xx;
            
            if(xx>47) xx=57; else xx=67;      //注释这条可以运行9998次
            out=xx;
            
            xx<<=1;                           //注释这条可以运行9248次
            out=xx;
            
            xx>>=1;                           //注释这条可以运行9248次
            out=xx;
            
            xx|=1;                            //注释这条可以运行9142次
            out=xx;
            
            xx&=1;                            //注释这条可以运行9142次
            out=xx;
            
            xx=~xx;                            //注释这条可以运行9142次
            out=xx;
            
            xx=xx^1;                           //注释这条可以运行9142次
            out=xx;
            
            xx+=1;                            //注释这条可以运行9090次
            out=xx;
            
            xx-=1;                            //注释这条可以运行9090次
            out=xx;
            
            xx*=3;                            //注释这条可以运行9523次
            out=xx;
            
            xx/=3;                            //注释这条可以运行9523次
            out=xx;
            
            xx%=3;                            //注释这条可以运行9638次
            out=xx;
        }
        while(1);
    }
}

代码如下:

使用特权

评论回复
25
panxiaoyi| | 2021-4-24 10:45 | 只看该作者
上面的代码中,修改47行的“后”分频,和48行的频率选择,显示器的速度都有不同反应,但是,运行for语句不变,只有1655次
我认为我上面的时钟没有选错,系统时钟就是 64M ,后分频就是 1 ,就是没有分频,看来 PIC 的速度就是这么慢了,1T的51可以运行9000次,PIC只运行了1655次
如果大家看出了哪里有错,也多谢指正


微信图片_20210424104450.jpg (176.31 KB )

微信图片_20210424104450.jpg

使用特权

评论回复
26
panxiaoyi| | 2021-4-24 10:46 | 只看该作者
完整代码如下

PIC18F26K83性能测试.rar

388.43 KB

使用特权

评论回复
27
panxiaoyi| | 2021-4-24 10:53 | 只看该作者
每秒中断次数 = 64M 除以 4分频 ,再除以 8192 分频 ,再除以 195 计数 ,= 10 次/s

使用特权

评论回复
28
systemchip| | 2021-4-25 10:41 | 只看该作者

使用特权

评论回复
29
panxiaoyi| | 2021-4-30 12:10 | 只看该作者
AVR 的 ATmega48 使用 CodeVisionAVR V2.05.0
HC89F0541 使用 Keil C51 9.60A
PIC 使用 MPLAB X IDE v4.20 加 xc8 Free V2.32
全部都是默认优化,业余爱好测试,结果如图




捕获10.PNG (61.33 KB )

捕获10.PNG

使用特权

评论回复
30
慢动作| | 2021-4-30 21:55 | 只看该作者
看看优化之后的。

使用特权

评论回复
31
慢动作| | 2021-4-30 21:58 | 只看该作者
panxiaoyi 发表于 2021-4-23 12:15
AVR比较简单,放假回去我也让ATmega48跑一遍试试,现在手头没有工具

重新做了吗?

使用特权

评论回复
32
panxiaoyi| | 2021-4-30 22:50 | 只看该作者
上面的截图就是结果啊,因为ATmega48使用的是1M时钟,因此结果 159 要 乘以16, 16*159=2544次,就是说如果是16M时钟的话,它的运行结果就是2544次,其它的类推。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则