L2-2 Keil5-MDK软件STM32工程仿真(USART篇)

前置条件

  • 已创建STM32工程(本文以STM32F103ZE系列芯片为例)
  • 已完成USART1的驱动程序编写(包括printf的硬件重定向)

代码示例

usart.h

#ifndef _USART_H_
#define _USART_H_

#include "stm32f10x.h"

#ifdef __GNUC__
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

void Usart_Init(void);  // 对外提供的API接口

void Usart_Pin_Init(void); // 硬件端口配置(引脚输入输出方式)
void Usart_Port_Init(void); // 串口外设配置(波特率等)

#endif

usart.c

#include "usart.h"

// serial port init
void Usart_Init(void) {

    Usart_Pin_Init();
    Usart_Port_Init();
    USART_ClearFlag(USART1, USART_FLAG_TC);
    return;
}


void Usart_Pin_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // open clock

    // USART1_TX,推挽输出
    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);

    // USART1_RX,浮空输入
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    return;
}

void Usart_Port_Init(void) {
    USART_InitTypeDef USART_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

    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_HardwareFlowControl = USART_HardwareFlowControl_None; // 硬件流控
    USART_InitStructure.USART_Mode = USART_Mode_Tx; // 收发模式

    USART_Init(USART1, &USART_InitStructure);
    USART_Cmd(USART1, ENABLE);
    return;
}

 // 覆盖(重写)fputc函数
PUTCHAR_PROTOTYPE {
  USART_SendData(USART1, (uint8_t) ch);
  while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {
  }
  return ch;
}

main.c

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include <stdio.h>
#include "usart.h"

/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void) {
    Usart_Init(); // Usart Init

    // print something
    printf("1. Hello, I am USART1\r\n");
    printf("2. Hello, I am USART1\r\n");
    printf("3. Hello, I am USART1\r\n");
    printf("4. Hello, I am USART1\r\n");
    printf("5. Hello, I am USART1\r\n");

    return 0;
}

详情

编译通过,启动调试

打开工具栏 >> Serial Windows >> USART #1

打开串口1监视窗口

右下角出现串口调试窗口
串口调试窗口

打开main.c,将光标定位在如图所示位置,使用调试方式 >> 运行到光标所在代码行
PS:若采用单步调试等方式,需要等待引导区的代码执行完毕,效率较低,所以此处一开始就强制调试运行到代码观察点。
运行到指定代码行

等待代码执行至光标处,使用Step Over调试,逐次运行打印语句,同时观察USART1监视窗口
Step Over调试打印语句

如下图可见,已运行的3条语句的打印结果出现在串口监视器中
运行结果

问题与调试

问题描述:笔者仿真调试时字符串可以打印在调试窗口,但是把编译生成的.hex文件烧写到物理开发板之后,发现无法与上位机建立USART连接,即字符串发送不过去,解决方法如下:
点击魔棒工具,点击Target,勾选Use MicroLIB

勾选Use Micro LIB

原理与ARM的半主机模式有关,笔者后续会有专门的博客来讨论。

串口映射

下面演示一种把Target驱动的仿真串口映射到主机的物理串口(或软件虚拟串口)的方法,以方便调试。
首先进入调试模式,点击标记1的调试按钮进入调试模式,点击调试工具条标记2处的命令行按钮打开标记3所示的命令行窗口
依次输入以下两条命令:

  • 1. MODE COM1 9600, n, 8, 1
  • 2. ASSIGN COM1 <S1IN> S1OUT
    PS:
  • 命令1和命令2的COM1指的是主机的串口
  • 命令2的S1IN和S1OUT的指的是Tartget的USART1串口
  • 此方式与调试器自带的USRT1监视窗口是并行的,互不影响


    进入调试模式

至此结束。

声明

商业开发请购买正版软件和服务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342