STM32串口通信

一、基于寄存器与基于固件库编程差异

  1. 学习相关资料,说名基于寄存器与基于固件库的stm32 LED流水灯例子的编程方式有什么差异。

基于寄存器的编程方式具体参数更加直观,程序运行占用资源少,可移植性强,但是程序的可读性较差;
基于固件库的编程方式特点是简单方便理解,上手stm32比较容易

二、STM32的USART窗口通讯程序

  1. 学习和阅读“零死角玩转STM32F103–指南者”文档中的第20、21章内容,完成STM32的USART窗口通讯程序,要求:
    1)设置波特率为115200,1位停止位,无校验位。
    2)STM32系统给上位机(win10)连续发送“hello windows!”,上位机接收程序可以使用“串口调试助手“,也可自己编程。
    3)当上位机给stm32发送“Stop,stm32”后,stm32停止发送。

我用的是野火指南者STM32F103VE 开发板
(1)利用野火官方提供的指南者配套开发例程
在这里插入图片描述
(2)打开“21-USART-串口通信”文件夹
在这里插入图片描述(3)选择“USART1接发”
在这里插入图片描述(4)打开里面的工程例程如下:
在这里插入图片描述(5)找到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++;
}

(6)找到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);
	}	
}

(7)编译 运行
在这里插入图片描述
(8)采用J Link线连接开发板和电脑
在这里插入图片描述在这里插入图片描述(9)下载
在这里插入图片描述(10)串口调试结果如下:
在这里插入图片描述

三、C语言程序里的全局变量、局部变量、堆、栈

3.重温C语言程序里全局变量、局部变量、堆、栈等概念,并在ubuntu系统中编程,输出信息进行验证;

在Ubuntu下写程序,并用gcc编译
代码如下:

#include <stdio.h>
#include <stdlib.h>
int k1 = 1;
int k2;
static int k3 = 2;
static int k4;
int main( )
{   static int m1=2, m2;
    int i = 1;
    char *p;
    char str[10] = "hello";
    char *var1 = "123456";
    char *var2 = "abcdef";
    int *p1=malloc(4);
    int *p2=malloc(4);
    free(p1);
    free(p2);
    printf("栈区-变量地址\n");
    printf("                i:%p\n", &i);
    printf("                p:%p\n", &p);
    printf("              str:%p\n", str);
    printf("\n堆区-动态申请地址\n");
    printf("                   %p\n", p1);
    printf("                   %p\n", p2);
    printf("\n.bss段\n");
    printf("全局外部无初值 k2:%p\n", &k2);
    printf("静态外部无初值 k4:%p\n", &k4);
    printf("静态内部无初值 m2:%p\n", &m2);
    printf("\n.data段\n");
    printf("全局外部有初值 k1:%p\n", &k1);
    printf("静态外部有初值 k3:%p\n", &k3);
    printf("静态内部有初值 m1:%p\n", &m1);
    printf("\n常量区\n");
    printf("文字常量地址     :%p\n",var1);
    printf("文字常量地址     :%p\n",var2);
    printf("\n代码区\n");
    printf("程序区地址       :%p\n",&main);
    return 0;
}

在这里插入图片描述

C语言在内存中一共分为如下几个区域,分别是:

内存栈区: 存放局部变量名;
内存堆区: 存放new或者malloc出来的对象;
常数区: 存放局部变量或者全局变量的值;
静态区:用于存放全局变量或者静态变量;
代码区:二进制代码。

由程序运行结果分析得:
栈的地址是向下增长;
堆的地址是向上增长;
静态变量的地址是向下增长;
全局常量的地址是向上增长;
函数的地址是向上增长;

四、stm32里的全局变量、局部变量、堆、栈

  1. 重温C语言程序里全局变量、局部变量、堆、栈等概念,在Keil中针对stm32系统进行编程,调试变量,进行验证; 通过串口输出信息到上位机,进行验证。 并归纳出stm32的堆、栈、全局变量的分配地址,与ARM教材中的地址分配进行对比。

在实作二的keil工程文件下修改main.c文件如下:

#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)
	{	
		
	}	
}

通过串口输出信息到上位机
在这里插入图片描述其中part1、part2、part3为栈中的局部变量,可以看到地址在逐渐减小;
global1、global2、global3为静态的全局变量,可以看到地址在逐渐增加

再次修改main.c文件如下:

#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)
	{	
		
	}	
}

通过串口输出信息到上位机
在这里插入图片描述其中st1、st2、st3都是静态变量,可以看到地址在逐渐增加;
p1、p2、p3是堆中的指针,可以看到地址也是在逐渐增加

这与之前在实作三Ubuntu下得出的结论一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值