注:keil仿真可以这样解决,下载进开发板并不会出现问题
注:仅用于keil仿真
注:仅用于keil仿真
注:仅用于keil仿真
使用芯片STM32F103ZE
实验内容:独立看门狗实验,利用STM32CubeMx生成代码,并利用keil查看仿真结果。参考例程正点原子独立看门狗实验
- stm32Cube配置及用户代码如下
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_USART1_UART_Init();
MX_IWDG_Init();
/* USER CODE BEGIN 2 */
printf("Hello World\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)==RESET)
{
HAL_IWDG_Refresh(&hiwdg);
HAL_GPIO_WritePin(LED0_GPIO_Port, LED0_Pin, GPIO_PIN_RESET);
printf("Refresh the IWDG\r\n");
while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)!=SET)
HAL_Delay(10);
}
}
/* USER CODE END 3 */
}
-
问题分析:
点击调试运行后,看门狗一直复位,并且没有串口输出。点击打开IWDG的寄存器后发现寄存器值并没有被初始化。若将printf语句与初始化语句互换后,程序一直执行printf语句,运行如下
由此可推断,独立看门狗初始化MX_IWDG_Init() 存在问题,初始化函数通过调用HAL_IWDG_Init 函数实现对看门狗RLR,PR寄存器 的初始化,但实际观察到寄存器值并没有被初始化,所以问题应该是在于HAL_IWDG_Init函数。利用keil单步执行进入MX_IWDG_Init() 函数,发现在执行 HAL_IWDG_Init(&hiwdg) 函数后程序进入死循环,于是重新仿真单步执行进入到HAL_IWDG_Init(&hiwdg) 之中,在执行以下语句后程序跳转到启动文件startup_stm32f103xe.s 进行系统复位。
由此可以验证 MCU一直复位是HAL_IWDG_Init函数中 __HAL_IWDG_START(hiwdg); 语句引起的。
__HAL_IWDG_START(hiwdg);
- 解决过程
查看函数定义,发现该语句是向KR 寄存器中写入0x5555开启看门狗
#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE)
//宏定义
#define IWDG_KEY_RELOAD 0x0000AAAAU /*!< IWDG Reload Counter Enable */
#define IWDG_KEY_ENABLE 0x0000CCCCU /*!< IWDG Peripheral Enable */
#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555U /*!< IWDG KR Write Access Enable */
#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000U /*!< IWDG KR Write Access Disable */
在进行执行初始化之前就打开了看门狗,寄存器值默认为0,所以MCU会由于没有喂狗而一直复位
- 解决办法
将 __HAL_IWDG_START(hiwdg)语句从HAL_IWDG_Init中删除,放在main.c中调用
结果如下图,看门狗相关寄存器初始化正常。
那么为什么正点原子的程序没有错误,可能是由于我们使用的hal版本不同,或者是正点原子对hal库进行了修改。在正点原子的库中确实存在HAL_IWDG_Start 函数。
- 加上该条语句确保按键松开,不支持连续按
while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)!=SET)
HAL_Delay(10);