STM32
直播中

王鹏

7年用户 1273经验值
私信 关注
[问答]

如何利用stm32f103c8t6最小系统板实现LED周期闪烁?

如何利用STM32f103c8t6最小系统板实现LED周期闪烁?

回帖(1)

何培芬

2021-11-25 11:54:50
  测试平台

  PlatformIO IDE(VSCode)
stm32f103c8t6最小系统板,板载LED连接在PC13管脚,低电平点亮
j-link 仿真调试器
  测试目标:创建stm32cube框架的工程项目,实现LED周期闪烁的代码
  创建工程项目

  这一步很简单,请注意选择框架stm32cube ^ [stm32cube对应的就是cubemx库,详见STM32Cube ],开发板选择STM32F103C8(20kRAM。64kFlash )(通用),名称随便,最后点击保存即可:

  

  


  

  

  添加例程代码

  按照STM32Cube HAL和Nucleo-F401RE:调试和单元测试-向生成的项目中添加代码 ^ [ STM32Cube HAL和Nucleo-F401RE:调试和单元测试 ]描述的过程添加适合自己的开发板的代码(修改对应的LED管脚)即可)。
  快捷src文件夹,新建两个文件,一个是main.h另一个是main.c:

  

  


向mian.h中添加以下代码,如果您的板载LED连接到其他管脚,请相应修改关于LED的三个宏定义:


#ifndef MAIN_H
#define MAIN_H


#include "stm32f1xx_hal.h"


#define LED_PIN GPIO_PIN_13
#define LED_GPIO_PORT GPIOC
#define LED_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()


#endif  // MAIN_H


向mian.c中添加以下代码:


#include "main.h"


void LED_Init(void);


int main(void) {
  HAL_Init();
  LED_Init();


  while (1) {
    // LED 翻转
    HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_PIN);
    HAL_Delay(1000);
  }
}


void LED_Init(void) {
  // LED GPIO 初始化
  LED_GPIO_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Pin = LED_PIN;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct);
}


void SysTick_Handler(void) { HAL_IncTick(); }
修改下载器,PlatformIO默认的下载器其st-link
我们使用的是j-link
修改platformio.ini文件,添加jlink下载器

  

  

确保把stm32f103c8t6的最小系统板通过j-link连接到电脑u***,编译并上传程序:

  


这个时候,我们会发现,LED并没有按照预期1s进行闪烁,通过参考stm32cube生成的工程项目可以发现,我们没有对单片机外部时钟进行分频,也就是说我们现在用的是8M始终。


这里我们添加了两个新的文件sys_basic.h和sys_basic.c。
文件sys_basic.h内容如下:


#ifndef SYS_BASIC_H
#define SYS_BASIC_H


void _Error_Handler(char*, int);
#define Error_Handler() _Error_Handler(__FILE__, __LINE__)


void SystemClock_Config(void);


#endif
文件sys_basic.c内容如下:


#include "sys_basic.h"
#include "stm32f1xx_hal.h"


/** System Clock Configuration
*/
void SystemClock_Config(void) {
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;


  /**Initializes the CPU, AHB and APB busses clocks
   */
  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(__FILE__, __LINE__);
  }


  /**Initializes the CPU, AHB and APB busses 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(__FILE__, __LINE__);
  }


  /**Configure the Systick interrupt time
   */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);


  /**Configure the Systick
   */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}


/**
* @brief  This function is executed in case of error occurrence.
* @param  None
* @retval None
*/
void _Error_Handler(char* file, int line) {
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  while (1) {
  }
  /* USER CODE END Error_Handler_Debug */
}


void NMI_Handler(void) {}


void HardFault_Handler(void) {
  while (1) {
  }
}


void MemManage_Handler(void) {
  while (1) {
  }
}


void BusFault_Handler(void) {
  while (1) {
  }
}


void UsageFault_Handler(void) {
  while (1) {
  }
}


void SVC_Handler(void) {}


void DebugMon_Handler(void) {}


void PendSV_Handler(void) {}


SystemClock_Config时钟初始化在函数中实现,此处时钟源选择使用8M高速晶振,9倍频等常用的时钟配置
修改main.c
在main.c中包含头文件sys_basic.h并在主函数HAL_Init();后加入时钟初始化函数调用SystemClock_Config();。


  
  

此时编译上传程序,可以看到LED按照1s的间隔闪烁l!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分