stm32串口通信入门
一. 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理。
串口协议是一种计算机通信协议,用于实现设备间的数据交换。它是一种比较古老但仍然广泛使用的通信方式,特别是在工业控制和嵌入式系统中。串口通信通常是指串行通信,与并行通信相对,数据是一位接一位按顺序传送的。
RS-232电平与TTL电平的主要区别在于它们的电压表示方式:
RS-232电平:使用较高的电压,通常在-3V到-15V之间表示逻辑“1”,在+3V到+15V之间表示逻辑“0”。这种高电压电平设计是为了在较长距离的通信中提供更好的抗噪声能力。
TTL电平:使用较低的电压,通常在0V到0.8V之间表示逻辑“0”,在2.0V到5V之间表示逻辑“1”。TTL电平主要用于集成电路内部,或电路板上的近距离通信。
由于RS-232和TTL电平不兼容,当需要在两种电平之间进行通信时,需要使用电平转换器进行转换。常见的电平转换器有MAX232等芯片,它们能够将TTL电平转换为RS-232电平,反之亦然。
二. 掌握TM32的标准库开发的基本方法;掌握UART串口通信程序开发基本方法(效率较低的查询方式)。
1、在上一次寄存器方式点亮LED灯的基础上,改用标准库方式,完成LED的点灯或流水灯实验。
#include "stm32f10x.h" // Device header
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启A口的时钟
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;//用的GPIO A的0号引脚
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_ResetBits(GPIOA,GPIO_Pin_0);//配置低电平,若只需要点亮LED灯就只执行此条命令。
while(1)
{
}
}
2、采用标准库的查询方式(暂不使用中断方式)完成以下要求:
1、STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
#include "stm32f10x.h"
#include "misc.h"
#include <string.h> // 包含 string.h 以使用 strlen
void USART_Configuration(void) {
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 打开GPIO与USART端口的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);
// 配置USART1 Tx (PA.09)为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置USART
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx;
USART_Init(USART1, &USART_InitStructure);
// 使能USART
USART_Cmd(USART1, ENABLE);
}
void Delay(__IO uint32_t nCount) { // 简单的延时函数
for(; nCount != 0; nCount--);
}
int main(void) {
SystemInit(); // 初始化系统时钟
USART_Configuration(); // 配置串口
char *str = "hello windows!\r\n"; // 添加换行符
while(1) {
for(uint32_t i = 0; i < strlen(str); i++) {
// 等待发送数据寄存器为空
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
// 发送一个字节数据到USART1
USART_SendData(USART1, str[i]);
}
// 延时
Delay(5000000); // 增加延时时间,以便观察效果
}
}
2、采用标准库的查询方式,完成以下要求:STM32以查询方式接收上位机(win10)串口发来的数据,如果接收到“Y”则点亮链接到stm32上的一个LED灯;接收到“N”则熄灭LED灯。
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
uint8_t RxData; //定义用于接收串口数据的变量
uint8_t Serial_RxData; //定义串口接收的数据变量
uint8_t Serial_RxFlag; //定义串口接收的标志位变量
void Serial_Init(void)
{
/*开启时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启USART1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟
/*GPIO初始化*/
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA9引脚初始化为复用推挽输出
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure); //将PA10引脚初始化为上拉输入
//使用GPIOA0引脚连接LED
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*USART初始化*/
USART_InitTypeDef USART_InitStructure; //定义结构体变量
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制,不需要
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //模式,发送模式和接收模式均选择
USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶校验,不需要
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长,选择8位
USART_Init(USART1, &USART_InitStructure); //将结构体变量交给USART_Init,配置USART1
/*USART使能*/
USART_Cmd(USART1, ENABLE); //使能USART1,串口开始运行
}
int main(void)
{
/*串口初始化*/
Serial_Init(); //串口初始化
GPIO_WriteBit(GPIOA,GPIO_Pin_6,Bit_SET);//将A6口初始化为电平
while (1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)
{
RxData=USART_ReceiveData(USART1);
if(RxData=='Y')
{GPIO_ResetBits(GPIOA,GPIO_Pin_0);}
if(RxData=='N')
{GPIO_SetBits(GPIOA,GPIO_Pin_0);}
}
}
}