打印
[其他]

继搞定GPIO后,搞定了时钟系统。

[复制链接]
3296|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
没有用库,因为感觉用库不爽。(不想比较,因为新事物毛病多是正常的)


贴出来,支持国产!


头文件定义:

#define        PLL_P(x)        ( (x) << (28) )
#define        PLL_Q(x)        ( (x) << (24) )
#define        PLL_R(x)        ( (x) << (20) )
#define        PLL_N(x)        ( (x) << (8) )
#define        PLL_M(x)        ( (x) << (0) )
#define        PLL_XTAL_IN()        ( (0) << (7) )
#define        PLL_HRC_IN()        ( (1) << (7) )

// CMU_OSCSTBSR
#define HRC_STABLE                1
#define XTAL_STABLE                0x08
#define MPLL_STABLE                0x20
#define UPLL_STABLE                0x40

#define FLASH_READ_WAIT(x)        ((x) << (4))

#define RET_RAM_WRITE_WAIT(x)        ((x) << (28))
#define RET_RAM_READ_WAIT(x)        ((x) << (24))
#define RAM3_WRITE_WAIT(x)                ((x) << (12))
#define RAM3_READ_WAIT(x)                ((x) << (8))
#define RAM12_WRITE_WAIT(x)                ((x) << (4))
#define RAM12_READ_WAIT(x)                ((x) << (0))

#define HCLK_DIV(x)                                ((x) << (24))
#define EXCLK_DIV(x)                        ((x) << (20))                /*        SDIO, CAN */
#define PCLK4_DIV(x)                        ((x) << (16))                /*        ADC controller */
#define PCLK3_DIV(x)                        ((x) << (12))                /*        RTC, I2C, CMP, WDT  max 50MHz */
#define PCLK2_DIV(x)                        ((x) << (8))                /*        ADC convert  60MHz */
#define PCLK1_DIV(x)                        ((x) << (4))                /*        UART, SPI,TA,T4,T6 Control, I2S,  100MHz */
#define PCLK0_DIV(x)                        ((x) << (0))                /*        T6, 200MHz */

#define USBCLK_SYS_DIV2                        0x20
#define USBCLK_SYS_DIV3                        0x30
#define USBCLK_SYS_DIV4                        0x40
#define USBCLK_MPLL_P                        0x80
#define USBCLK_MPLL_Q                        0x90
#define USBCLK_MPLL_R                        0xA0
#define USBCLK_UPLL_P                        0xB0
#define USBCLK_UPLL_Q                        0xC0
#define USBCLK_UPLL_R                        0xD0

#define PERCLK_SCFGR                        0
#define PERCLK_MPLL_P                        0x0008
#define PERCLK_MPLL_Q                        0x0009
#define PERCLK_MPLL_R                        0x000A
#define PERCLK_UPLL_P                        0x000B
#define PERCLK_UPLL_Q                        0x000C
#define PERCLK_UPLL_R                        0x000D

#define GPIO_UNLOCK()        ( CM_GPIO->PWPR        = 0xA501 )
#define GPIO_LOCK()                ( CM_GPIO->PWPR        = 0xA500 )

#define PWR_UNLOCK()        ( CM_PWC->FPRC        = 0xA50B )
#define PWR_LOCK()                ( CM_PWC->FPRC        = 0xA500 )

#define SRAM_UNLOCK()        ( CM_SRAMC->WTCR = 0x3B01 )
#define SRAM_LOCK()                ( CM_SRAMC->WTCR = 0x3B00 )

#define SRAM_UNLOCK()        ( CM_SRAMC->WTCR = 0x3B01 )
#define SRAM_LOCK()                ( CM_SRAMC->WTCR = 0x3B00 )



实现部分:
void ClkInit(void)
{
        uint16_t tmp;
       
        // PC14, PC15, PH0, PH1 as the xtal pin
        GPIO_UNLOCK();
        CM_GPIO->PCRC14                        |= 0x8000;
        CM_GPIO->PCRC15                        |= 0x8000;
        CM_GPIO->PCRH0                        |= 0x8000;
        CM_GPIO->PCRH1                        |= 0x8000;
        GPIO_LOCK();
       
        /**** switch to XTAL ( 10MHz )                *************************/
        PWR_UNLOCK();
        CM_CMU->XTALCFGR                = 0xA0;                // XTAL, drive small
        CM_CMU->XTALSTBCR                = 8;                // stable time is 8163 circle
        CM_CMU->XTALCR                        = 0;                // start XTAL
        while (!( CM_CMU->OSCSTBSR & XTAL_STABLE ))
        {}

        CM_CMU->XTAL32CFGR                = 0;                // MID        drive
        CM_CMU->XTAL32CR                = 0;                // start
        PWR_LOCK();
       
        /**** M-VCO = 400MHz, U-VCO = 240MHz                ********************/
        PWR_UNLOCK();
        CM_CMU->PLLCFGR                        = PLL_P(1)                /*200MHz*/
                                                        | PLL_Q(3)                /* 100MHz*/
                                                        | PLL_R(7)                /* 50MHz*/
                                                        | PLL_N(19)                /* 10MHz x 20 */
                                                        | PLL_XTAL_IN()
                                                        | PLL_M(0);
        CM_CMU->UPLLCFGR                = PLL_P(4)                /* 48MHz*/
                                                        | PLL_Q(3)                /* 60MHz*/
                                                        | PLL_R(1)                /* 120MHz*/
                                                        | PLL_N(47)                /* 5MHz x 48 */
                                                        | PLL_XTAL_IN()
                                                        | PLL_M(1);                /* frequency division = 2 , input frequency = 5MHz */
        CM_CMU->PLLCR                        = 0;
        CM_CMU->UPLLCR                        = 0;
        while (!( CM_CMU->OSCSTBSR & MPLL_STABLE )){}
        while (!( CM_CMU->OSCSTBSR & UPLL_STABLE )){}
        PWR_LOCK();

        /*******************         FLASH and SRAM insert wait circle                ************/
        CM_EFM->FAPRT        = 0x0123;
        CM_EFM->FAPRT        = 0x3210;        // Unlock flash
        CM_EFM->FRMC                |= FLASH_READ_WAIT(5);                        // data sheet V1.6 page 179
        CM_EFM->FAPRT        = 0x4567;        // lock
       
        SRAM_UNLOCK();
        CM_SRAMC->WTCR                = RET_RAM_WRITE_WAIT(1)
                                                | RET_RAM_READ_WAIT(1)
                                                | RAM3_WRITE_WAIT(1)
                                                | RAM3_READ_WAIT(1)
                                                | RAM12_WRITE_WAIT(1)
                                                | RAM12_READ_WAIT(1);
        SRAM_LOCK();
        /************                system clock select         **********
                sys clock = 200MHz
                SDUI clock = 100MHz
                ADC control = 100MHz
                PCK3 = 50MHz
                PCK2 =50MHz ,ADC converter
                PCK1 = 100MHz, uart, TA,T4,T6
               
        */
        tmp = CM_CMU->OSCSTBSR;
        if (( tmp & XTAL_STABLE ) && ( tmp & MPLL_STABLE ))
        {
                PWR_UNLOCK();
                CM_CMU->CKSWR                = 5;                // system clock is MPLL-P, 200MHz
                CM_CMU->SCFGR                = HCLK_DIV(0) | EXCLK_DIV(1) | PCLK4_DIV(1) | PCLK3_DIV(2) |PCLK2_DIV(2) | PCLK1_DIV(1) | PCLK0_DIV(1);
                CM_CMU->USBCKCFGR        = USBCLK_UPLL_P;
                CM_CMU->PERICKSEL        = PERCLK_SCFGR;
                CM_CMU->I2SCKSEL        = PERCLK_SCFGR;
                PWR_LOCK();
        }
}




初步运行验证,正常,

使用特权

评论回复
沙发
caigang13| | 2024-6-2 15:35 | 只看该作者
用库肯定不错,前提是库函数要做好。

使用特权

评论回复
板凳
qintian0303| | 2024-6-2 20:45 | 只看该作者
应该先搞定时钟系统啊,不过这样直接操作寄存器很怕会忘记哪个配置导致错误

使用特权

评论回复
地板
前功尽弃| | 2024-6-3 09:13 | 只看该作者
直接操作寄存好

使用特权

评论回复
5
cooldog123pp| | 2024-6-3 09:15 | 只看该作者
直接寄存器看个人能力了,但是等你离职以后接手的人就很蛋疼了,或者过了很长一段时间你去看自己的程序就嘿嘿,注释要做好。

使用特权

评论回复
6
acrelyjh| | 2024-6-3 11:55 | 只看该作者

小华MCU全系列产品提货,欢迎联系18256013035  微信同号

使用特权

评论回复
7
wubangmi| | 2024-6-3 13:06 | 只看该作者
你说的初步两个字用的非常正确,这个升频代码还没写全,我告诉你有bug。
具体什么bug就看你批量生产了,遇到了奇怪的问题想不通的,记得在群里找人答疑。

不是写寄存器方式不好,而是你在没有完全了解MCU特性和仔细研读用户手册的前提下,不建议直接写寄存器。

换个思路考虑下问题,原厂毕竟是原厂,芯片有什么Bug,他可以在库函数里用软件方式做弥补。
原厂那么多人花那么多时间写的库,个人不觉得你写的寄存器肯定没有原厂写的周全。

使用特权

评论回复
8
xzy568| | 2024-6-3 16:29 | 只看该作者
如果原厂库开源,出了问题,自己去对比原厂库,最重要的还是开发效率问题,虽然直接写寄存器效率高一点,用库操作,多了一层封装

使用特权

评论回复
9
dontium|  楼主 | 2024-6-3 17:28 | 只看该作者
wubangmi 发表于 2024-6-3 13:06
你说的初步两个字用的非常正确,这个升频代码还没写全,我告诉你有bug。
具体什么bug就看你批量生产了,遇 ...

请问一下,具体哪个地方有BUG、愿听指导。

使用特权

评论回复
10
wubangmi| | 2024-6-4 09:41 | 只看该作者
dontium 发表于 2024-6-3 17:28
请问一下,具体哪个地方有BUG、愿听指导。

请看截图

1717465228334.jpg (163 KB )

1717465228334.jpg

使用特权

评论回复
11
亚瑟| | 2024-6-28 19:41 | 只看该作者
库函数写得好就行

使用特权

评论回复
12
发货后已经wi| | 2024-8-28 18:59 | 只看该作者
选择DMA中断类型为:数据块传输完成中断

使用特权

评论回复
13
shenxiaolin| | 2024-9-29 11:17 | 只看该作者
努力加油干就完了

使用特权

评论回复
14
申小林一号| | 2024-9-30 13:54 | 只看该作者
继续加油

使用特权

评论回复
15
更多更合适ii| | 2024-9-30 17:18 | 只看该作者
你的代码实现看起来很扎实!手动配置时钟。这种确实能更好地控制硬件细节,并且便于优化性能。

使用特权

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

本版积分规则

个人签名:官向官来民向民,穷人向的是穷人

151

主题

1172

帖子

10

粉丝