整个STMF407系列的学习汇总链接如下:
https://github.com/GreyZhang/g_stmf407
我选择的IDE对于基础功能来说,基本上是一个开箱即用的环境。不过,我没有找到文档性的说明,好在代码本身的注释就是一个很好的文档说明。
开始之前,我想实现的是一个1ms的周期性中断。看了一下这个芯片的设计,似乎设计之初就考虑了很多像我这样的用户的使用方便。硬件上直接有一个systick的功能,这样任务调度等功能可以根据此功能进行开发匹配。使用这个功能可以很容易获得1ms或者8分频的一个定时。
自动生成的功能默认对此进行了初始化,这里我简单理顺一下初始化的代码接口。
首先,HAL_Init。
从自动生成的注释看,就知道这个功能在这里初始化。
接下来:
从这里可以找到初始化的信息。
如此,初始化完成。但是软件执行还是会有问题,毕竟我们需要找到相应的ISR。我开始寻找中断向量表,很容易在一段汇编代码中找到了。
进一步查看ISR函数。
这里调用了一个函数,还得进一步查看,从这里看似乎看得出这里多了一层纯粹为了软件层级而设计的假接口。
分析到这里,比较有价值的信息就发觉出来了。这个函数是需要我们自己重新实现的用户接口。从代码注释看,还有一个接口需要我们自己实现,那就是 HAL_SYSTICK_Callback()。其实,这个也是一个形式意义上的接口了,所谓的中断回调,方便我们增加理解的同时扩充应用代码。在此,我也再次扩增一个接口层,按照代码中的注释提示来实现。
经过上面的分析,可以设计代码以实现一个2s周期的LED闪烁。关键代码如下:
/* USER CODE BEGIN 0 */
uint32_t systick_counter_1ms;
uint8_t task_1000ms_flg;
uint32_t counter = 0U;
void HAL_SYSTICK_Callback(void)
{
/* NOTE : This function Should not be modified, when the callback is needed,
the HAL_SYSTICK_Callback could be implemented in the user file
*/
systick_counter_1ms++;
if (systick_counter_1ms % 1000 == 0U)
{
task_1000ms_flg = 1U;
}
}
void HAL_IncTick(void)
{
HAL_SYSTICK_Callback();
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
counter++;
if (task_1000ms_flg == 1U)
{
HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);
task_1000ms_flg = 0U;
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
完整的代码参考: https://github.com/GreyZhang/g_stmf407
以上的软件,编译成功烧写后,我的开发板上的LED灯会以2s为周期进行周期性闪烁。