写在前面
这篇博客介绍下我从环境配置到烧录STM32F103C8T6并使用HAL库点灯的过程。
MDK下载
MDK跟C51都是Keil的功能模块,我说下我搭建开发环境的流程,仅供参考。
-
首先因为我电脑原先就存在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目录内,最后下载正常。
至此,编译程序和下载程序就正常了。其他的坑我还没有遇到过。
-
STlink或者J-link的使用:
我的电脑连接上J-Link之后,设备管理器里面不识别J-link,于是乎优快云搜了一个可以用的J-link驱动,下载安装完之后J-link就识别了。 -
开发板与电脑连接并识别:
我的开发板是自己打板和焊接的,开发板上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生成代码的。
- 选型号、设置时钟、其他一些乱七八糟的设置
- 开定时器、设定分频、初值、允许中断之类的
- 回调函数(中断服务函数)里面定义功能
- 开启定时器中断
详细说下这四步:
第一步我是选定了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闪烁就成功了。