STM32学习——定时器与串口综合训练




扩展知识

  sprintf():字符串格式化函数,把格式化的数据写入某个字符串中。

#include "sudio.h"		//引入头文件
int sprintf(char *string, char *format[,argument,....]);	//string是用来存放格式化后的数据

例子
在这里插入图片描述

uint8_t Str_buff[64];
sprintf((char*)Str_buff, "温度是:%d摄氏度",tmp);		//tmp的数值填到%d的地方
HAL_UART_Transmit(&huart1,Str_buff,sizeof(Str_buff),0xFFFF);	//串口发送函数(阻塞式发送函数)   
//huart1=所用UART的别名;Str_buff=需要发送的数据;sizeof(Str_buff)=发送的字节数;0xFFFF=最大发送时间,超过该时间退出发送

题目要求

在这里插入图片描述
在这里插入图片描述




练习

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

问题1

在这里插入图片描述
在这里插入图片描述

问题2

在这里插入图片描述

问题3

在这里插入图片描述
在这里插入图片描述

问题4

在这里插入图片描述
在这里插入图片描述

main代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */

#include "stdio.h"

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

#define LED1_on() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)			//LED1亮
#define LED1_off() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)		//LED1灭
#define LED2_on() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)			//LED1亮
#define LED2_off() HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)		//LED1灭


#define LED1_toggle() 	HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9)			//翻转LED1的电平
#define LED2_toggle() 	HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8)			//翻转LED2的电平

uint8_t str1[] = "========STM32F103C8T6欢迎您========\r\n";
uint8_t hh = 0, mm = 0, ss = 0, ss05 = 0;				//hh时,mm分,ss秒,ss05间隔0.5秒
uint8_t str_buff[64];		//字符串的缓存空间   64个字节
uint8_t Rx_dat[16];			//接收的缓存空间			16个字节

void Ckeck_LED()		//LED依次点亮,然后熄灭,完成灯光检测
{
	LED1_on();
	HAL_Delay(500);
	LED2_on();
	HAL_Delay(500);
	
	LED1_off();
	HAL_Delay(500);
	LED2_off();
	HAL_Delay(500);
}

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)			//定时器2的中断回调函数,每隔0.5s进入一次定时器2中断,翻转LED1的电平			问题3完成
{
	LED1_toggle();
	ss05++;
	if(ss05 == 2)
	{
		ss05 = 0;
		ss++;
		if(ss == 60)
		{
			ss = 0;
			mm++;
			if(mm = 60)
			{
				mm = 0;
				hh++;
			}
		}
	}
}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)			//串口1的中断回调函数,当串口要接受信息时,发生中断,进入该函数
{
	if(huart->Instance == USART1)
	{
		if(Rx_dat[0] == 0xBF && Rx_dat[2] == 0xFB)
		{
			switch(Rx_dat[1])
			{
				case 0xa1:	
					LED2_on();
					sprintf((char *)str_buff,"%d:%d:%d		LED2打开\r\n",hh,mm,ss);		//将"%d:%d:%d		LED2打开"字符串格式化写入str_buff中				需要引入头文件		#include "stdio.h"
				break;
				
				case 0xa2:
					LED2_off();
					sprintf((char *)str_buff,"%d:%d:%d		LED2关闭\r\n",hh,mm,ss);		//需要引入头文件		#include "stdio.h"
				break;
				
				default:
					sprintf((char *)str_buff,"%d:%d:%d		这是一个错误的命令\r\n",hh,mm,ss);		//需要引入头文件		#include "stdio.h"
				
					break;
			}
			HAL_UART_Transmit(&huart1,str_buff,sizeof(str_buff),100000);			
			HAL_UART_Receive_IT(&huart1,Rx_dat,3);		//继续开启串口接收中断功能,方便后续再接收(如不开启,则只能接收一次指令)
		}
	}
}

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
	LED1_on();									//LED1亮
	LED1_toggle();							//翻转LED1的电平
  /* 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();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */

	Ckeck_LED();			//LED依次点亮,然后熄灭,完成灯光检测		问题1完成
	
	HAL_UART_Transmit(&huart1,str1,sizeof(str1),10000);			//注意:开启串口  要放在初始化函数(119行“MX_USART1_UART_Init();”)后			问题2完成
	
	HAL_UART_Receive_IT(&huart1,Rx_dat,3);			//开启串口接收中断(CubeMX只是使能,但是需要人为开启)		 stm32f1xx_hal_uart.h的750行		Rx_dat为接收缓存区		3为字节数
																			//进入中断后执行串口回调函数HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)			
	
	HAL_TIM_Base_Start_IT(&htim2);			//开启定时器中断(CubeMX只是使能,但是需要人为开启)		STM32F1xx_hal_tim.h的1877行   htim2参数可从tim.c的27行看出		&为取地址符号,用来取一个变量的地址		
																			//进入中断后执行定时器回调函数HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)		任务3完成

  /* USER CODE END 2 */

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

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

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值