[HAL库]STM32F103C8T6定时器2实现LED闪烁

写在前面

这篇博客介绍下我从环境配置到烧录STM32F103C8T6并使用HAL库点灯的过程。

MDK下载

MDK跟C51都是Keil的功能模块,我说下我搭建开发环境的流程,仅供参考。

  1. 首先因为我电脑原先就存在C51,下载MDK安装包之后,一直默认下一步就好了,然后下好之后,注册机激活。期间遇到的一些问题:

    第一个:下好MDK之后再打开Keil之后会弹框报错两次,提示我版本要高于5,ARMCLANG有错误。这个问题我看到对使用没影响,只是每次进Keil恶心一点就没管,网上搜了一下说是电脑的时间不对,但是我的电脑时间就是最新的时间,应该不是这个原因。后来我因为一些报错,把Keil彻底卸载了,然后先装MDK,后装C51,再也没有报错过。

    第二个:编译程序的时候提示我各种main.o错误,然后说没有找到/bin目录下的一个ARMCC.BIN。我的解决方法:网上找了一个ARMComplier 5.06版本的,然后安装在Keil/ARM目录下 ,安装完了发现没有帮我创建新文件夹,然后我就把最新修改的几个文件夹单独拎出来放在了ARMCC(自己新建的)里面。然后到Keil里面把这个C编译器手动添加,这样就可以正常编译了。

    第三个:出错的原因是在解决第二个问题的途中把Keil/ARM/BIN文件夹复制到了我创建的Keil/ARM/ARMCC内,导致下载程序到MCU的时候报错说找不到ARM/BIN内的一个DLL文件。解决方法:把Keil/ARM/ARMCC内的BIN文件夹又复制了一个放在Keil/ARM目录内,最后下载正常。

    至此,编译程序和下载程序就正常了。其他的坑我还没有遇到过。

  2. STlink或者J-link的使用:
    我的电脑连接上J-Link之后,设备管理器里面不识别J-link,于是乎CSDN搜了一个可以用的J-link驱动,下载安装完之后J-link就识别了。

  3. 开发板与电脑连接并识别:
    我的开发板是自己打板和焊接的,开发板上3.3V GND SWDIO SWCLK跟J-link上相应的口连接好,DIO连DIO,CLK连CLK。关于J-Tag口,pin脚定义如下图:
    [HAL库]STM32F103C8T6定时器2实现LED闪烁_第1张图片
    我使用的是JTAG接口,但是也可以SWD下载,其中RESET脚我没接,软件里面好像也可以设置下载之后自动复位。

    连接好芯片和JLink和电脑之后,在Keil-Options for Target…-Debug标签页
    [HAL库]STM32F103C8T6定时器2实现LED闪烁_第2张图片

    点击Setting之后:
    [HAL库]STM32F103C8T6定时器2实现LED闪烁_第3张图片
    选择SW模式,右边是速率,一般来说只要连接没有问题,芯片没有问题,jlink没有问题,右边框框就是显示到芯片信号,这个时候就可以下载程序进去MCU里面了。

    到这里为止,我的编译,下载好像都没有问题了。

然后介绍下我是怎么用CubeMX生成代码的。

  1. 选型号、设置时钟、其他一些乱七八糟的设置
  2. 开定时器、设定分频、初值、允许中断之类的
  3. 回调函数(中断服务函数)里面定义功能
  4. 开启定时器中断

详细说下这四步:
第一步我是选定了STM103C8T6,然后到达芯片的设置的步骤
[HAL库]STM32F103C8T6定时器2实现LED闪烁_第4张图片
只能简略的描述下这个软件的一些功能,详细的使用方法建议上B站搜索视频跟着学。
第一步设置好TIM2的时钟频率为24MHz之后

第二步设置定时器初值有个公式 Time(秒)=(分频-1)(数数值-1)/24MHz。我这是1=(24000-1)(1000-1)/24000000

第三步是找到stm32f1xx_it.c这个文件,然后找到TIM2_IRQHandler(void)这个函数里面的HAL_TIM_IRQHandler(&htim2);回调函数,然后在这个函数里面找到 HAL_TIM_PeriodElapsedCallback(htim); 这个函数,意思就是周期运行的回调函数,到这个函数里面写相应的内容。
使用这个HAL_TIM_PeriodElapsedCallback(htim);函数的时候,库里面的源程序尽量别动,库在定义之前加了一个weak void,意思是如果没有找到用户自己重写的HAL_TIM_PeriodElapsedCallback函数,那么程序才会编译库里面自带的这个。官方的注释也写着让我们尽量不要动这个weak定义的库原函数,如果我们需要用,那么我们直接在其他位置重新重定义一个HAL_TIM_PeriodElapsedCallback(htim);函数,然后在自己定义的这个函数里面再写相应的中断处理内容。

	if(htim->Instance == TIM2)
	{
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
	}

意思就是如果发生中断的是TIM2,那么执行HAL库里面的端口翻转函数,翻转的IO口试B5口。

写完上面的回调函数,那么就差最后一部开中断。

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
	HAL_TIM_Base_Start_IT(&htim2);			//开中断
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

上面的代码大部分是CubeMX生成的,只有HAL_TIM_Base_Start_IT(&htim2);是我自己在 USER CODE区域 调用了库,意思就是开中断。

写完这些,编译,下载。我的开发板上PB5口接的LED灯就开始周期性闪烁了,示波器实测1S翻转IO一次,意味着TIM2中断运行正常,功能执行正常。

至此,定时器2实现LED闪烁就成功了。

你可能感兴趣的:(技术分享,stm32,单片机,arm)