找回密码
 立即注册
查看: 1034|回复: 12

STC8H1K08T外部晶振和PLL144M问题

[复制链接]
  • TA的每日心情
    开心
    2024-4-15 13:14
  • 签到天数: 1 天

    [LV.1]初来乍到

    11

    主题

    43

    回帖

    220

    积分

    中级会员

    积分
    220
    发表于 2023-10-2 13:39:08 | 显示全部楼层 |阅读模式
    本帖最后由 firefly2k 于 2023-10-2 13:46 编辑

    我使用的芯片是STC8H1K08T-Beta ( 固件版本号: 7.2.1U),使用外部晶振和PLL 144M有问题

    使用内部IRC 24M(STC8H1K08T-Beta内部IRC不可调好像只能是24M),可以正常运行(uart和PWM时钟源都是用的内部24M)。我外接12M晶振,测量晶振已经起振,我下面代码想要实现主时钟24M,PLL 144M给PWM用。下面代码初始化后,uart波特率只有之前的1/6,PWM输出也只是之前的1/6(与144M的预期差的更远)。

    我不知道是STC8H1K08T-Beta不支持还是我的软件初始化有问题,请指正
    晶振初始化代码如下:

            P_SW2 = 0x80;
            XOSCCR = 0xC0;                //启动外部晶振
            while (!(XOSCCR & 1));        //等待时钟稳定
            CLKDIV = 3;                       //PLL/2/3=24M MCLK/3
            CLKSEL = 0xC5;                  //外部高速时钟,144M,PLL/2 CKMS=1;HSIOCK=1 MCK2SE=01 PLL/2;MCKSEL=01 外部晶振
            PLLCR        = 0x80;             //ENCKM=1 PLL;PCKI=00 12M
            HSCLKDIV = 0;



    回复 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 14:18:21 | 显示全部楼层
    1, 你节后申请 [免费+包邮送]的 STC8H1K08T-33I-TSSOP20
    2, 你外部挂 32768晶振, 2个外挂电容 15pF
    ===用外部 32768 自动校准内部时钟到
          【11.0592MHz, 12MHz】
          【22.1184MHz, 24MHz
          【30MHz, 33.1776MHz

    截图202310021421344540.jpg

    http://www.stcmcudata.com/STC8F-DATASHEET/STC8H.pdf


    截图202310021422546845.jpg

    利用外部 32768 RTC 晶振时钟,自动校准内部高速IRC时钟,STC8H数据手册 内容 - 触摸按键/80mA大电流LED数码管自动刷新显示/段码LCD/RTC实时时钟/低功耗 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区 (stcaimcu.com)


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 14:24:39 | 显示全部楼层
    7.2                  范例程序1.2.1                     自动校准内部高速IRCHIRC
    例如:校准的目标频率为22.1184MHz,校准误差范围为±0.5%
    则需要将CREHF设置为0,CRECNT设置为(16*22118400)/32768=10800(2A30H),
    即将CRECNTH设置为2AH,CRECNTL设置为30H,CRERES设置为10800 * 0.5%=54(36H)


    //测试工作频率为11.0592MHz
    #include "stc8h.h"//头文件见下载软件
    #define       CNT22M             (16 * 22118400L) / 32768)                     //校准目标频率为22.1184M
    #define       RES22M             (CNT22M *5 / 1000)                              //设置校准误差为0.5%
    void main()
    {
             P_SW2 |= 0x80;//使能访问XFR
             P0M0 = 0x00;
             P0M1 = 0x00;
             P1M0 = 0x00;
             P1M1 = 0x00;
             P2M0 = 0x00;
             P2M1 = 0x00;
             P3M0 = 0x00;
             P3M1 = 0x00;
             P4M0 = 0x00;
             P4M1 = 0x00;
             P5M0 = 0x00;
             P5M1 = 0x00;
    X32KCR = 0xc0;                                                                           //启动外部32K晶振
    while (!(X32KCR & 1));                                                               //等待时钟稳定
             IRCBAND &= ~0x03;
             IRCBAND |= 0x02;                                                                      //选择27M频段
             CLKSEL = 0x00;                                                                          //选择内部高速HIRC为系统时钟
             CRECNTH = CNT22M >>8;                                                      //设置目标校准值
             CRECNTL = CNT22M;
             CRERES = RES22M;                                                                  //设置校准误差
             CRECR = 0x90;                                                                            //使能CRE功能,并设置校准周期为4ms
             while (1)
             {
                       if (CRECR& 0x01)
                       {
    //频率自动校准完成
                       }
             }
    }

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 14:29:15 | 显示全部楼层
    截图202310021426406860.jpg

    其实
    1,直接用内部高速IRC-24MHz 给 CPU 跑;
    2,IRC-24MHz / 2 = 12MHz 给 PLL时钟输入;
    3,12MHz 的 PLL时钟输入 * 12 = 144MHz 时钟输出给 PWM;
    截图202310021430399354.jpg

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 14:35:13 | 显示全部楼层
    7.2.1                     自动校准内部高速IRCHIRC
    例如:校准的目标频率为22.1184MHz,校准误差范围为±0.5%
    则需要将CREHF设置为0,CRECNT设置为(16*22118400)/32768=10800(2A30H),
    即将CRECNTH设置为2AH,CRECNTL设置为30H,CRERES设置为10800 * 0.5%=54(36H)

    //测试工作频率为11.0592MHz
    #include "stc8h.h"                                                                                //头文件见下载软件
    #define       CNT22M             (16 * 22118400L) / 32768)                     //校准目标频率为22.1184M
    #define       RES22M             (CNT22M *5 / 1000)                              //设置校准误差为0.5%
    void main()
    {
             P_SW2 |= 0x80;                                                                            //使能访问XFR
             P0M0 = 0x00;
             P0M1 = 0x00;
             P1M0 = 0x00;
             P1M1 = 0x00;
             P2M0 = 0x00;
             P2M1 = 0x00;
             P3M0 = 0x00;
             P3M1 = 0x00;
             P4M0 = 0x00;
             P4M1 = 0x00;
             P5M0 = 0x00;
             P5M1 = 0x00;
             X32KCR = 0xc0;                                                                           //启动外部32K晶振
             while (!(X32KCR & 1));                                                               //等待时钟稳定
             IRCBAND &= ~0x03;
             IRCBAND |= 0x02;                                                                      //选择27M频段
             CLKSEL = 0x00;                                                                          //选择内部高速HIRC为系统时钟
             CRECNTH = CNT22M >>8;                                                      //设置目标校准值
             CRECNTL = CNT22M;
             CRERES = RES22M;                                                                  //设置校准误差
             CRECR = 0x90;                                                                            //使能CRE功能,并设置校准周期为4ms
             while (1)
             {
                       if (CRECR& 0x01)
                       {
                                                                                                                    //频率自动校准完成
                       }
             }
    }


    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 14:38:09 | 显示全部楼层
    24.2.1                     使能高级PWM的高速模式(异步模式)

    //测试工作频率为24MHz
    #include "stc8h.h"
    #include "intrins.h"
    #define       FOSC                           24000000UL
    #define       HSCK_MCLK             0
    #define       HSCK_PLL                 1
    #define       HSCK_SEL                 HSCK_PLL
    #define       PLL_96M                     0
    #define       PLL_144M                  1
    #define       PLL_SEL                     PLL_144M
    #define       CKMS                          0x80
    #define       HSIOCK                      0x40
    #define       MCK2SEL_MSK        0x0c
    #define       MCK2SEL_SEL1        0x00
    #define       MCK2SEL_PLLD2     0x04
    #define       MCK2SEL_PLLD4     0x08
    #define       MCKSEL_MSK          0x03
    #define       MCKSEL_HIRC         0x00
    #define       MCKSEL_XOSC        0x01
    #define       MCKSEL_X32K          0x02
    #define       MCKSEL_IRC32K     0x03
    #define       ENCKM                      0x80
    #define       PCKI_MSK                 0x60
    #define       PCKI_D1                     0x00
    #define       PCKI_D2                     0x20
    #define       PCKI_D3                     0x40
    #define       PCKI_D4                     0x60
    void delay()
    {
             int     i;
             
             for    (i=0; i<100; i++);
    }
    char ReadPWMA(char addr)
    {
             chardat;
             
             while(HSPWMA_ADR & 0x80);                                                //等待前一个异步读写完成
             HSPWMA_ADR= addr | 0x80;                                                   //设置间接访问地址,只需要设置原XFR地址的低7
                                                                                                                    //HSPWMA_ADR寄存器的最高位写1,表示读数据
             while(HSPWMA_ADR & 0x80);                                                //等待当前异步读取完成
             dat    = HSPWMA_DAT;                                                              //读取异步数据
             
             returndat;
    }
    void WritePWMA(char addr, chardat)
    {
             while(HSPWMA_ADR & 0x80);                                                //等待前一个异步读写完成
             HSPWMA_DAT= dat;                                                                 //准备需要写入的数据
             HSPWMA_ADR= addr & 0x7f;                                                 //设置间接访问地址,只需要设置原XFR地址的低7
                                                                                                                    //HSPWMA_ADR寄存器的最高位写0,表示写数据
    }
    void main()
    {
             P_SW2|= 0x80;                                                                            //使能访问XFR
             
             //选择PLL输出时钟
    #if     (PLL_SEL == PLL_96M)
             CLKSEL&= ~CKMS;                                                                  //选择PLL96M作为PLL的输出时钟
    #elif (PLL_SEL == PLL_144M)
             CLKSEL|= CKMS;                                                                      //选择PLL144M作为PLL的输出时钟
    #else
             CLKSEL&= ~CKMS;                                                                  //默认选择PLL96M作为PLL的输出时钟
    #endif
             
             //选择PLL输入时钟分频,保证输入时钟为12M
             PLLCR&= ~PCKI_MSK;
    #if     (FOSC == 12000000UL)
             PLLCR|= PCKI_D1;                                                                   //PLL输入时钟1分频
    #elif (FOSC == 24000000UL)
             PLLCR|= PCKI_D2;                                                                   //PLL输入时钟2分频
    #elif (FOSC == 36000000UL)
             PLLCR|= PCKI_D3;                                                                   //PLL输入时钟3分频
    #elif (FOSC == 48000000UL)
             PLLCR|= PCKI_D4;                                                                   //PLL输入时钟4分频
    #else
             PLLCR|= PCKI_D1;                                                                   //默认PLL输入时钟1分频
    #endif
             //启动PLL
             PLLCR|= ENCKM;                                                                    //使能PLL倍频
             
             delay();                                                                                          //等待PLL锁频
             //选择HSPWM/HSSPI时钟
    #if     (HSCK_SEL == HSCK_MCLK)
             CLKSEL&= ~HSIOCK;                                                             //HSPWM/HSSPI选择主时钟为时钟源
    #elif (HSCK_SEL == HSCK_PLL)
             CLKSEL|= HSIOCK;                                                                  //HSPWM/HSSPI选择PLL输出时钟为时钟源
    #else
             CLKSEL&= ~HSIOCK;                                                             //默认HSPWM/HSSPI选择主时钟为时钟源
    #endif
             HSCLKDIV= 0;                                                                            //HSPWM/HSSPI时钟源不分频
             
             HSPWMA_CFG= 0x03;                                                             //使能PWMA相关寄存器异步访问功能
             
             //通过异步方式设置PWMA的相关寄存器
             WritePWMA((char)&PWMA_CCER1,0x00);
             WritePWMA((char)&PWMA_CCMR1,0x00);                           //CC1为输出模式
             WritePWMA((char)&PWMA_CCMR1,0x60);                           //OC1REF输出PWM1(CNT<CCR时输出有效电平1)
             WritePWMA((char)&PWMA_CCER1,0x05);                           //使能CC1/CC1N上的输出功能
             WritePWMA((char)&PWMA_ENO,0x03);                                //使能PWM信号输出到端口
             WritePWMA((char)&PWMA_BKR,0x80);                                //使能主输出
             WritePWMA((char)&PWMA_CCR1H,200 >> 8);                    //设置输出PWM的占空比
             WritePWMA((char)&PWMA_CCR1L,200);
             WritePWMA((char)&PWMA_ARRH,1000 >> 8);                    //设置输出PWM的周期
             WritePWMA((char)&PWMA_ARRL,1000);
             WritePWMA((char)&PWMA_DTR,10);                                    //设置互补对称输出PWM的死区
             WritePWMA((char)&PWMA_CR1,0x01);                                 //开始PWM计数
             
             P2M0= 0;
             P2M1= 0;
             P3M0= 0;
             P3M1= 0;
             
             P2= ReadPWMA((char)&PWMA_ARRH);                               //异步方式读取寄存器
             P3= ReadPWMA((char)&PWMA_ARRL);
             
             while(1);
    }



    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-15 13:14
  • 签到天数: 1 天

    [LV.1]初来乍到

    11

    主题

    43

    回帖

    220

    积分

    中级会员

    积分
    220
     楼主| 发表于 2023-10-2 15:06:51 | 显示全部楼层
    本帖最后由 firefly2k 于 2023-10-2 15:12 编辑
    神农鼎 发表于 2023-10-2 14:18
    1, 你节后申请 [免费+包邮送]的 STC8H1K08T-33I-TSSOP20
    2, 你外部挂 32768晶振, 2个外挂电容 15pF
    ===用 ...

    敬业啊,今天竟然还有人上班回复问题
    您的意思是我用beta版可能有问题?
    另外,我需要输出高精度的PWM频率信号,您说的校准的方式可能精度达不到我的要求,我不太想用。我还是想要外挂12M晶振的模式
    等我试完正式版的 STC8H1K08T-33I,有什么结果再跟您反馈下
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 15:25:44 | 显示全部楼层
    您的意思是我用beta版可能有问题?
    ===你用外部时钟,无问题
    另外,我需要输出高精度的PWM频率信号,

    您说的校准的方式可能精度达不到我的要求,我不太想用。我还是想要外挂12M晶振的模式
    ===无问题,12M * 8 = 96MHz 给 PWM做时钟输入



    96MHz/4 = 24MHz 给  CPU
    截图202310021525279145.jpg

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    640

    主题

    1万

    回帖

    1万

    积分

    管理员

    积分
    15687
    发表于 2023-10-2 15:29:06 | 显示全部楼层
    外部 12MHz * 12 = 144MHz 给 PWM做时钟输入
    144MHz/4 = 36MHz 给 CPU,  
    但 STC8H1K08T-33I-TSSOP20 是最高频率不要超过33.1776MHz
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-15 13:14
  • 签到天数: 1 天

    [LV.1]初来乍到

    11

    主题

    43

    回帖

    220

    积分

    中级会员

    积分
    220
     楼主| 发表于 2023-10-2 15:31:36 | 显示全部楼层
    本帖最后由 firefly2k 于 2023-10-2 15:33 编辑
    神农鼎 发表于 2023-10-2 15:29
    外部 12MHz * 12 = 144MHz 给 PWM做时钟输入
    144MHz/4 = 36MHz 给 CPU,  
    但 STC8H1K08T-33I-TSSOP20 是最 ...

    谢谢,我刚刚换上正式版的了,但还是一样的问题,原115200波特率,现在只有19200。可能还是寄存器配置问题,我再按您提供的例程仔细查查
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-11-1 06:57 , Processed in 0.090669 second(s), 73 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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