热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

STM32入坑(12)串口发送字节、半字、字、字符串、数组及实现串口控制

串口发送字节、半字、字、字符串、数组及实现串口控制简介串口的配置1.配置usart的TX和RX引脚2.配置串口模式3.配置串口的优先级(使用串口中断时)4.串口初始化编写发送函数发

串口发送字节、半字、字、字符串、数组及实现串口控制

  • 简介
  • 串口的配置
    • 1. 配置usart的TX和RX引脚
    • 2. 配置串口模式
    • 3.配置串口的优先级(使用串口中断时)
    • 4.串口初始化
  • 编写发送函数
    • 发送一个字节函数
    • 发送半字函数
    • 发送字函数
    • 发送字符串函数
    • 发送数组函数
  • 重新定向printf函数
  • 编写主函数
  • 注意事项
简介

串口通讯(Serial Communication)是一种设备间非常常用的串行通讯方式,因为它简单便捷,大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。

STM32的串口通信外设有USART和UART。USART是Universal Synchronous Asynchronous Receiver and Transmitter的缩写,即通用同步异步收发器可以灵活地与外部设备进行全双工数据交换。UART(Universal Asynchronous Receiver and Transmitter)在USART基础上裁减了同步通信功能,只有异步通信。

串口通过三个引脚从外部连接到其它设备,任何 USART 双向通信均需要至少两个引脚:接收数据输入引脚 (RX) 和发送数据输出 引脚(TX)。

串口的配置

1. 配置usart的TX和RX引脚

static void MyUsart_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //TX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //RX
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStruct);
}

这里配置的是:
TX—PA9;
RX—PA10

2. 配置串口模式

1.使能串口时钟
2.配置串口参数:
波特率(一般是9600或15200);
硬件控制流(一般是None);
模式(一般RX和TX都用);
奇偶校验(一般无);
停止位(一般为1);
字长(一般是8位);

static void MyUSART_Mode_Init(void)
{
USART_InitTypeDef USART_InitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

USART_InitStruct.USART_BaudRate = 9600;
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStruct.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_InitStruct.USART_Parity = USART_Parity_No;
USART_InitStruct.USART_StopBits = USART_StopBits_1;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART_InitStruct);
}

3.配置串口的优先级(使用串口中断时)

static void MyUSART_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStruct;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}

4.串口初始化

1.初始化串口引脚
2.初始化串口模式
3(配置串口优先级)
4.使能串口

void MyUSART_Init(void)
{
//初始化串口引脚
MyUsart_GPIO_Init();

//初始化串口模式
MyUSART_Mode_Init();

//使能串口
USART_Cmd(USART1,ENABLE);
}

经过以上步骤串口的配置就完成了,接下来就是编辑串口的发送字节、半字、字、字符串、数组函数了。

编写发送函数

当然了,以下函数可以根据具体要求来裁剪。

发送一个字节函数

void MyUSART_SendByte(uint8_t data)
{
USART_SendData(USART1, data);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

发送半字函数

void MyUSART_SendHalfWord(uint16_t data)
{
uint8_t data_h,data_l;
data_h = (data&0xff00)>>8;
data_l = data&0xff;
USART_SendData(USART1, data_h);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
USART_SendData(USART1, data_l);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

发送字函数

void MyUSART_SendWord(uint32_t data)
{
uint16_t data_h,data_l;
data_h = (data>>16)&0xffff;
data_l = data&0xffff;
MyUSART_SendHalfWord(data_h);
MyUSART_SendHalfWord(data_l);
// while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)!=RESET)
}

发送字符串函数

void MyUSART_SendStr(uint8_t *str)
{
uint8_t i=0;
do
{
MyUSART_SendByte(*(str+i));
i++;
}while(*(str+i)!='\0');
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); //判断是否发送完成
}

发送数组函数

void MyUSART_SendArr(uint8_t *str,uint8_t count)
{
uint8_t i=0;
for(;i<count;i++)
{
MyUSART_SendByte(*(str+i));
}
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
}
重新定向printf函数

如果需要使用printf函数、putchar函数、getchar函数,则必须重新定向fputc和fgetc函数。否则c语言中的输入输出语句不能使用。

int fputc(int ch,FILE *f)
{
USART_SendData(USART1, (uint8_t)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return(ch);
}
int fgetc(FILE *f)
{
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET);
return((int)USART_ReceiveData(USART1));
}
编写主函数

int main()
{
uint32_t a='我';
uint8_t b[5]={ 1,2,3,4,5};
uint8_t c[22]="单片机工程师\r\n";
LED_Init();
MyUSART_Init();
MyUSART_SendByte(0x61); //发送一个字节a
MyUSART_SendHalfWord(0x6263); //发送两个字节ab
MyUSART_SendWord(a); //发送字
MyUSART_SendStr((unsigned char*)"单片机"); //发送字符串
MyUSART_SendArr(b,5); //发送数组
printf(c); //发送字符串
putchar('n'); //输出一个字节
while(1) //实现串口控制,输入‘1’控制LED亮灭。
{
uint8_t ch;
ch = getchar();
if(ch=='1')LED0=!LED0;
}
}

运行的结果如下:
《STM32入坑(12)串口发送字节、半字、字、字符串、数组及实现串口控制》
结果分析:
MyUSART_SendByte(0x61); 输出结果:a
MyUSART_SendHalfWord(0x6263); 输出结果:bc
MyUSART_SendWord(a); 输出结果:我
MyUSART_SendStr((unsigned char*)“单片机”);输出结果:单片机
MyUSART_SendArr(b,5);输出结果:为一个数组,结果要在串口调试助手上勾选“16进制显示”,如下图
《STM32入坑(12)串口发送字节、半字、字、字符串、数组及实现串口控制》
printf©;输出结果:单片机工程师
putchar(‘n’);输出结果:n
while循环中不断扫描输入的数据,如果是‘1’,则点亮或熄灭LED灯。

注意事项
  1. 发送字节、半字、全字的时候,如果输入的16进制数大于128(十进制计算)会显示“?”。例如0X9797,97的十进制151,查询ask码表应该是ù,但实际中会显示“?”。查阅c语言书籍,有个小注:000-127是标准的,128-255是扩展的。难道扩展的不能显示吗?有懂的请告知,谢了。
  2. 使用串口时一定要在魔术棒的Target中勾选“USE Micro LIB”。

程序已经过调试验证,可正常输出,串口可控制LED
完整代码传送门:
https://download.csdn.net/download/m0_46195580/13773217


推荐阅读
  • 海马s5近光灯能否直接更换为H7?
    本文主要介绍了海马s5车型的近光灯是否可以直接更换为H7灯泡,并提供了完整的教程下载地址。此外,还详细讲解了DSP功能函数中的数据拷贝、数据填充和浮点数转换为定点数的相关内容。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 本文由编程笔记#小编整理,主要介绍了关于数论相关的知识,包括数论的算法和百度百科的链接。文章还介绍了欧几里得算法、辗转相除法、gcd、lcm和扩展欧几里得算法的使用方法。此外,文章还提到了数论在求解不定方程、模线性方程和乘法逆元方面的应用。摘要长度:184字。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
author-avatar
蜗蜗家的逆时针
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有