[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脚定义如下图:
    在这里插入图片描述
    我使用的是JTAG接口,但是也可以SWD下载,其中RESET脚我没接,软件里面好像也可以设置下载之后自动复位。

    连接好芯片和JLink和电脑之后,在Keil-Options for Target…-Debug标签页
    在这里插入图片描述

    点击Setting之后:
    在这里插入图片描述
    选择SW模式,右边是速率,一般来说只要连接没有问题,芯片没有问题,jlink没有问题,右边框框就是显示到芯片信号,这个时候就可以下载程序进去MCU里面了。

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

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

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

详细说下这四步:
第一步我是选定了STM103C8T6,然后到达芯片的设置的步骤
在这里插入图片描述
只能简略的描述下这个软件的一些功能,详细的使用方法建议上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闪烁就成功了。

  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那我来给你提供一个使用HAL库驱动STM32F103C8T6定时器3,控制L298N电机驱动模块的示例代码。 首先,你需要在STM32CubeMX中配置定时器3和GPIO引脚,作为L298N电机驱动模块的控制引脚,如下图所示: ![image](https://img-blog.csdn.net/20180517171909334?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NvbW1lbnRzMTEx/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/75) 上图中,TIM3被配置为PWM输出模式,GPIOA的Pin6和Pin7被配置为TIM3的CH1和CH2通道输出引脚,分别对应L298N电机驱动模块的IN1和IN2引脚。 接下来,我们来看看使用HAL库驱动定时器3和GPIO的代码实现: ```c #include "stm32f1xx_hal.h" // 定义全局变量 TIM_HandleTypeDef htim3; // 定义函数原型 void MX_TIM3_Init(void); void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim); void HAL_MspInit(void); int main(void) { // 初始化HAL库 HAL_Init(); // 配置系统时钟 SystemClock_Config(); // 配置定时器3 MX_TIM3_Init(); // 启动定时器3 HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); // 设置PWM占空比 __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 500); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 0); while (1) { // 空循环 } } // 定义定时器3初始化函数 void MX_TIM3_Init(void) { TIM_OC_InitTypeDef sConfigOC = {0}; htim3.Instance = TIM3; htim3.Init.Prescaler = 71; htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.Period = 999; htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&htim3); sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2); HAL_TIM_MspPostInit(&htim3); } // 定义定时器3底层初始化函数 void HAL_TIM_MspPostInit(TIM_HandleTypeDef* htim) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if (htim->Instance == TIM3) { __HAL_RCC_TIM3_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } } // 定义HAL库底层初始化函数 void HAL_MspInit(void) { __HAL_RCC_AFIO_CLK_ENABLE(); __HAL_RCC_PWR_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); } ``` 在上面的代码中,我们使用了HAL库定时器3和GPIO初始化函数,创建了一个PWM输出模式的定时器3,同时设置了PWM占空比,以控制L298N电机驱动模块的IN1和IN2引脚。需要注意的是,我们使用了TIM3的CH1和CH2通道输出引脚,分别对应了L298N电机驱动模块的IN1和IN2引脚。 当你把代码烧录进STM32F103C8T6开发板后,你可以通过修改__HAL_TIM_SET_COMPARE函数的第二个参数,来控制PWM占空比的大小,从而驱动L298N电机驱动模块。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值