700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 基于STM32的USART串口通讯程序

基于STM32的USART串口通讯程序

时间:2021-03-28 16:28:27

相关推荐

基于STM32的USART串口通讯程序

文章目录

一、串口协议和RS-232、485标准,以及RS232、485电平与TTL电平的区别,USB/TTL转232模块的工作原理1.串口协议2.RS-232、RS-485标准3.RS232、485电平与TTL电平的区别4."USB/TTL转232"模块(以CH340芯片模块为例)的工作原理二、使用HAL库&寄存器完成3只LED红绿灯的周期闪烁三、使用HAL库串口输出"hello windows!"1.新建项目2.编写程序3.连接电路4.程序烧录5.串口调试6.运行结果7.观察串口输出波形四、用寄存器方式串口输出"hello windows!"1.新建项目2.编写程序3.连接电路4.程序烧录5.串口调试6.运行结果7.观察串口输出波形五、总结六、参考链接

一、串口协议和RS-232、485标准,以及RS232、485电平与TTL电平的区别,USB/TTL转232模块的工作原理

1.串口协议

串口通信指串口按位(bit)发送和接收字节。尽管比特字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括RS-232、RS-422和RS-485。

2.RS-232、RS-485标准

(1)RS-232标准

①介绍

RS-232-C是美国电子工业协会EIA(Electronic Industry Association)制定的一种串行物理接口标准。RS(Recommended Standard)是英文“推荐标准”的缩写,232为标识号,C表示修改次数。RS-232-C总线标准设有25条信号线,包括一个主通道和一个辅助通道。

RS-232-C标准规定,驱动器允许有2500pF的电容负载,通信距离将受此电容限制。例如,采用150pF/m的通信电缆时,最大通信距离为15m;若每米电缆的电容量减小,通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。

②电气特性

在TxD和RxD上:

逻辑“1”:-3V~-15V

逻辑“0”:+3~+15V

③信号和管脚定义

④设置

串行通信在软件设置里需要做多项设置,最常见的设置包括波特率(Baud Rate)、奇偶校验(Parity Check)和停止位(Stop Bit)。

1)波特率(Baud Rate):

是指从一设备发到另一设备的波特率,即每秒钟多少比特bits per second (bit/s)。典型的波特率是300, 1200, 2400, 9600, 19200, 115200 等bit/s。一般通信两端设备都要设为相同的波特率,但有些设备也可以设置为自动检测波特率。

2)奇偶校验(Parity Check):

是用来验证数据正确性的。奇偶校验一般不使用,如果使用,那么既可以做奇校验(Odd Parity)也可以做偶校验(Even Parity)。

3)停止位(Stop Bit):

是在每个字节数据传输之后发送的,它用来帮助接收信号方硬件重同步。

(2)RS-485标准

①介绍

电子工业协会(EIA)于 1983 年制订并发布 RS-485 标准,并经通讯工业协会(TIA)修订后命名为 TIA/EIA-485-A,习惯地称之为 RS-485 标准。

RS-485 标准是为弥补 RS-232 通信距离短、速率低等缺点而产生的。RS-485 标准只规定了平衡发送器和接收器的电特性,而没有规定接插件、传输电缆和应用层通信协议。

RS-485 标准通常被用作为一种相对经济、具有相当高噪声抑制、相对高的传输速率、传输距离远、宽共模范围的通信平台。同时,RS-485 电路具有控制方便、成本低廉等优点。

②性能

RS-485 标准的数据信号采用差分传输方式(Differential Driver Mode),也称作平衡传输,它使用一对双绞线,将其中一线定义为 A,另一线定义为 B。

通常情况下,发送发送器 A、B 之间的正电平在+2+6V,是一个逻辑状态;负电平在-2-6V,是另一个逻辑状态。另有一个信号地 C。在 RS-485 器件中,一般还有一个“使能”控制信号。“使能”信号用于控制发送发送器与传输线的切断与连接,当“使能”端起作用时,发送发送器处于高阻状态,称作“第三态”,它是有别于逻辑“1”与“0”的第三种状态。

对于接收发送器,也作出与发送发送器相对的规定,收、发端通过平衡双绞线将 A-A与 B-B 对应相连。当在接收端 A-B 之间有大于+200mV 的电平时,输出为正逻辑电平;小于-200mV 时,输出为负逻辑电平。在接收发送器的接收平衡线上,电平范围通常在 200mV至 6V 之间。

定义逻辑 1(正逻辑电平)为 B>A 的状态,逻辑 0(负逻辑电平)为 A>B 的状态,A、B 之间的压差不小于200mV。

TIA/EIA-485 串行通讯标准的性能如下表所示:

RS-485 标准的最大传输距离约为 1219 米,最大传输速率为 10Mbps。

通常,RS-485 网络采用平衡双绞线作为传输媒体。平衡双绞线的长度与传输速率成反比,只有在 20kbps 速率以下,才可能使用规定最长的电缆长度。只有在很短的距离下才能获得最高速率传输。一般来说,15 米长双绞线最大传输速率仅为 1Mbps。

注意:并不是所有的 RS-485 收发器都能够支持高达 10Mbps 的通讯速率。如果采用光电隔离方式,则通讯速率一般还会受到光电隔离器件响应速度的限制。

RS-485 网络采用直线拓朴结构,需要安装 2 个终端匹配电阻,其阻值要求等于传输电缆的特性阻抗(一般取值为 120Ω)。在矩距离、或低波特率数据传输时可不需终端匹配电阻,即一般在 300 米以下、19200bps 不需终端匹配电阻。终端匹配电阻安装在 RS-485 传输网络的两个端点,并联连接在 A-B 引脚之间。

3.RS232、485电平与TTL电平的区别

4."USB/TTL转232"模块(以CH340芯片模块为例)的工作原理

TXD:发送端,一般表示为自己的发送端,正常通信必须接另一个设备的RXD。

RXD:接收端,一般表示为自己的接收端,正常通信必须接另一个设备的TXD。

正常通信时候本身的TXD永远接设备的RXD!

自收自发:正常通信时RXD接其他设备的TXD,因此如果要接收自己发送的数据顾名思义,也就是自己接收自己发送的数据,即自身的TXD直接连接到RXD,用来测试本身的发送和接收是否正常,是最快最简单的测试方法,当出现问题时首先做该测试确定是否产品故障。也称回环测试。

电平逻辑:

TTL电平:通常数据表示采用二进制,规定+5V等价于逻辑“1”,0V等价于逻辑“0”,称作TTL信号系统,是正逻辑

RS232电平:采用-12V到-3V,等价于逻辑“0”,+3V到+12V的逻辑电平,等价于逻辑“1”,是负逻辑的。

二、使用HAL库&寄存器完成3只LED红绿灯的周期闪烁

参照上一篇博客使用HAL库&寄存器完成LED流水灯程序

三、使用HAL库串口输出"hello windows!"

1.新建项目

(1)打开STM32CubeMX主界面,点击“ACCESS TO MCU SELECTOR”,创建新项目

(2)在“Commerical Part Number”里面选择自己需要的芯片,点击信息栏中的具体芯片信息选中,再点击“Start Project”

(3)先点击System Core将其展开,再点击RCC,将HSE设置为Crystal/Ceramic Resonator

(4)先点击Connectivity将其展开,再点击USART1,将Mode设置为Asynchronous,然后点击Parameter Settings,设置波特率为115200,1位停止位,无校验位

(5)点击“Clock Configuration”,勾选PLLCLK和HSE,并将*PLLMul设置为×4

(6)点击Project Manager 配置好自己的项目名和项目存放路径,然后将Application Structure设置为Basic,将IDE设置为MDK-ARM

(7)点击Code Generate界面,选择生成初始化文件.c/.h,之后再点击GENERATE CODE即可成功创建项目

2.编写程序

(1)在点击GENERATE CODE之后弹出来的界面点击Open Project即可跳转到Keil5进行程序编写

(2)打开main.c文件,滑到主函数的while循环那一部分

(3)在main.c的while循环中添加如下代码:

char data[]="hello windows!\n";HAL_UART_Transmit(&huart1, (uint8_t *)data, 15, 0xffff);HAL_Delay(1000);

(4)编译程序并创建hex文件

3.连接电路

4.程序烧录

置BOOT0为0,BOOT1为1

(1)打开mcuisp,选择串口为COM5,并选择生成的Hello.hex文件

(2)点击读器件信息,若显示一切正常则进行下一步

(3)点击开始编程,若显示一切正常则说明烧录成功

5.串口调试

打开野火串口调试助手,将波特率设置为115200,数据位设置为8,停止位设置为1,校验位设置为None,然后点击打开串口

6.运行结果

7.观察串口输出波形

(1)先点击魔术棒,再点击Debug,进行如下设置:

(2)点击Start/Stop Debug Session进行调试

(3)选择逻辑分析仪

(4)点击Setup Logic Analyzer,然后添加自己需要观察引脚并将Display Type设置为Bit,设置完成后点击Close

(5)点击In/Out将Grid的大小调为1s,勾选Signal info和Cursor能设置显示起始线并能看到相关信息

(6)点击Run即可开始运行,运行一段时间后点击Stop停止运行并观察输出波形

由串口输出波形图及其显示的相关信息可知,时序状态正确。

四、用寄存器方式串口输出"hello windows!"

1.新建项目

(1)打开Keil5,点击Project,选择第一项新建工程,并设置好工程名和路径,不要有中文

(2)设置工程的目标环境,即选择芯片STM32F103C8,然后点击OK,将弹出来的页面直接叉掉

(3)点击“Add New Item to Group ‘Source Group1’”,添加一个.s文件,并设置好名称,我这里设置的是hello,然后选择路径,设置完成后点击Add

(4)点击魔术棒→Output→勾选Create HEX File→OK

2.编写程序

(1)在hello.s文件中写入如下代码:

;RCC寄存器地址映像 RCC_BASE EQU 0x40021000 RCC_CR EQU (RCC_BASE + 0x00) RCC_CFGR EQU (RCC_BASE + 0x04) RCC_CIR EQU (RCC_BASE + 0x08) RCC_APB2RSTR EQU (RCC_BASE + 0x0C) RCC_APB1RSTR EQU (RCC_BASE + 0x10) RCC_AHBENREQU (RCC_BASE + 0x14) RCC_APB2ENR EQU (RCC_BASE + 0x18) RCC_APB1ENR EQU (RCC_BASE + 0x1C) RCC_BDCR EQU (RCC_BASE + 0x20) RCC_CSR EQU (RCC_BASE + 0x24) ;AFIO寄存器地址映像 AFIO_BASE EQU 0x40010000 AFIO_EVCR EQU (AFIO_BASE + 0x00) AFIO_MAPR EQU (AFIO_BASE + 0x04) AFIO_EXTICR1 EQU (AFIO_BASE + 0x08) AFIO_EXTICR2 EQU (AFIO_BASE + 0x0C) AFIO_EXTICR3 EQU (AFIO_BASE + 0x10) AFIO_EXTICR4 EQU (AFIO_BASE + 0x14) ;GPIOA寄存器地址映像 GPIOA_BASEEQU 0x40010800 GPIOA_CRL EQU (GPIOA_BASE + 0x00) GPIOA_CRH EQU (GPIOA_BASE + 0x04) GPIOA_IDR EQU (GPIOA_BASE + 0x08) GPIOA_ODR EQU (GPIOA_BASE + 0x0C) GPIOA_BSRREQU (GPIOA_BASE + 0x10) GPIOA_BRR EQU (GPIOA_BASE + 0x14) GPIOA_LCKREQU (GPIOA_BASE + 0x18) ;GPIO C口控制 GPIOC_BASEEQU 0x40011000 GPIOC_CRL EQU (GPIOC_BASE + 0x00) GPIOC_CRH EQU (GPIOC_BASE + 0x04) GPIOC_IDR EQU (GPIOC_BASE + 0x08) GPIOC_ODR EQU (GPIOC_BASE + 0x0C) GPIOC_BSRREQU (GPIOC_BASE + 0x10) GPIOC_BRR EQU (GPIOC_BASE + 0x14) GPIOC_LCKREQU (GPIOC_BASE + 0x18) ;串口1控制 USART1_BASE EQU 0x40013800 USART1_SR EQU (USART1_BASE + 0x00) USART1_DR EQU (USART1_BASE + 0x04) USART1_BRREQU (USART1_BASE + 0x08) USART1_CR1EQU (USART1_BASE + 0x0c) USART1_CR2EQU (USART1_BASE + 0x10) USART1_CR3EQU (USART1_BASE + 0x14) USART1_GTPR EQU (USART1_BASE + 0x18) ;NVIC寄存器地址NVIC_BASE EQU 0xE000E000 NVIC_SETENEQU (NVIC_BASE + 0x0010);SETENA寄存器阵列的起始地址 NVIC_IRQPRI EQU (NVIC_BASE + 0x0400);中断优先级寄存器阵列的起始地址 NVIC_VECTTBL EQU (NVIC_BASE + 0x0D08);向量表偏移寄存器的地址NVIC_AIRCREQU (NVIC_BASE + 0x0D0C);应用程序中断及复位控制寄存器的地址 SETENA0 EQU 0xE000E100 SETENA1 EQU 0xE000E104 ;SysTick寄存器地址 SysTick_BASE EQU 0xE000E010 SYSTICKCSREQU (SysTick_BASE + 0x00) SYSTICKRVREQU (SysTick_BASE + 0x04) ;FLASH缓冲寄存器地址映像FLASH_ACR EQU 0x40022000 ;SCB_BASE EQU (SCS_BASE + 0x0D00) MSP_TOP EQU 0x20005000;主堆栈起始值PSP_TOP EQU 0x20004E00;进程堆栈起始值 BitAlias_BASE EQU 0x22000000;位带别名区起始地址 Flag1EQU 0x20000200 b_flas EQU (BitAlias_BASE + (0x200*32) + (0*4));位地址 b_05sEQU (BitAlias_BASE + (0x200*32) + (1*4));位地址 DlyIEQU 0x20000204 DlyJEQU 0x20000208 DlyKEQU 0x2000020C SysTim EQU 0x20000210 ;常数定义 Bit0EQU 0x00000001 Bit1EQU 0x00000002 Bit2EQU 0x00000004 Bit3EQU 0x00000008 Bit4EQU 0x00000010 Bit5EQU 0x00000020 Bit6EQU 0x00000040 Bit7EQU 0x00000080 Bit8EQU 0x00000100 Bit9EQU 0x00000200 Bit10EQU 0x00000400 Bit11EQU 0x00000800 Bit12EQU 0x00001000 Bit13EQU 0x00002000 Bit14EQU 0x00004000 Bit15EQU 0x00008000 Bit16EQU 0x00010000 Bit17EQU 0x00020000 Bit18EQU 0x00040000 Bit19EQU 0x00080000 Bit20EQU 0x00100000 Bit21EQU 0x00200000 Bit22EQU 0x00400000 Bit23EQU 0x00800000 Bit24EQU 0x01000000 Bit25EQU 0x02000000 Bit26EQU 0x04000000 Bit27EQU 0x08000000 Bit28EQU 0x10000000 Bit29EQU 0x20000000 Bit30EQU 0x40000000 Bit31EQU 0x80000000 ;向量表 AREA RESET, DATA, READONLY DCD MSP_TOP ;初始化主堆栈 DCD Start ;复位向量 DCD NMI_Handler ;NMI Handler DCD HardFault_Handler ;Hard Fault Handler DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD 0 DCD SysTick_Handler ;SysTick Handler SPACE 20 ;预留空间20字节 ;代码段 AREA |.text|, CODE, READONLY ;主程序开始 ENTRY ;指示程序从这里开始执行 Start ;时钟系统设置 ldr r0, =RCC_CR ldr r1, [r0] orr r1, #Bit16 str r1, [r0] ;开启外部晶振使能 ;启动外部8M晶振 ClkOk ldr r1, [r0] ands r1, #Bit17 beq ClkOk ;等待外部晶振就绪 ldr r1,[r0] orr r1,#Bit17 str r1,[r0] ;FLASH缓冲器 ldr r0, =FLASH_ACR mov r1, #0x00000032 str r1, [r0] ;设置PLL锁相环倍率为7,HSE输入不分频 ldr r0, =RCC_CFGR ldr r1, [r0] orr r1, #(Bit18 :OR: Bit19 :OR: Bit20 :OR: Bit16 :OR: Bit14) orr r1, #Bit10 str r1, [r0] ;启动PLL锁相环 ldr r0, =RCC_CR ldr r1, [r0] orr r1, #Bit24 str r1, [r0] PllOk ldr r1, [r0] ands r1, #Bit25 beq PllOk ;选择PLL时钟作为系统时钟 ldr r0, =RCC_CFGR ldr r1, [r0] orr r1, #(Bit18 :OR: Bit19 :OR: Bit20 :OR: Bit16 :OR: Bit14) orr r1, #Bit10 orr r1, #Bit1 str r1, [r0] ;其它RCC相关设置 ldr r0, =RCC_APB2ENR mov r1, #(Bit14 :OR: Bit4 :OR: Bit2) str r1, [r0];IO端口设置 ldr r0, =GPIOC_CRL ldr r1, [r0] orr r1, #(Bit28 :OR: Bit29);PC.7输出模式,最大速度50MHz and r1, #(~Bit30 & ~Bit31) ;PC.7通用推挽输出模式 str r1, [r0] ;PA9串口0发射脚 ldr r0, =GPIOA_CRH ldr r1, [r0] orr r1, #(Bit4 :OR: Bit5);PA.9输出模式,最大速度50MHz orr r1, #Bit7 and r1, #~Bit6 ;10:复用功能推挽输出模式 str r1, [r0] ldr r0, =USART1_BRR mov r1, #0x271 str r1, [r0] ;配置波特率-> 115200 ldr r0, =USART1_CR1 mov r1, #0x200c str r1, [r0] ;USART模块总使能 发送与接收使能 ;71 02 00 00 2c 20 00 00 ;AFIO 参数设置 ;Systick 参数设置 ldr r0, =SYSTICKRVR ;Systick装初值 mov r1, #9000 str r1, [r0] ldr r0, =SYSTICKCSR ;设定,启动Systick mov r1, #0x03 str r1, [r0] ;NVIC ;ldr r0, =SETENA0 ;mov r1, 0x00800000 ;str r1, [r0] ;ldr r0, =SETENA1 ;mov r1, #0x00000100 ;str r1, [r0] ;切换成用户级线程序模式 ldr r0, =PSP_TOP ;初始化线程堆栈 msr psp, r0 mov r0, #3 msr control, r0 ;初始化SRAM寄存器 mov r1, #0 ldr r0, =Flag1 str r1, [r0] ldr r0, =DlyI str r1, [r0] ldr r0, =DlyJ str r1, [r0] ldr r0, =DlyK str r1, [r0] ldr r0, =SysTim str r1, [r0] ;主循环 main ldr r0, =Flag1 ldr r1, [r0] tst r1, #Bit1 ;SysTick产生0.5s,置位bit 1 beq main ;0.5s标志还没有置位 ;0.5s标志已经置位 ldr r0, =b_05s;位带操作清零0.5s标志 mov r1, #0 str r1, [r0] blLedFlas mov r0, #'H' blsend_a_charmov r0, #'e' blsend_a_charmov r0, #'l' blsend_a_charmov r0, #'l' blsend_a_charmov r0, #'o' blsend_a_charmov r0, #' ' blsend_a_charmov r0, #'w' blsend_a_charmov r0, #'i' blsend_a_charmov r0, #'n' blsend_a_charmov r0, #'d' blsend_a_charmov r0, #'o' blsend_a_charmov r0, #'w' blsend_a_charmov r0, #'s' blsend_a_charmov r0, #'!' blsend_a_charmov r0, #'\n' blsend_a_charbmain;子程序 串口1发送一个字符 send_a_char push {r0 - r3} ldr r2, =USART1_DR str r0, [r2] b1 ldr r2, =USART1_SR ldr r2, [r2] tst r2, #0x40 beq b1 ;发送完成(Transmission complete)等待 pop {r0 - r3} bxlr ;子程序 led闪烁 LedFlaspush {r0 - r3} ldr r0, =Flag1 ldr r1, [r0] tst r1, #Bit0 ;bit0 闪烁标志位 beq ONLED ;为0 打开led灯 ;为1 关闭led灯 ldr r0, =b_flas mov r1, #0 str r1, [r0] ;闪烁标志位置为0,下一状态为打开灯 ;PC.7输出0 ldr r0, =GPIOC_BRR ldr r1, [r0] orr r1, #Bit7 str r1, [r0] bLedEx ONLED ;为0 打开led灯 ldr r0, =b_flas mov r1, #1 str r1, [r0] ;闪烁标志位置为1,下一状态为关闭灯 ;PC.7输出1 ldr r0, =GPIOC_BSRR ldr r1, [r0] orr r1, #Bit7 str r1, [r0] LedEx pop {r0 - r3} bxlr ;异常程序 NMI_Handler bxlr HardFault_Handler bxlr SysTick_Handler ldr r0, =SysTim ldr r1, [r0] add r1, #1 str r1, [r0] cmp r1, #500 bcc TickExit mov r1, #0 str r1, [r0] ldr r0, =b_05s ;大于等于500次 清零时钟滴答计数器 设置0.5s标志位 ;位带操作置1 mov r1, #1 str r1, [r0] TickExit bxlr ALIGN ;通过用零或空指令NOP填充,来使当前位置与一个指定的边界对齐 END

(2)编译程序并创建hex文件

3.连接电路

电路连接与使用HAL库串口输出"hello windows!"的连接方式完全一样

4.程序烧录

置BOOT0为0,BOOT1为1

(1)打开mcuisp,选择串口为COM5,并选择生成的hello.hex文件

(2)点击读器件信息,若显示一切正常则进行下一步

(3)点击开始编程,若显示一切正常则说明烧录成功

5.串口调试

打开野火串口调试助手,将波特率设置为115200,数据位设置为8,停止位设置为1,校验位设置为None,然后点击打开串口

6.运行结果

7.观察串口输出波形

相关参数设置与使用HAL库的方式相同,全部设置好后点击Run即可开始运行,运行一段时间后点击Stop停止运行并观察输出波形

由串口输出波形图及其显示的相关信息可知,时序状态正确。

五、总结

通过本次实验可以发现,使用用寄存器方式写比较复杂,要声明很多地址,语句也比较繁琐,而且还容易出现各种各样的错误;而使用HAL库只需要在主函数里写几句代码就可以实现,更方便,且不易出错。

六、参考链接

基于STM32F103C8的USART串口通讯程序

电平标准(RS232 \ RS485 \ TTL)对比

RS-485标准

串口协议和RS-232标准,以及RS232电平与TTL电平的区别,“USB/TTL转232“模块(以CH340芯片模块为例)的工作原理。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。