记录7——学习stm32之实现轮询方式、中断方式及简单帧格式串口通信

目录

  • 一.轮询方式
    • 任务
    • 代码实现
  • 二.中断方式
    • 任务
    • 代码实现
  • 三. 简单的帧格式
    • 任务
    • 代码实现

一.轮询方式

轮询方式就是不断去访问一个信号的端口,看看有没有信号进入,有则进行处理。

任务

通过任务轮询方式,利用串口调试助手发送字符,若发送‘y’,则在调试助手上显示‘Received
y!‘,且LED亮;若发送’n’,则在调试助手上显示’Received
n!',LED灭;若发送其他字符,则在调试助手上显示‘Received others!’

代码实现

/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */

printf、scanf函数重定向


int fputc(int ch,FILE *f)
{
	HAL_UART_Transmit (&huart2 ,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}

int fgetc(FILE *f)
{
	uint8_t ch;
	HAL_UART_Receive (&huart2 ,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}


/* USER CODE BEGIN PV */
uint8_t RecDate;//接收缓冲区

/* USER CODE END PV */
/* USER CODE BEGIN 2 */
	printf ("UART Retarget:\r\n");
  /* USER CODE END 2 */

while中写入

if(scanf("%c",&RecDate )==1)
		{
			if(RecDate =='y')
			{
				printf ("Received y!\r\n");
				HAL_GPIO_WritePin (GPIOC ,GPIO_PIN_13,GPIO_PIN_RESET );
			}
			else if(RecDate =='n')
			{
				printf ("Received n!\r\n");
				HAL_GPIO_WritePin (GPIOC ,GPIO_PIN_13,GPIO_PIN_SET );
			}
			else
			{
				printf ("Received others!\r\n");
			}
		}

二.中断方式

中断方式则是当输入产生的时候,产生一个触发信号告诉 STM32 有输入信号进入,需要进行处理。

任务

利用中断方式,实现定长数据的收发。

代码实现

/* USER CODE BEGIN PD */
#define LENGTH 10
/* USER CODE END PD */

/* USER CODE BEGIN PV */
uint8_t RxBuffer[LENGTH];
uint8_t RxFlag = 0;//接收完成标志
/* USER CODE END PV */
/* USER CODE BEGIN 2 */
	printf("Please enter 10 characters:\r\n");
	HAL_UART_Receive_IT(&huart2 ,(uint8_t*)RxBuffer ,LENGTH);

  /* USER CODE END 2 */
/* USER CODE BEGIN 3 */
		if(RxFlag == 1)
		{
			RxFlag=0;
			printf ("Recevie!");
			HAL_UART_Transmit_IT(&huart2 ,(uint8_t*)RxBuffer ,LENGTH);
		}
  
  /* USER CODE END 3 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART2)
	{
		RxFlag = 1;
		HAL_UART_Receive_IT(&huart2 ,(uint8_t*)RxBuffer ,LENGTH);
	}
}

三. 简单的帧格式

帧格式的组成:帧头 设备码 功能码 帧尾

任务

利用简单帧格式,当发送aa 01 01 55时,点亮LED灯,当发送aa 01 00 55时,熄灭LED灯。

代码实现

/* USER CODE BEGIN PV */
uint8_t RxBuffer[4];//接收缓冲区
uint8_t RxFlag=0;//接收完成标志:0--接收未完成;1--接收完成
uint8_t ErrFlag=0;//指令错误标志:0--指令正确;1--指令错误

/* USER CODE END PV */
/* USER CODE BEGIN 2 */
	printf ("********************\r\n");
	printf ("head->0xaa,device->0x01,operation->0x00/0x01,tail->0x55\r\n");
	HAL_UART_Receive_IT(&huart2 ,(uint8_t*)RxBuffer ,4);//使能接收中断

  /* USER CODE END 2 */
    /* USER CODE BEGIN 3 */
		if(RxFlag == 1)
		{
			RxFlag = 0;//清除标志位
			if(RxBuffer[0] == 0xaa && RxBuffer[3] == 0x55 )//判断帧头帧尾
			{
				if(RxBuffer[1] == 0x01)//判断设备码
				{
					if(RxBuffer[2] == 0x01) //判断功能码
					{
						HAL_GPIO_WritePin (GPIOC,GPIO_PIN_13,GPIO_PIN_RESET);
						printf ("open!\r\n");
					}
					else if (RxBuffer[2] == 0x00) 
					{
						HAL_GPIO_WritePin (GPIOC,GPIO_PIN_13,GPIO_PIN_SET);
						printf ("close!\r\n");
					}
					else ErrFlag = 1;//功能码错误,置位错误标志(else只和最近的if进行对应噢!)
				}
				else ErrFlag = 1;//设备码错误,置位错误标志
			}
			else ErrFlag = 1;//帧头、尾错误,置位错误标志

			if(ErrFlag == 1)
			{
				printf ("Wrong\r\n");
			}
			//清除接收缓冲区和错误标志,准备下一步接收
			RxBuffer [0] = 0;
			RxBuffer [1] = 0;
			RxBuffer [2] = 0;
			RxBuffer [3] = 0;
			RxFlag = 0;
			ErrFlag = 0;
		}
  }
  /* USER CODE END 3 */
/* USER CODE BEGIN 4 */
void  HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance==USART2)
	{
		RxFlag = 1;
		HAL_UART_Receive_IT(&huart2 ,(uint8_t*)RxBuffer ,4);
	}
}
int fputc (int ch,FILE *f)
{
	HAL_UART_Transmit (&huart2 ,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}

int fgetc(FILE *f)
{
	uint8_t ch;
	HAL_UART_Receive (&huart2 ,(uint8_t *)&ch,1,HAL_MAX_DELAY);
	return ch;
}

/* USER CODE END 4 */

你可能感兴趣的:(stm32f411CEU6,stm32,单片机,学习)