STM32开发——串口通讯(第1篇)——蓝牙(非中断+中断)

目录

1.串口简介

2.非中断接收发送字符

3.中断接收字符


1.串口简介

通过中断的方法接受串口工具发送的字符串,并将其发送回串口工具。

串口发送/接收函数:

  • HAL_UART_Transmit(); 串口发送数据,使用超时管理机制
  • HAL_UART_Receive(); 串口接收数据,使用超时管理机制
  • HAL_UART_Transmit_IT(); 串口中断模式发送 
  • HAL_UART_Receive_IT(); 串口中断模式接收
HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size, uint32_t Timeout)

作用:以阻塞的方式发送指定字节的数据
形参 1 :UART_HandleTypeDef 结构体类型指针变量
形参 2:指向要发送的数据地址(指针),(用数组时不用取地址)(用字符变量需要取地址&)
形参 3:要发送的数据大小,以字节为单位  strlen(ch)
形参 4:设置的超时时间,以ms单位,最大0xffff

HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart,uint8_t *pData, uint16_t Size)

作用:以中断的方式接收指定字节的数据
形参 1 是 UART_HandleTypeDef 结构体类型指针变量
形参 2 是指向接收数据缓冲区
形参 3 是要接收的数据大小,以字节为单位
此函数执行完后将清除中断,需要再次调用以重新开启中断。

串口中断回调函数:

  • HAL_UART_IRQHandler(UART_HandleTypeDef *huart); //串口中断处理函数
  • HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); //发送中断回调函数
  • HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); //接收中断回调函数

状态标记变量:
USART_RX_STA

从0开始,串口中断接收到一个数据(一个字节)就+1。当数据读取全部OK时候(回车和换行
符号来的时候),那么 USART_RX_STA的最高位置设置1。接收到0x0D(回车)设置第二位为1.

2.非中断接收发送字符

需求:
接受串口工具发送的字符串,并将其发送回串口工具。
硬件接线:
TX -- A10
RX -- A9

串口配置:
1. 选定串口

 2. 选择模式
异步通讯

 3. 串口配置

 4. 使用MicroLIB库
从魔术棒打开,这个勾勾一定要打上,否则 printf 无法重映射!

 编程实现:

#include <stdio.h>
#include <string.h>
unsigned char ch[20] = {0};
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
main函数里:
unsigned char ch[20] = {0};
HAL_UART_Transmit(&huart1, "hello world\n", strlen("hello world\n"), 100);
while(1)
{
HAL_UART_Receive(&huart1, ch, 19, 100);
//HAL_UART_Transmit(&huart1, ch, strlen(ch), 100);
printf(ch);
memset(ch, 0, strlen(ch));
}

3.中断接收字符

需求:
通过中断的方法接受串口工具发送的字符串,并将其发送回串口工具。

串口配置:
前4步同上
5. 打开中断

 编程实现:

#include <stdio.h>

uint8_t buf;
unsigned char ch[200] = {0};

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 100);
	return ch1;
}


//重写串口中断服务函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数据
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到过0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,开始下一次接收
					UART1_RX_STA|=0x8000;
				//如果这个数不是0x0a换行
				}else{
					//接收失败,数据清空
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到过0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状态为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不是0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
				}
	
			}
		}
		//重新开启串口中断接收
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}

//main函数中代码
//打开串口1接收中断  接收到的字符存在buf里,有一个字符 
HAL_UART_Receive_IT(&huart1, &buf, 1);

  while (1)
  {
    /* USER CODE END WHILE */
	
    /* USER CODE BEGIN 3 */
		//如果sta高位为1
		if((UART1_RX_STA & 0x8000)){
			//打印收到的数据,清空ch,情空sta
			printf("recevied word:");
			HAL_UART_Transmit(&huart1,ch,UART1_RX_STA & 0x3fff,0xffff);
			printf("\r\n");
			while(huart1.gState != HAL_UART_STATE_READY);
			//memset(ch,0,200);
			UART1_RX_STA=0;
		}
		printf("hello world.\r\n");
		HAL_Delay(1000);
		
  }

4.蓝牙插座_风扇_灯(非中断)

项目需求:通过蓝牙透传功能控制IO口

 非中断代码

#include "string.h"
#include "stdio.h"

int fputc(int ch1,FILE *f)
{
	unsigned char temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 0xffff);
	return ch1;
}

//main函数中代码
	char ch[10]={0};


	HAL_UART_Transmit(&huart1, (const uint8_t *)"hello world.", strlen("hello world."), 100);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		HAL_UART_Receive(&huart1,(uint8_t *)ch,10,100);  //不能用strlen(ch)其是有效字符 可以用sizeof数组大小
		printf("%s",ch);
		if(!strcmp((const char *)ch, "open")) {
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
			printf("led1已经打开.\r\n");
		}else if(!strcmp((const char *)ch, "close")) {
			HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
			printf("led1已经关闭.\r\n");			
		}else{
			if(ch[0]!='\0')
				printf("输出指令错误:%s,其strlen(%s)为%d sizeof(为) %d \r\n",ch,ch,strlen(ch),sizeof(ch));
		}
		memset(ch,0,10);
  }

5.蓝牙插座_风扇_灯(中断)

波特率:9600 
发送数据必须加换行符:open(enter)

#include "string.h"
#include "stdio.h"

uint8_t buf;
unsigned char ch[200] = {0};
uint16_t UART1_RX_STA=0;

int fputc(int ch1,FILE *f)
{
	uint8_t temp[1]={ch1};  //必须要用uint8_t承接,将int char变为uint8_t
	
	HAL_UART_Transmit(&huart1, temp, 1, 100);
	return ch1;
}


//重写串口中断服务函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//如果来自串口1的数捿
	if(huart->Instance==USART1){
		//如果没有接收完成
		if((UART1_RX_STA & 0x8000)==0){
			//如果已经收到迿0x0d回车
			if(UART1_RX_STA & 0x4000){
				//如果这个数是0x0a换行
				if(buf==0x0a){
					//,接收完成,弿始下丿次接政
					UART1_RX_STA|=0x8000;
				//如果这个数不昿0x0a换行
				}else{
					//接收失败,数据清穿
					UART1_RX_STA=0;
					//memset(ch,0,200);
				}
		
			//如果没有收到迿0x0d
			}else{
				//如果现在这个数是0x0d回车
				if(buf==0x0d){
					//状濁为标记改变为收到了0x0d
					UART1_RX_STA|=0x4000;
			//如果现在这个数不昿0x0d换行
				}else{
				//进行接收进入ch里面
					ch[UART1_RX_STA&0x3fff]=buf;
					UART1_RX_STA++;
				}
	
			}
		}
		//重新弿启串口中断接政
		HAL_UART_Receive_IT(&huart1, &buf,1);
	}
}

//main函数中代码
//在串口初始化后
	//打开串口1接收中断  接收到的字符存在buf里,有一个字? 
	HAL_UART_Receive_IT(&huart1, &buf, 1);

	HAL_UART_Transmit(&huart1, (uint8_t *)"hello world.", strlen("hello world."), 100);
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		//如果sta高位为1 ==受到带换行的数据 
		if((UART1_RX_STA & 0x8000)){
			//打印收到的数据,清空ch,请空sta
			printf("recevied word: \r\n");
			printf("%s",ch);
			if(!strcmp((const char *)ch,"open")){
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
			}else if(!strcmp((const char *)ch,"close")){
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
			}else{
				printf("输入错误。%s",ch);
			}
			UART1_RX_STA=0;
			memset(ch,0,200);
		}
		
		//printf("hello world.\r\n");
		HAL_Delay(10);
  }

  • 7
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是基于STM32F103和AS608指纹模块的串口打印代码示例: ``` #include "stm32f10x.h" #include "stdio.h" #include "string.h" #include "usart.h" #include "as608.h" //AS608指纹模块驱动库 char uart_buf[50]; //定义串口接收缓存 int main(void) { USART_Config(); //配置串口 AS608_Init(); //初始化AS608指纹模块 while (1) { if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) //判断是否有串口数据接收 { char c = USART_ReceiveData(USART1); //读取串口数据 if (c == '\n') //判断是否接收到换行符 { uart_buf[strlen(uart_buf) - 1] = '\0'; //将换行符替换为字符串结束符 printf("Received command: %s\r\n", uart_buf); //打印接收到的命令 memset(uart_buf, 0, sizeof(uart_buf)); //清空缓存 } else { strncat(uart_buf, &c, 1); //将接收到的字符添加到缓存中 } } if (AS608_ReceivePacket()) //判断是否接收到AS608指纹模块的数据包 { printf("Received packet: "); for (int i = 0; i < AS608.packet_len; i++) //打印数据包内容 { printf("%02x ", AS608.packet[i]); } printf("\r\n"); } } } ``` 在上述代码中,首先调用`USART_Config()`和`AS608_Init()`函数分别初始化串口和AS608指纹模块。然后在主循环中,不断检测串口是否接收到数据,并将接收到的数据添加到缓存中。当检测到换行符时,打印接收到的命令并清空缓存。同时,检测是否接收到AS608指纹模块的数据包,如果接收到,则打印数据包的内容。使用该代码,可以方便地调试和测试AS608指纹模块的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值