修改红牛开发板在arduino平台的上cpu速度

起初是发现红牛的官方例程的延时程序跑在arduino上时间是不对的  。

void Delay_10ms (u32 nCount)
{
volatile int i;//volatile表示编译器不要优化这个变量,即使没有用到变量。否则这种空循序编译器直接就删掉忽略了

for (i=0;i<nCount*800;i++);
}     它的定义1ms 是空循环80次。跑起来明显跟实际时间对不上。抛开红牛官方例程的自己时序。至少证明板子arduino没有跑在72M上。用hal函数验证下。

参考  (59条消息) STM32获取时钟频率_米兰的无线电的博客-CSDN博客_stm32查看时钟频率

uint32_t a;
 a = HAL_RCC_GetSysClockFreq();
 Serial.println(a);

发现是48M。尝试在修改、f——cpi发现没有用

 

 

 

但是在把board从genericSTM32F103ZE 改成  vccgnd_f103zet6可以跑在72M上。

查看C:\Users\kyo\.platformio\packages\framework-arduinoststm32\boards.txt 里板子的区别。发现vccgnd的相比通用103

# Generic F103ZETx
GenF1.menu.pnum.GENERIC_F103ZETX=Generic F103ZETx
GenF1.menu.pnum.GENERIC_F103ZETX.upload.maximum_size=524288
GenF1.menu.pnum.GENERIC_F103ZETX.upload.maximum_data_size=65536
GenF1.menu.pnum.GENERIC_F103ZETX.build.board=GENERIC_F103ZETX
GenF1.menu.pnum.GENERIC_F103ZETX.build.product_line=STM32F103xE
GenF1.menu.pnum.GENERIC_F103ZETX.build.variant=STM32F1xx/F103Z(C-D-E)(H-T)

多了一句   

 GenF1.menu.pnum.VCCGND_F103ZET6.build.variant_h=variant_{build.board}.h

看来是多设置了board的变量。

查看C:\Users\kyo\.platformio\platforms\ststm32\boards下json文件的区别 发现是通用f103多了这些 

   "hwids": [
      [
        "0x1EAF",
        "0x0003"
      ],
      [
        "0x1EAF",
        "0x0004"
      ]
    ],

没有啥线索  继续找出现VCCGND的文件的地方。在这里发现了线索    C:\Users\kyo\.platformio\packages\framework-arduinoststm32\variants\STM32F1xx\F103Z(C-D-E)(H-T)

 

这些variant都是用来stm32对应arduino api  的针脚的名字或者函数功能的   。可以看到arduino api用到了gpio,iic,spi ,tim,serial功能 。开启其他stm32特有的功能就需要在pio。ini里加 -D来开启。

原来那一句GenF1.menu.pnum.VCCGND_F103ZET6.build.variant_h=variant_{build.board}.h  是对应在这的开发板自己定义的。h文件。查看跟通用f103的区别  。原来是 variant_VCCGND_F103ZET6_XXX.cpp里多了rcc的设置。对比下跟generic_clock.c的区别

通用的是     注意是启用了usb

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;

8/2*12=48   如果不开usb,会是8/2-16=64  

vccgnd

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

 

8*9=72

这时候就要看时钟树了

 

 默认的genercic f103 用的是hsi  内部高速晶振,vccgnd用的是 hse  外部晶振信号 。如果纯粹选择内部晶振,内部晶振也是8M,pll最多能12倍。主频到64M  所以要跑72满速  必须用hse外部晶振 。内部晶振另一个问题是随着芯片工作升温频率就变了

这里也能看出来 单片机也能是能超频的。经过测试单片机程序80M可以跑,但是usb不正常了 。

知道了原理  那就把代码代码抄过来。  注意weak这个关键词。他的意思是如果在别的地方定义了同名的东西那别的地方的生效。

贴上代码


#include <Arduino.h>
#include "Gpio.h"
uint32_t a;

void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {};

    /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }
    /** Initializes the CPU, AHB and APB buses clocks
     */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
    PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
    PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
    {
        Error_Handler();
    }
}

void setup()
{

    SystemClock_Config();
    LED_Init();
    Serial.begin(9600);
    a = HAL_RCC_GetSysClockFreq();
}

void loop()
{
    // put your main code here, to run repeatedly:
    for (int i = 0; i < 5; i++)
    {
        digitalToggle(LED1_GPIO_PIN + i);
        delay(1000);
        Serial.print("主频:");
        Serial.println(a);
    }
}

 

实验测试主频确实是72m   usb正常。

 

posted @ 2022-08-28 21:09  kyo413  阅读(253)  评论(0)    收藏  举报