目录
(1) 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别.
二. 掌握TM32的标准库开发的基本方法;掌握UART串口通信程序开发基本方法。
一.基本原理
(1) 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别.
A.串口协议
基本概念
串口协议是一种用于将数据以串行方式传输的通讯协议。它通过发送和接收数据位来进行通信,与并行通信不同,可以有效地减少通讯线路的数量和复杂度。串口协议在各种设备间通讯中都得到了广泛的应用。
串口协议的种类
常见的串口协议包括UART、USART、SPI、I2C等。UART(通用异步收发传输器)是最常见的串行通信协议之一,常被用于微控制器与外围设备的通信。USART(通用同步/异步收发传输器)在其基础上增加了同步通信功能,适用于较高速率的通信需求。SPI(串行外设接口)和I2C(串行外设接口)则是常用于片上系统内部通信的协议。
特点与应用
不同的串口协议具有各自的特点和适用场景。UART在短距离通信中应用广泛且成本低廉,而SPI和I2C在连接多个设备时具有优势。理解不同协议的特点和应用场景有助于更好地选择适合的通信方案。
串口协议的发展
随着科技的不断进步,串口协议也在不断发展和演变。现代串口协议通常具有更高的数据传输速率、更低的功耗、更小的接口尺寸等特点,以适应各种复杂的通信需求。
最新发展
最新的串口协议不仅注重数据传输速率和稳定性,还更加关注通讯安全性、抗干扰能力和通讯距离等方面的提升。例如,在工业控制、智能家居、物联网等领域,新的串口协议不断涌现,为各种应用场景提供了更好的解决方案。
未来展望
未来,串口协议可能会继续朝着更高的速率、更低的功耗、更强的抗干扰能力等方向发展。同时,在智能化、自动化方面的需求不断增长下,新的串口协议可能会更加注重与其他通信协议的兼容性,以实现更灵活、高效的通信方式。
B.RS-232标准
RS232串口标准简介
RS232是一种标准的串行通信接口,用于在数据终端设备之间进行数据传输。它最初由美国电子工业协会(EIA)制定,用于连接调制解调器、打印机、计算机等设备。RS232标准定义了接口的物理连接、电气特性和通信协议等方面规范,为不同设备间的互联提供了统一的标准。
RS232的物理连接
RS232接口通常采用DB9或DB25连接器,通过DB9连接器的9个引脚或DB25连接器的25个引脚进行数据传输。其中,引脚2和3分别用于发送数据(TXD)和接收数据(RXD),引脚5用于地线(GND)。除了这些基本引脚外,RS232还包括控制信号引脚,如数据就绪、数据终端就绪、清除发送数据等。
RS232的电气特性
RS232接口使用的是异步串行通信方式,传输数据时要求发送端和接收端具有相同的波特率、数据位、校验位和停止位等参数。另外,RS232的电平约定为逻辑1为-3V至-15V,逻辑0为+3V至+15V,这种双极性信号设计使得RS232接口具有较好的抗干扰能力。
RS232在工业控制领域的应用
作为一种稳定可靠的串口通信标准,RS232在工业控制领域有着广泛的应用。例如,工业自动化设备通过RS232接口与计算机或控制器进行数据交换,实现生产过程的监控、控制和数据采集。另外,各种工业仪器仪表也常常采用RS232接口与上位机进行通信,方便实时数据传输和配置调试等操作。
RS232在工业通信设备中的应用
许多工业通信设备,如工业级路由器、工业交换机、串口服务器等,都配备有RS232串口接口。这些设备常常用于连接传感器、执行机构、PLC等工业控制设备,通过RS232串口进行数据交换和控制指令的传输,实现智能化的工业控制和监控。
RS232在工业自动化设备中的应用
工业自动化设备中的控制器、人机界面、编程器等设备通常配备RS232接口,用于与计算机或工控设备进行数据交换。通过RS232接口,这些设备可以方便地实现程序下载、参数设置、实时监控等功能,是工业自动化领域的重要通信方式。
RS232标准的未来发展
随着现代通信技术的不断发展,传统的RS232串口标准逐渐面临着被USB、Ethernet等新一代通信接口所取代的挑战。但同时,由于RS232接口的成本低廉、稳定可靠,以及传统设备大量采用RS232接口,因此RS232标准仍然在许多应用中广泛存在。
RS232在传统设备中的应用
许多传统设备,如老式仪器仪表、工控设备等,仍然使用RS232串口作为数据通信接口。为了兼容这些设备并延长其使用寿命,许多现代设备依然需要配备RS232接口进行数据交换。因此,即使出现了新的通信接口标准,RS232标准仍将在传统设备中长期存在。
RS232的延伸应用
随着科技的不断发展,人们对数据通信的需求也在不断增加。在一些特殊领域,如军事、航空航天、能源等,对数据通信的稳定性和可靠性提出了更高的要求。因此,基于RS232标准的延伸应用,如RS422、RS485等更强大的串口标准,也在逐渐兴起,并得到了一定程度的应用和发展。
C.RS232电平与TTL电平
什么是TTL电平?
TTL(Transistor-Transistor Logic)电平是一种数字电平标准,代表了逻辑值0和逻辑值1。TTL电平中,0通常被定义为0V至0.8V之间的电压,而1被定义为2V至5V之间的电压。
特点
TTL电平具有高噪声抗干扰能力、低功耗和简单的电路设计特点。
应用
TTL电平常用于数字电路、微处理器和微控制器等领域。
什么是RS-232电平?
RS-232电平是一种标准用于串行通信的电平表示方法,它表示逻辑值0和逻辑值1的方式与TTL电平有所不同。
特点
RS-232电平通常采用负逻辑,即逻辑值1使用负电平表示,逻辑值0使用正电平表示。
应用
RS-232电平常用于计算机串口、通信设备、工业控制系统等领域。
TTL电平和RS-232电平的区别
电平表示方式
首先,最重要的区别在于它们表示逻辑值0和逻辑值1的方式。TTL电平使用电压高低来表示逻辑值,而RS-232电平使用正负电平表示。
应用领域
其次,TTL电平常用于数字电路、微处理器和微控制器,而RS-232电平常用于串行通信、计算机串口等领域。
(2)了解"USB/TTL转232"模块的工作原理。
我们以CH340芯片模块为例,分析其工作原理.
CH340 是一个USB 总线的转接芯片,实现USB 转串口、USB 转IrDA 红外或者USB 转打印口。为了增加串口通讯的远距离传输及抗干扰能力,RS-232标准使用-15V 表示逻辑 1, +15V 表示逻辑 0。常常会使用 MH340芯片对 USB/TTL与RS-232电平的信号进行转换。
CH340芯片在单片机上的参考电路:
注意事项
1.CH340模块插在USB2.0口时,5V排针输出口电流只有500MA左右,如过要接的功率比较的大模块建议接USB3.0或者给大功率模块单独外接电源且共地。
2. 切勿将VCC与GND短接,否则会烧坏模块,发现插上后模块灯不亮货模块发烫严重请立即拔掉检测是否接反或短路。
3.将模块TX、RX两个引脚短接,可以测试USB转TTL模块功能是否正常。
二. 掌握TM32的标准库开发的基本方法;掌握UART串口通信程序开发基本方法。
1、用标准库方式,完成LED的流水灯实验。
main.c代码如下
#include "stm32f10x.h" // Device header
#include "Delay.h"
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//??GPIOA???,????????
//??GPIOA
GPIO_InitTypeDef GPIO_InitStructure;//?????GPIO_InitStructure,GPIO_InitTypeDef????????,?Library??gpio.h????????
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//?????????
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_0;//??GPIOA?0123??
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//???????50MHZ
GPIO_Init(GPIOA, &GPIO_InitStructure);//GPIO_Init???GPIO???,???????????????,????
while (1)
{
GPIO_Write(GPIOA, ~0x0001); //16???2???,0000 0000 0000 0001,????,A0?????
Delay_ms(1000);//??1000ms,???1?
GPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010,????,,A1?????
Delay_ms(1000);
GPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100,????,,A2?????
Delay_ms(1000);
GPIO_Write(GPIOA, ~0x0008); //0000 0000 0000 1000,????,,A3?????
Delay_ms(1000);
}
}
实验结果:
2、采用标准库的查询方式(暂不使用中断方式)完成以下要求:
1)设置波特率为9600,1位停止位,无校验位;
USART_InitStructure.USART_BaudRate = 9600; //波特率
USART_InitStructure.USART_Mode = USART_Mode_Tx; //模式,选择为发送模式
USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶校验,不需要
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位,选择1位
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长,选择8位
2)STM32系统给上位机(win10)连续发送“hello windows!”。win11采用“串口助手”工具接收。
Serial.c代码:
#include "stm32f10x.h" // Device header
#include <stdio.h>
#include <stdarg.h>
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引脚初始化为复用推挽输出
/*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_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,串口开始运行
}
void Serial_SendByte(uint8_t Byte)
{
USART_SendData(USART1, Byte); //将字节数据写入数据寄存器,写入后USART自动生成时序波形
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); //等待发送完成
/*下次写入数据寄存器会自动清除发送完成标志位,故此循环后,无需清除标志位*/
}
void Serial_SendArray(uint8_t *Array, uint16_t Length)
{
uint16_t i;
for (i = 0; i < Length; i ++) //遍历数组
{
Serial_SendByte(Array[i]); //依次调用Serial_SendByte发送每个字节数据
}
}
void Serial_SendString(char *String)
{
uint8_t i;
for (i = 0; String[i] != '\0'; i ++)//遍历字符数组(字符串),遇到字符串结束标志位后停止
{
Serial_SendByte(String[i]); //依次调用Serial_SendByte发送每个字节数据
}
}
uint32_t Serial_Pow(uint32_t X, uint32_t Y)
{
uint32_t Result = 1; //设置结果初值为1
while (Y --) //执行Y次
{
Result *= X; //将X累乘到结果
}
return Result;
}
void Serial_SendNumber(uint32_t Number, uint8_t Length)
{
uint8_t i;
for (i = 0; i < Length; i ++) //根据数字长度遍历数字的每一位
{
Serial_SendByte(Number / Serial_Pow(10, Length - i - 1) % 10 + '0'); //依次调用Serial_SendByte发送每位数字
}
}
int fputc(int ch, FILE *f)
{
Serial_SendByte(ch); //将printf的底层重定向到自己的发送字节函数
return ch;
}
void Serial_Printf(char *format, ...)
{
char String[100]; //定义字符数组
va_list arg; //定义可变参数列表数据类型的变量arg
va_start(arg, format); //从format开始,接收参数列表到arg变量
vsprintf(String, format, arg); //使用vsprintf打印格式化字符串和参数列表到字符数组中
va_end(arg); //结束变量arg
Serial_SendString(String); //串口发送字符数组(字符串)
}
main.c代码:
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
int main(void)
{
/*模块初始化*/
//OLED_Init(); //OLED初始化
Serial_Init(); //串口初始化
//串口打印字符串,使用自己封装的函数实现printf的效果
while (1)
{
Serial_Printf("hello windows!");
Serial_Printf("\n");
Delay_s(1);
}
}
实验结果:
3、采用标准库的查询方式,完成以下要求:
STM32以查询方式接收上位机(win10)串口发来的数据,如果接收到“Y”则点亮链接到stm32上的一个LED灯;接收到“N”则熄灭LED灯。
main.c代码:
#include "stm32f10x.h"
#include "Delay.h"
int main(void)
{
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF_PP;
GPIO_Init(GPIOA,&GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
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_Mode=USART_Mode_Rx;
USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_Init(USART1, &USART_InitStructure);
USART_Cmd(USART1,ENABLE);
GPIO_WriteBit(GPIOA,GPIO_Pin_1,0);
while (1)
{
if(USART_GetFlagStatus(USART1, USART_IT_RXNE) == SET)
{
unsigned char a= USART_ReceiveData(USART1);
if(a=='N')
{
GPIO_WriteBit(GPIOA,GPIO_Pin_1,1);
}
else if(a=='Y')
{
GPIO_WriteBit(GPIOA,GPIO_Pin_1,0);
}
else
{
}
}
}
}
实验结果:
总结
通过这次实验,我逐渐了解了串口协议和RS-232标准,以及RS232电平与TTL电平的区别,也了解了"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理,渐渐掌握了TM32的标准库开发的基本方法以及掌握UART串口通信程序开发基本方法(效率较低的查询方式).