主页 > 互联网 > 内容页

使用TLE984X系列MCU进行产品开发

2023-03-08 18:08:30 来源:头条号嵌小白


(资料图片仅供参考)

使用TLE984X系列MCU进行产品开发,开发过程中参考官方例程配置SCU-CGU函数。 CGU全称为Clock Generation Unit(时钟产生单元),使用官方工具箱配置时钟,模式为内部振荡器PLL,产生25MHz时钟信号。 配置完成后,生成工程文件,可找遍了整个工程文件,也没有看到SCU初始化单元是怎么被执行的。 下面是部分代码:

int main(void){  /* Initialization of hardware modules based on Config Wizard configuration */  TLE_Init();//函数初始化,包含SCU初始化函数  /*****************************************************************************  ** Place your application code here                                         **  *****************************************************************************/      /*****************************************************************************  ** Main endless loop                                                        **  *****************************************************************************/  for (;;)  {    /* Main watchdog1 (WDT1) service *///    (void)WDT1_Service();    /***************************************************************************    ** Place your application code here                                       **    ***************************************************************************/  }
void TLE_Init(void){//#ifdef RTE_DEVICE_SDK_SCU  SCU_Init();//SCU初始化函数//#endif//#ifdef RTE_DEVICE_SDK_PMU  PMU_Init();//#endif//#ifdef RTE_DEVICE_SDK_ADC1//  ADC1_Init();//#endif//#ifdef RTE_DEVICE_SDK_ADC2//  ADC2_Init();//#endif//#ifdef RTE_DEVICE_SDK_CCU6//  CCU6_Init();//#endif//#ifdef RTE_DEVICE_SDK_GPT12E//  GPT12E_Init();//#endif//#ifdef RTE_DEVICE_SDK_TRX  TRX_Init();//#endif//#ifdef RTE_DEVICE_SDK_HS//  HS1_Init();//#if (UC_FEAT_HS > 1u)//  HS2_Init();//#endif//#endif//#ifdef RTE_DEVICE_SDK_LS//  LS1_Init();//  LS2_Init();//#endif//#ifdef RTE_DEVICE_SDK_MON//  MONx_Init();//#endif//#ifdef RTE_DEVICE_SDK_PORT  PORT_Init();//#endif//#ifdef RTE_DEVICE_SDK_SSC//  SSC1_Init();//  SSC2_Init();//#endif//#ifdef RTE_DEVICE_SDK_TIMER2X  TIMER2_Init();  TIMER21_Init();//#endif//#ifdef RTE_DEVICE_SDK_UART//  UART1_Init();//  UART2_Init();//#endif//#ifdef RTE_DEVICE_SDK_INT//  INT_Init();//#endif}
void SCU_Init(void){  /***************************************************************************   ** System Clock Output Control                                           **   ***************************************************************************/  SCU->COCON.reg = (uint32) (SCU_COCON); /***************************************************************************  ** Module Pin Select                                                     **  **************************************************************************/#ifdef SCU_MODPISEL  SCU->MODPISEL.reg = (uint32) SCU_MODPISEL;#endif#ifdef SCU_MODPISEL1  SCU->MODPISEL1.reg = (uint8) SCU_MODPISEL1;#endif#ifdef SCU_MODPISEL2  SCU->MODPISEL2.reg = (uint8) SCU_MODPISEL2;#endif#ifdef SCU_MODPISEL3  SCU->MODPISEL3.reg = (uint8) SCU_MODPISEL3;#endif  SCU->GPT12PISEL.reg = (uint8) SCU_GPT12PISEL;}

第三段代码中,只是配置了fsys的分频及选择外部中断口,没有任何关于时钟源的选择及时钟配置相关的代码。 百思不得其解(对启动文件未曾了解),使用keil工具进行Debug,将断点打在PC初始位置,PC:0x00000000,按下F10单步调试,指针会在当前汇编代码中逐步执行,且PC会跳转至SystemInit函数中执行。

PC初始化

SCU配置初始化函数

void SCU_ClkInit(void){  sint32 int_was_mask;  /* disable all interrupts                */  int_was_mask = CMSIS_Irq_Dis();  /***************************************************************************   ** NVM Protection Control                                                **   **************************************************************************/#if (SCU_NVM_BOOT_PROT == 1u)  (void)user_nvm_protect_set((uint32) SCU_NVM_PROT_PW, NVM_PASSWORD_SEGMENT_BOOT);#endif#if (SCU_NVM_CODE_PROT == 1u)  (void)user_nvm_protect_set((uint32) SCU_NVM_PROT_PW, NVM_PASSWORD_SEGMENT_CODE);#endif#if (SCU_NVM_DATA_PROT == 1u)  (void)user_nvm_protect_set((uint32) SCU_NVM_PROT_PW, NVM_PASSWORD_SEGMENT_DATA);#endif /***************************************************************************  ** PLL/SYSCLK Control                                                    **  **************************************************************************/  SCU->NMICON.bit.NMIPLL = 0u;  /* enable XTAL1/2 pins */  SCU_OpenPASSWD();  SCU->MODPISEL1.reg = (uint32)(SCU_MODPISEL1 & SCU_MODPISEL1_XTAL12EN_Msk);  SCU->PASSWD.reg = PASSWD_Close;  /* select LP_CLK */  SCU_OpenPASSWD();  SCU->SYSCON0.bit.SYSCLKSEL = 2u;  SCU_ClosePASSWD();  /* Oscillator Select */  SCU_OpenPASSWD();  SCU->OSC_CON.reg = (uint32)SCU_OSC_CON;//  SCU_ClosePASSWD();  SCU_OpenPASSWD();  SCU->PLL_CON.reg = (uint32) SCU_PLL_CON;  SCU_ClosePASSWD();  SCU_OpenPASSWD();  SCU->CMCON1.reg = (uint32) SCU_CMCON1;  SCU_ClosePASSWD();  SCU->PLL_CON.bit.RESLD = 1u;  /* set PLL_CON.bit.VCOBYP=0 */  SCU->PLL_CON.reg=(SCU->PLL_CON.reg&~SCU_PLL_CON_VCOBYP_Msk)|SCU_PLL_CON_UNPROT_VCOBYP_Msk;  /* set PLL_CON.bit.OSCDISC=0 */  SCU->PLL_CON.reg=(SCU->PLL_CON.reg&~SCU_PLL_CON_OSCDISC_Msk)|SCU_PLL_CON_UNPROT_OSCDISC_Msk;  while (u1_Field_Rd32(&SCU->PLL_CON.reg, (uint8)SCU_PLL_CON_LOCK_Pos, SCU_PLL_CON_LOCK_Msk) == (uint8)0)  {  }  SCU_OpenPASSWD();  /* 0u << 6u */  SCU->SYSCON0.reg = 0u;//PLL OUT signal  SCU_ClosePASSWD();  SCU->NMISRCLR.bit.FNMIPLLC = 1u;    /***************************************************************************   ** AnalogClock Control                                                  **   ***************************************************************************/  /* set factor for MI_CLK and Filt_CLK*/  SCU->APCLK.reg = (uint32) SCU_APCLK;  /* apply setting by toggling APCLK_SET */  SCU_OpenPASSWD();  SCU->APCLK_CTRL.bit.APCLK_SET = 1u;  SCU_ClosePASSWD();  CMSIS_NOP();  SCU_OpenPASSWD();  SCU->APCLK_CTRL.bit.APCLK_SET = 0u;  SCU_ClosePASSWD();  /* enable interrupts                     */  if (int_was_mask == 0)  {    CMSIS_Irq_En();  }}
Reset_Handler   PROC                EXPORT  Reset_Handler               [WEAK]                IMPORT  SystemInit                IMPORT  __main                LDR     R0, =SystemInit                       BLX     R0                LDR     R0, =__main                BX      R0                ENDP

于是,进一步分析,并且对启动文件中部分代码做了一番分析。 程序在执行main函数之前,会先执行启动文件,启动文件中可以处理函数,并使用LDR,将该函数的地址放入R0通用寄存器,再使用BLX指令跳转执行。 执行后再使用LDR进入main函数,程序便进入主函数开始执行。

启动文件部分代码

Debug过程中,遇到一个问题,LDR指令存入R0寄存器的地址,与函数名的地址不符合。 比如systemInit函数在R0寄存器中存入的地址为0x110004D5,但通过watch窗口看到的地址是0x110004D4,小编试过其他函数,均是一样的情况,R0存入的地址比实际的地址+1。

Debug地址不同

标签:

上一篇:
下一篇: