STM32串口通讯
1、基于寄存器与基于固件库编写的差别
固件库编写方式,特色是简单易于理解,资料多。新手适合用这种方式入门。
寄存器的可移植性强,更贴近底层,要求对外设的工做原理和运行机理有更深的理解。
编程
2、stm32串口通讯实战
1.烧录方式
我使用的是stm32f103指南者,从电脑中下载程序到stm32有两种方式:
1.使用仿真线下载程序;(须要仿真线)
2.使用串口下载程序;(已经快被淘汰了,因为只须要一根USB线,因此在没有仿真线的状况下,仍是实用)
ubuntu
接下来我使用的是第二种方法。
先下载图中圈出的三个压缩包
windows
连接: 野火STM32F103指南者开发板.
提取码:pmf1
失效了就去这里找到stm32f013指南者点进去下:
连接: 野火全部产品资料下载连接.
函数
而后用usb线把stm32开发板和电脑相链接,stm32端链接的 ‘usb转串口’这个接口,再打开stm32开关,能够看到红色的小灯亮起。
开发板上有黄色的跳帽,是至关于导线的做用,此处要求BOOT0和BOOT1接地,RXD接A9,TXD接A10,开发板买来默认就是这样接的,因此不须要改动。
测试
链接事后打开CH341SER.EXE,点击安装,显示安装成功便可。
而后打开串口下载助手mcuisp
按以下方式配置:①搜索串口,设置波特率 115200(尽可能不要设置的过高) ,②选择要下载的 HEX 文件、③校验、编程后执行、④DTR 低电平复位,RTS 高电平进入 bootloader、⑤开始编程。(前4步必定要调试正确,不然可能链接不上)
ui
2.代码及效果图
该处串口通讯实现如下功能:
1)设置波特率为115200,1位中止位,无校验位。
spa
2)STM32系统给上位机(win10)连续发送“hello windows!”,.net
3)当上位机给stm32发送“Stop stm32!”后,stm32中止发送。3d
此处的代码在野火的代码模板上改动。
先在前面的百度云连接中下载模板
解压后打开第21个串口通讯文件中的USART1接发中的工程文件
而后把其中stm32f10x_it.c文件的串口中断服务函数部分改成以下:
指针
int i=0; uint8_t ucTemp[50]; void DEBUG_USART_IRQHandler(void) { if(USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET) { ucTemp[i] = USART_ReceiveData(USART1); } if(ucTemp[i] == '!') { if(ucTemp[i-1] == '2'&&ucTemp[i-2] == '3'&&ucTemp[i-3] == 'm'&&ucTemp[i-4] == 't'&&ucTemp[i-5] == 's'&&ucTemp[i-6] == ' ') if(ucTemp[i-7] == 'p'&&ucTemp[i-8] == 'o'&&ucTemp[i-9] == 't'&&ucTemp[i-10] == 's') { printf("ÊÕµ½£¡"); while(1); } } i++; }
而后把main.c函数改成
#include "stm32f10x.h" #include "bsp_usart.h" void delay(uint32_t count) { while(count--); } int main(void) { USART_Config(); while(1) { printf("hello windows 10!\n"); delay(5000000); } }
而后就能够编译生成hex文件了,按照上面的方式把hex文件烧录到stm32中,而后打开最开始下载的串口调试助手,点击打开串口,便可以看到stm32发给电脑的信息
最终效果以下(中止命令中的感叹号是英文状态下的):
3、C语言程序里全局变量、局部变量、堆、栈等概念
看如下代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> char g_buf[16]; char g_buf2[16]; char g_buf3[16]; char g_buf4[16]; int main() { printf("g_buf: 0x%x\n", g_buf); printf("g_buf2: 0x%x\n", g_buf2); printf("g_buf3: 0x%x\n", g_buf3); printf("g_buf4: 0x%x\n", g_buf4); return 0; }
该代码定义了4个全局变量并输出它们的地址,
它们储存到了全局区里,地址依次递增。
再看如下代码
#include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char l_buf[16]; char l_buf2[16]; char l_buf3[16]; printf("l_buf: 0x%x\n", l_buf); printf("l_buf2: 0x%x\n", l_buf2); printf("l_buf3: 0x%x\n", l_buf3); }
定义了4个局部变量,并输出它们的地址
它们的地址也是递增的,暂时不知道储存到了哪里。(我在ubuntu定义的全部变量地址都是递增,多是cpu的关系)
4、stm32的堆、栈、全局变量的分配地址
仍然使用以前野火的串口通讯模板,把main.c(分别在stm32中定义了全局变量和局部变量,并把它们的地址返回给windows)改成以下:
#include "stm32f10x.h" #include "bsp_usart.h" char global1[16]; char global2[16]; char global3[16]; int main(void) { char part1[16]; char part2[16]; char part3[16]; USART_Config(); printf("part1: 0x%p\n", part1); printf("part2: 0x%p\n", part2); printf("part3: 0x%p\n", part3); printf("global1: 0x%p\n", global1); printf("global2: 0x%p\n", global2); printf("global3: 0x%p\n", global3); while(1) { } }
生成hex文件后,烧录到stm32中,打开串口调试助手,点击打开串口,而后点击stm32上的reset按钮,就能够看到以下结果。
前3个part变量为局部变量,它们储存到了栈中,地址依次减少。
后三个global为全局变量,它们储存到了静态区,地址依次增长。
再试试如下函数(定义了静态变量和指针),
#include "stm32f10x.h" #include "bsp_usart.h" #include <stdlib.h> int main(void) { static char st1[16]; static char st2[16]; static char st3[16]; char *p1; char *p2; char *p3; USART_Config(); printf("st1: 0x%p\n", st1); printf("st2: 0x%p\n", st2); printf("st3: 0x%p\n", st3); p1 = (char *)malloc(sizeof(char) * 16); p2 = (char *)malloc(sizeof(char) * 16); p3 = (char *)malloc(sizeof(char) * 16); printf("p1: 0x%p\n", p1); printf("p2: 0x%p\n", p2); printf("p3: 0x%p\n", p3); while(1) { } }
前三个静态变量储存到了静态区,地址依次增长。
后三个指针储存到了堆中,地址依次增长。(堆栈具体知识请看参考博客)
结合两次结果看(针对于测试的3个区域),能够大概看出栈在顶层(地址最大),而后依次是堆,静态区。对比如下地址分配图,大体符合。
参考博客:
C语言中,局部变量、全局变量、静态变量、堆、栈的内存地址.
C/C++程序内存的各类变量存储区域和各个区域详解.