打印
[PIC®/AVR®/dsPIC®产品]

PIC16(L)F1826——时钟使用

[复制链接]
7616|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 JackTang1994 于 2021-9-26 14:03 编辑

硬件平台:PIC16(L)F1826、MPLAB ICD4调试器
软件平台:MPLAB X IDE V5.5、MPLAB Code Configurator V4
PIC16(L)F1826数据手册:https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/DataSheets/41391D.pd

示例工程: OSC_Switch.X.zip (134.36 KB)

说明这里我们只介绍内部时钟源内的切换,而如果需要设置时钟模式则设置配置字1中的FOSC<2:0>位。

芯片手册阅读
阅读手册第5章:5.0OSCILLATOR MODULE (WITH FAIL-SAFE CLOCK MONITOR)

MCU时钟框图
从框图中我们可以知道CPU时钟来源有3个:外部晶振、Timer1、内部时钟


内部时钟源(INTERNAL CLOCK SOURCES)HFINTOSC:内部高速时钟,有31.25 kHz、125 kHz、250 kHz、500 kHz、1 MHz、2 MHz、4 MHz、8 MHz 或 32 MHz、16MHz频率
MFINTOSC:内部中速时钟,有31.25 kHz、62.5 kHz、125 kHz、250 kHz、500 kHz频率
LFINTOSC:内部低速时钟,只有31 kHz频率

内部时钟源切换
内部时钟源切换就是HFINTOSC、MFINTOSC、LFINTOSC之间切换,不同时钟源之间切换时,新的时钟可能还处理关闭状态所以在设置时钟切换时有一个延时。我们可以通过OSCSTAT寄存器判断时钟是否已经切换完成。


内部时钟源频率及设置


时钟切换时序
在时钟没有切换完毕时,MCU一直使用以前的时钟频率,当完成切换时MCU系统频率就会切换成设置的值.所以这里的Start-up time不是MCU不运行代码的空闲等待时间而是时钟切换电路反应时间.所以我们不必加NOP延时,而是直接判断OSCSTAT的Ready标志位。


时钟切换成功标志
通过读取OSCSTAT寄存器中的HFIOFR、MFIOFR、LFIOFR即可知道当前切换到HFINTOSC、MFINTOSC、LFINTOSC内部时钟源是否已经准备好了。

MCC配置
MCC的时钟配置,按照下图设置即可


代码编写
在main.c文件中添加以下代码:定义时钟频率设置值,并编写了一个时钟配置函数通过判断OSCSTAT寄存器中相应的时钟准备位来判断切换后时钟是否已经准备好了,从而决定是否需要继续操作相关外设
typedef enum internal_CLK 
{
    OSC_31K_LF = 0x00, OSC_31K25_MF = 0x02, OSC_31K25_HF = 0x03, \
    OSC_62K5_MF = 0x04, OSC_125K_MF = 0x05, OSC_250K_MF = 0x06, \
    OSC_500K_MF = 0x07, OSC_125K_HF = 0x08, OSC_250K_HF = 0x09, \
    OSC_500K_HF = 0x0A, OSC_1M_HF = 0x0B, OSC_2M_HF = 0x0C, \
    OSC_4M_HF = 0x0D, OSC_8M_HF = 0x0E, OSC_16M_HF = 0x0F
}INT_CLK_FREQ_TypeDef;

void Set_SysInternal_Freq(INT_CLK_FREQ_TypeDef clock_freq)
{
    OSCCONbits.SCS = 0x02; // internal oscillator
    OSCCONbits.IRCF = clock_freq; // start-up clock
   
    switch(clock_freq)
    {
        case OSC_31K_LF:

            
            while(OSCSTATbits.LFIOFR != 0x01);
            break;
            
        case OSC_31K25_MF:
        case OSC_62K5_MF:
        case OSC_125K_MF:
        case OSC_250K_MF:
        case OSC_500K_MF:
            while(OSCSTATbits.MFIOFR != 0x01);
            break;

        case OSC_31K25_HF:
        case OSC_125K_HF:
        case OSC_250K_HF:
        case OSC_500K_HF:
        case OSC_1M_HF:
        case OSC_2M_HF:
        case OSC_4M_HF:
        case OSC_8M_HF:
        case OSC_16M_HF:   
            while(OSCSTATbits.HFIOFR != 0x01);
            break;
            
        default:
            break;
    }
}
由于MPLAB X IDE单纯的软件仿真无法仿真时钟,所以这一次我们使用调试器来仿真并观察现象。软件仿真时的程序运行时钟频率是预先设置好的,无法后期修改。如下图所示:

注:关于时钟相关的仿真,无法使用MPLAB X IDE的软件仿真来观察结果。

工程设置
在工程设置中选择调试器,然后在调试器设置窗口选择使用调试器供电.
注:这个需要根据不同调试器来进行设置,我这里使用的是ICD4调试器


将程序停止在函数处,此时软件使用默认的时钟500KHZ


通过将CLKOUT引脚接示波器上观察波形就是125KHZ(Fosc / 4).这个是CLKOUT输出的时钟为系统时钟的4分频

从手册中我们也可以知道,MCU复位后的时钟频率



运行完SYSTEM_Initialize()函数
在Set_SysInternal_Freq(OSC_31K25_HF);语句处打一个断点,此时程序只是运行完了SYSTEM_Initialize()函数,但是还没有运行Set_SysInternal_Freq(OSC_31K25_HF);语句,CLKOUT输出波形为MCC软件自动生成的代码中设置的系统频率。

此时频率约1.75MHZ。不知道为啥这个时钟频率不是系统时钟的1/4,即16/4 = 4MHZ。


运行完Set_SysInternal_Freq()函数。

此时系统时钟已经是我们设置的31.25KHZ时钟源为HFINTOSC






时钟切换配置.PNG (265.95 KB )

时钟切换配置.PNG

使用特权

评论回复
沙发
wziyi| | 2021-10-4 20:46 | 只看该作者
内部时钟源只有三个the 16 MHz High-Frequency
Internal Oscillator (HFINTOSC), 500 kHz (MFINTOSC)
and the 31 kHz Low-Frequency Internal Oscillator
(LFINTOSC)。不能把时钟树上的其他频率混在一块

使用特权

评论回复
板凳
wziyi| | 2021-10-4 20:48 | 只看该作者
下次可以搞点内部与外部时钟的来回切换。

使用特权

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

本版积分规则

29

主题

62

帖子

0

粉丝