[GD32F350 Urban Youth Home Security Guard] Fourth Post: How to set the GD32F305 system clock to 108MHz[Copy link]
This post was last edited by a media student on 2018-9-23 23:12
【GD32F350 Urban Youth Home Security Guardian】The fourth post is how to set the GD32F305 system clock to 108MHz
Preface:
Dear friends who are participating in the competition, I have run into two big pits here. Let me point them out first and hope it can help everyone.
Pit 1: The hardware I2C interface is occupied by buttons, LED lights, etc., as shown below:
PB7
B3
Button
PB8
LED5
PB9
LED6
PB10
LED4
Therefore, those who are still debugging the hardware I2C according to the official firmware library (GD32F3x0_Firmware_Library_V1.0.0) need to check the relevant interfaces. This may be because the engineers of GigaDevice did not consider these in the PCB design. The I2C source code for software I/O will be given in the fifth post of [GD32F350 Urban Youth Family Security Guard]. This part wasted a week of my time. On the one hand, it was my own carelessness. On the other hand, it was also a testimony to the continuous progress of domestic MCU manufacturers. The other parts are quite comfortable to use. Pit 2: If you use the GD32F3x0_Firmware_Library_V1.0.0 firmware library, you may find that the clock-related modules are not easy to use. I am also very puzzled. I have read the nearly 1,000 lines of RCU code several times, but it still can't run. Maybe there are some places that need further understanding. Here I have carefully checked all the registers and description documents of the RCU clock module, and tried to configure the registers myself. Now I can basically generate 108MHz sys_clk. First of all, everyone should understand the user manual. This clock tree is very important:
Note: If the CK_ADC clock uses the 28M internal IRC, the output is 14MHz, and there is a 2-division frequency, but it is not marked in the figure, so you should pay attention to it. After the system is powered on, if the relevant registers have not been set, the default is to enable the 8Mhz internal clock. If you encounter some other situations, you must also enable this clock. You only need to configure these two registers like this. The meanings can be found in the attached data sheet: RCU_CTL0: 0300a183 RCU_CFG0: 0828240a Note that the key reset cannot clear these two registers. These two registers belong to the backup domain registers and need to be set by other methods. Their reset values can be found in the attached RCU registers I summarized. The following code can be used as reference: Set: RCU_CTL0 |= 0x0300a183; Note that the last four bits of RCU_CFG0 are the control bits for selecting the system clock CK_SYS, where RCU_CFG0[4:3] SCSS, RCU_CFG0[2:0] SCS RCU_CFG0 &= 0xFFFFFFFC;//Set SCS to 00 while(RCU_CFG0&0x0000000C);//Judge that SCSS is 00, conversion is completed Other RCU registers can be set according to the above figure. Main code:
show_system_clk(); printf("\r\nRCU_CTL0:%x",RCU_CTL0); printf("\r\nRCU_CFG0:%x",RCU_CFG0); nops500ms_108M(); printf("\r\nRCU_CFG0:%x",RCU_CFG0); nops500ms_108M(); RCU_CFG0 &= 0xFFFFFFFC;//Set SCS to 00 while(RCU_CFG0&0x0000000C);//Judge that SCSS is 00, and the conversion is completed gd_eval_com_init(EVAL_COM1); printf("\r\nRCU_CFG0:%x",RCU_CFG0); show_system_clk();
复制代码
void show_system_clk(void)//self-built function { printf("\r\nThe current system clock source is: %d",rcu_system_clock_source_get());//10 00 - CK_PLL;0000 CK_IRC8M printf("\r\nThe current system clock frequency is: %dHz",rcu_clock_freq_get(CK_SYS)); printf("\r\nThe current AHB clock frequency is: %dHz",rcu_clock_freq_get(CK_AHB)); printf("\r\nThe current CK_APB1 clock frequency is: %dHz",rcu_clock_freq_get(CK_APB1)); printf("\r\nThe current CK_APB2 clock frequency is: %dHz",rcu_clock_freq_get(CK_APB2)); printf("\r\nThe current CK_ADC clock frequency is: %dHz",rcu_clock_freq_get(CK_ADC)); //28M/2 printf("\r\nThe current CK_CEC clock frequency is: %dHz",rcu_clock_freq_get(CK_CEC)); printf("\r\nThe current CK_USART clock frequency is: %dHz ",rcu_clock_freq_get(CK_USART)); }
复制代码
In fact, the official library function can still be used, but there are a few points to note in RCU: 1. When changing the PLL multiplication factor, be sure to turn off PLLEN first, switch the system clock to the 8MHz internal clock, then clear PLLSTB, then change the PLLMF value, then turn on PLLEN, and at the same time determine whether PLLSTB is stable, and then set the system clock source to pll output. 2. When switching the system clock source, pay attention to the sentence in the manual: Because the change of CK_SYS has an inherent delay, the software needs to read the SCSS bit to ensure that the conversion is complete. You can refer to the following procedure to change the system frequency from 108MHz to 8MHz and set it to 100MHz, provided that the RCU_CTL0 and RCU_CFG0 values are configured in advance. 3. Each time the clock is changed, it is sometimes necessary to reinitialize the serial port.
show_system_clk(); printf("\r\nRCU_CTL0:%x",RCU_CTL0); printf("\r\nRCU_CFG0:%x",RCU_CFG0); RCU_CFG0 &= 0xFFFFFFFC;//Set SCS to 00 while(RCU_CFG0&0x0000000C);//Judge that SCSS is 00, and the conversion is completed gd_eval_com_init(EVAL_COM1); printf("\r\nRCU_CFG0:%x",RCU_CFG0); show_system_clk(); printf("\r\nWaiting for pll to restart.."); RCU_CTL0 &= ~BIT(24); //Turn off PLLEN RCU_CTL0 &= ~BIT(25); //Clear the PLL stable flag RCU_CFG0 &= ~BIT(19);//BIT19 converts the frequency multiplier to 20 RCU_CTL0 |= BIT(24); //Enable PLLEN while(!(RCU_CTL0&(BIT(25)))); RCU_CFG0 |= BIT(1);//Set SCS to 10 while(!(RCU_CFG0&0x0000000C));//Judge that SCSS is 10, and the conversion is complete gd_eval_com_init(EVAL_COM1); show_system_clk();
The reason why it runs at 108MHz is because it needs to process the camera data. Subsequent posts will introduce I2C and camera processing in detail. I have to say that GigaDevice's MCU is still very good. If the library can be made more user-friendly, it is estimated that the domestic market will develop faster. Support domestic products and domestic chips!