赞
踩
目录
一. 了解串口协议和RS-232标准,以及RS232电平与TTL电平的区别;了解"USB/TTL转232"模块(以CH340芯片模块为例)的工作原理
二. 安装 stm32CubeMX,配合Keil,使用寄存器方式(汇编或C,不限) 或HAL库这两种方式,完成下列任务:
三、重做上一个LED流水灯作业,即用GPIO端口完成3只LED红绿灯的周期闪烁。
点击System Core,进入里面的SYS,在debug那里选择Serial Wire
3.2.2 将system clock mux从HSI设为PLLOCK
3.2.3 右边选择要使用到的引脚,本文主要选择PA12,PB1,和PC14,并点击GPIO_Output
3.2.4 接下来建立项目,输入项目名称和项目地址,在Toolchain/IDE选择MDK-ARM
3.2.5 进入code generate界面,选择生成初始化.c/.h文件,后面点击generate code
四、完成一个STM32的USART串口通讯程序(查询方式即可,暂不要求采用中断方式)
串口通信指串口按位(bit)发送和接收字节。尽管比特字节(byte)的串行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。串口通信协议是指规定了数据包的内容,内容包含了起始位、主体数据、校验位及停止位,双方需要约定一致的数据包格式才能正常收发数据的有关规范。在串口通信中,常用的协议包括RS-232、RS-422和RS-485。
RS232采用负逻辑电平,定义如下:
电平状态 | 电压 |
---|---|
0(space) | +3 ~ +15V |
1(mark) | -15 ~ -3V |
非法状态 | -3 ~ +3V |
输出 L: <=0.8V ; H:>=2.4V。
输入 L: <=1.2V ; H:=>2.0V
TTL器件输出低电平要小于0.8V,高电平要大于2.4V。输入,低于1.2V就认为是0,高于2.0就认为是1。于是TTL电平的输入低电平的噪声容限就只有(0.8-0)/2=0.4V,高电平的噪声容限为(5-2.4)/2=1.3V。
1.4 "USB/TTL转232"模块(以CH340芯片模块为例)的工作原理
TXD:发送端,一般表示为自己的发送端,正常通信必须接另一个设备的RXD。
RXD:接收端,一般表示为自己的接收端,正常通信必须接另一个设备的TXD。
正常通信时候本身的TXD永远接设备的RXD!
自收自发:正常通信时RXD接其他设备的TXD,因此如果要接收自己发送的数据顾名思义,也就是自己接收自己发送的数据,即自身的TXD直接连接到RXD,用来测试本身的发送和接收是否正常,是最快最简单的测试方法,当出现问题时首先做该测试确定是否产品故障。也称回环测试。
由于STM32CubeMX是Java实现的,需要安装jdk环境。
jdk官网下载链接:
Java Downloads | Oracle
此时关闭就是安装成功了。
下载地址:
STM32CubeMX - STM32Cube initialization code generator - STMicroelectronics
选择第三个Windows系统的就行。
安装过程如图所示。注意安装路径不要出现中文就行。
打开cubeMX,在help下选择manage
此处选择install now 第一个是本地下载 ,仅对于已有固件库的电脑。
接下来设置时钟RCC,在High Speed Clock选择Crystal/Ceramic Resonator
将GPIO output level选择high
GPIO output level:有low和high两种选择,一般选择low
GPIO mode:推挽输出和开漏输出两者模式,两者模式的区别在于推挽输出中1代表VCC,0表示GND;开漏输出中1代表高阻态,0代表GND。
GPIO Pull-up/Pull-down:输入需要上下拉,输出一般没有上下拉
Maxinum output speed:最大的输出速度,一般选择low就可以了。
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_SET);//PA12熄灯
- HAL_Delay(500);//延时0.5s
- HAL_GPIO_WritePin(GPIOA,GPIO_PIN_12,GPIO_PIN_RESET);//PA12亮灯
- HAL_Delay(500);//延时0.5s
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);//PB1熄灯
- HAL_Delay(500);//延时0.5s
- HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);//PB1亮灯
- HAL_Delay(500);//延时0.5s
-
- HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_SET);//PC14熄灯
- HAL_Delay(500);//延时0.5s
-
- HAL_GPIO_WritePin(GPIOC,GPIO_PIN_14,GPIO_PIN_RESET);//PC14亮灯
- HAL_Delay(500);//延时0.5s
通电下将boot0置0,然后再次通电后可运行。
选择合适的芯片。
直接点OK
- ;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_AHBENR EQU (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_BASE EQU 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_BSRR EQU (GPIOA_BASE + 0x10)
- GPIOA_BRR EQU (GPIOA_BASE + 0x14)
- GPIOA_LCKR EQU (GPIOA_BASE + 0x18)
-
- ;GPIO C口控制
- GPIOC_BASE EQU 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_BSRR EQU (GPIOC_BASE + 0x10)
- GPIOC_BRR EQU (GPIOC_BASE + 0x14)
- GPIOC_LCKR EQU (GPIOC_BASE + 0x18)
-
- ;串口1控制
- USART1_BASE EQU 0x40013800
- USART1_SR EQU (USART1_BASE + 0x00)
- USART1_DR EQU (USART1_BASE + 0x04)
- USART1_BRR EQU (USART1_BASE + 0x08)
- USART1_CR1 EQU (USART1_BASE + 0x0c)
- USART1_CR2 EQU (USART1_BASE + 0x10)
- USART1_CR3 EQU (USART1_BASE + 0x14)
- USART1_GTPR EQU (USART1_BASE + 0x18)
-
- ;NVIC寄存器地址
- NVIC_BASE EQU 0xE000E000
- NVIC_SETEN EQU (NVIC_BASE + 0x0010)
- ;SETENA寄存器阵列的起始地址
- NVIC_IRQPRI EQU (NVIC_BASE + 0x0400)
- ;中断优先级寄存器阵列的起始地址
- NVIC_VECTTBL EQU (NVIC_BASE + 0x0D08)
- ;向量表偏移寄存器的地址
- NVIC_AIRCR EQU (NVIC_BASE + 0x0D0C)
- ;应用程序中断及复位控制寄存器的地址
- SETENA0 EQU 0xE000E100
- SETENA1 EQU 0xE000E104
-
-
- ;SysTick寄存器地址
- SysTick_BASE EQU 0xE000E010
- SYSTICKCSR EQU (SysTick_BASE + 0x00)
- SYSTICKRVR EQU (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
- ;位带别名区起始地址
- Flag1 EQU 0x20000200
- b_flas EQU (BitAlias_BASE + (0x200*32) + (0*4))
- ;位地址
- b_05s EQU (BitAlias_BASE + (0x200*32) + (1*4))
- ;位地址
- DlyI EQU 0x20000204
- DlyJ EQU 0x20000208
- DlyK EQU 0x2000020C
- SysTim EQU 0x20000210
-
-
- ;常数定义
- Bit0 EQU 0x00000001
- Bit1 EQU 0x00000002
- Bit2 EQU 0x00000004
- Bit3 EQU 0x00000008
- Bit4 EQU 0x00000010
- Bit5 EQU 0x00000020
- Bit6 EQU 0x00000040
- Bit7 EQU 0x00000080
- Bit8 EQU 0x00000100
- Bit9 EQU 0x00000200
- Bit10 EQU 0x00000400
- Bit11 EQU 0x00000800
- Bit12 EQU 0x00001000
- Bit13 EQU 0x00002000
- Bit14 EQU 0x00004000
- Bit15 EQU 0x00008000
- Bit16 EQU 0x00010000
- Bit17 EQU 0x00020000
- Bit18 EQU 0x00040000
- Bit19 EQU 0x00080000
- Bit20 EQU 0x00100000
- Bit21 EQU 0x00200000
- Bit22 EQU 0x00400000
- Bit23 EQU 0x00800000
- Bit24 EQU 0x01000000
- Bit25 EQU 0x02000000
- Bit26 EQU 0x04000000
- Bit27 EQU 0x08000000
- Bit28 EQU 0x10000000
- Bit29 EQU 0x20000000
- Bit30 EQU 0x40000000
- Bit31 EQU 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]
-
-
- ;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]
-
- ;切换成用户级线程序模式
- 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]
-
- mov r0, #'H'
- bl send_a_char
-
- mov r0, #'e'
- bl send_a_char
-
- mov r0, #'l'
- bl send_a_char
-
- mov r0, #'l'
- bl send_a_char
-
- mov r0, #'o'
- bl send_a_char
-
- mov r0, #' '
- bl send_a_char
-
- mov r0, #'W'
- bl send_a_char
-
- mov r0, #'o'
- bl send_a_char
-
- mov r0, #'r'
- bl send_a_char
-
- mov r0, #'l'
- bl send_a_char
-
- mov r0, #'d'
- bl send_a_char
-
- mov r0, #'\n'
- bl send_a_char
-
- b main
-
-
-
- ;子程序 串口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}
- bx lr
-
- ;异常程序
- NMI_Handler
- bx lr
-
-
- HardFault_Handler
- bx lr
-
- 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
- bx lr
-
- ALIGN
- ;通过用零或空指令NOP填充,来使当前位置与一个指定的边界对齐
- END
此时是在boot0为1情况下烧录。首先先用mcuisp将hex文件烧入stm32芯片,再打开串口调试助手,首先打开刚刚生成的hex文件,再点击发送文件,波特率默认是115200,1位停止位,无校验位。接着将boot0置0,点击reset即可接收到hello world。
进入调试模式,并打开逻辑分析功能,选择setup,创建引脚。
举例:第12各引脚对应 1 0000 0000 0000 对应十六进制0x00001000
设置引脚名称和展示数据类型为bit
可以看出三个引脚在周期为0.5s交替出现,从而实现流水灯的闪烁
环境配置与上述一致
不同点:
设置引脚为USART1_SR
观测波形
可以看出烧录的hello world程序的周期为0.5s,每相隔0.5s电平就会变化,从而周期性的输出
通过使用STMCubeMX简化实验过程,因为它能生成一些代码。然后可以根据波形来判断自己的代码是否有问题,对于解决问题有很大帮助。
搭建STM32开发环境——STM32CubeMX,Keil5_Harriet的博客-CSDN博客
搭建STM32开发环境——STM32CubeMX,Keil5
STM32实现LED闪烁——基于HAL库_Harriet的博客-CSDN博客_stm32实现led灯的闪烁
STM32实现LED闪烁——基于HAL库
基于 MDK 创建 STM32 汇编程序:串口输出 Hello world_ssj925319的博客-CSDN博客
基于 MDK 创建 STM32 汇编程序:串口输出 Hello world
STM32最小核心板F103串口通信USART_vic_to_ry的博客-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。