keil uvision4调试怎么设置串口波特率

🏰 日博best365 📅 2025-09-11 17:50:03 👤 admin 👁️ 4015 👑 933
keil uvision4调试怎么设置串口波特率

Keil(MDK-ARM)使用教程(三)_在线调试

keil调试串口的软件仿真方法

由于我是直接使用(打开现有的软件工程),如果跟着需要下载上面演示参考的软件工程才行。工程默认是使用硬件在线调试,接下来按照每一点来讲述。

如果keil软件仿真时,程序不能正常运行解决方法

在用keil软件调试程序时,有时候手头没有硬件电路板,就需要用到软件仿真功能。但是使用软件仿真时经常出现一个问题,就是开始仿真后,程序就会卡在系统初始化函数中。

程序停在时钟设置这里就不动了,不能进入主函数。

引起这个的原因是debug选项没设置好,先看看debug默认设置

在debug选项中除了要设置使用软件仿真外,还要设置底下的 Dialog DLL 选项。

将Dialog 设置为DARMSTM.DLL,将Parameter 设置为 -pSTM32F103C8 。后面这个为使用的单片机型号,根据单片机型号填写。这个工程使用的是STM32F103C8T6单片机,所以这块设置为 -pSTM32F103C8。

-pSTM32F103RE

这个设置好之后,在重新仿真,程序就能正常运行了。

1.编译+调试

打开软件工程 -> 编译 -> 调试

这里的编译建议使用Build Target(第2个按钮)编译工程(如下图动画),也就是使用快捷键F7。Translate(第1个按钮)是编译当前活动文件。Rebuild all Target files(第3个按钮)是重新编译所有目标文件。

在线调试分类:软件在线调试和硬件在线调试;由于现在硬件成本比较便宜,一般我们都使用硬件在线调试,也就是软件直接下载到芯片,我们查看运行状态。

2.复位+全速运行

复位 -> 全速运行

复位,使程序复位到初始;

全速运行F5,我们可以在很多地方打断点,让程序运行到断点位置,此时程序就停止下来了。

3.单步调试

【单步调试】也就是每点一次按钮,程序运行一步。遇到函数会进入函数。

点击图标按钮,或者按快捷键F11。

(这里取消上面的断点)

4.逐步调试

【逐步调试】即逐行调试,也就是每点一次按钮,程序运行一行。遇到函数不会进入函数。

点击图标按钮,或者按快捷键F10。

5.跳出调试

【跳出调试】即挑出函数调试,也就是每点一次按钮,程序跳出一个函数,直到跳出最外面的函数(main函数)。

点击图标按钮,或者按快捷键Ctrl + F11。

6.运行到光标处

【运行到光标处】即将光标放在某一处,点击该按钮(或Ctrl + F11),程序执行到光标的位置就会停止下来(前提是程序能执行到光标的位置)。

7.跳转到暂停行

这个功能在程序停止运行时有效,主要的作用就是我们打开了很多文件,不知道将程序翻到哪里去了,点击改按钮即可知道我们的程序暂停在那个位置。

8.调试窗口

【调试窗口】是在调试的时候可以查看的窗口,这里有别于平时编辑状态下的窗口。平时编辑时View菜单下面的选项很小,但是进入调试模式,这里就多了很多选项,这些选项就是调试时查看的窗口(见下图)。

下面着重讲述一下常用的一个调试窗口吧

A.内存窗口,也就是我们查看变量的窗口

B.系统外设窗口,也就是外设寄存器数值查看的窗口

下面讲解一下最常用的串口调试

随便一个虚拟串口软件就行 这里采用比较常用的VSPD

从网上找的链接

http://www.pc0359.cn/downinfo/43905.html

1. 利用VSPD将PC上的两个虚拟串口连接起来。如图我将COM4 和COM5连接起来。点击Addr

pair。

2. 2.可以看到Virtual ports上将两个虚拟串口连接到了一起了。

3.虚拟串口准备就绪了。先将直接输入命令的方式来调试。我们打开KEIL MDK的,设置成仿真的模式。点DEBUG.在COMMAND串口输入:MODE COM1 115200,0, 8, 1

说明: MODE命令的作用是设置被绑定计算机串口的参数。基本使用方式为: MODE COMx baudrate, parity, databits, stopbits 其中: COMx(x = 1,2,…)代表计算机的串口号; baudrate代表串口的波特率;parity代表校验方式; databits代表数据位长度; stopbits代表停止位长度。 例如:MODE COM1 115200, 0, 8, 1 设置串口1。波特率为115200,无校验位,8位数据,1位停止位。MODE COM2 19200, 1, 8, 1 设置串口2。波特率为19200,奇校验,8位数据,1位停止位。

4、点回车后,再输入 ASSIGN COM4 S1OUT

说明:COMx代表计算机的串口,可以是COM1、COM2、COM3或其他; inreg和outreg代表单片机的串口。对于只有一个串口的普通单片机,即SIN和SOUT;对于有两个或者多个串口的单片机,即SnIN和SnOUT(n=1,2,…即单片机的串口号)。 例如:ASSIGN COM1 < SIN > SOUT 将计算机的串口1绑定到单片机的串口(针对只有一个串口的单片机)。 ASSIGN COM2 < SIN > SOUT 将计算机的串口2绑定到单片机的串口0(针对有多个串口的单片机,注意串口号的位置)。 需要注意的是,参数的括号是不能省略的,而outreg则是没有括号的。 5、然后调试程序。可以看到串口COM5打印出了串口1的数据了。

这样就能够将计算机的串口模拟成单片机的串口了。在进行软件仿真时,所有发送到被绑定的计算机串口上的数据都会转发到Keil模拟的单片机串口上,用户程序可以通过中断处理程序或查询方式接收到这些数据;同样,单片机程序中发送到单片机串口上的数据也会通过被绑定的计算机串口发送出来,可以被其他软件所接收。利用这个特点,就可以方便地仿真、调试单片机的串口部分程序。要注意的是,这两个命令需要一起使用。

1.Keil 里面先对串口编程,以下假设你已经设定串口的参数为 9600,n,8,1 2.下载一个虚拟串口软件 vspd,安装后config一下,增加一对串口,比如下图的 COM2<-->COM3 3. Keil 里面给两条指令 (调试状态下)MODE COM2 115200,0,8,1 ASSIGN COM2 < S1IN > S1OUT

要注意 要手打

下面会提示输入命令的详细格式 (如果嫌麻烦,可以先保存为一个 ini文件,并在调试选项里面选中) 4. 然后打开一个串口调试助手,选用另外一个对接的虚拟串口 就可以看到单片机串口输出的内容了

1 如何使用keil5建立一个工程文件

本篇文章所讲内容基于LPC1759芯片展开(公司用LPC比较多,M0、M3都用,对于LPC系列芯片,开发流程大同小异,如果以后用到STM32再总结跟大伙分享),比较完整地展现一个软件项目的开发,内容比较基础,希望对一些刚入门的同学有些帮助。(PS:我也是菜鸟,从事应用层的开发已经两年多,但是最近才着手负责一个较完整的小项目,期间的一些小感悟、小收获非常乐意拿出来跟大家交流分享,不对的地方还请各位高手赐教哈~)

打开keil5软件(需要软件安装包的同学私我哈,keil5安装包,以及AK100仿真器驱动都可以提供),创建一个新工程文件,如图1所示。

图1

取文件名称:lpc1759example,如图2所示。

图2

进入选择MCU界面,如图3所示。

图3

通过Manage Run-Time Environment可把keil5工具提供的针对开发者所选的MCU的软件功能加载到文件中,我一般就按照图4所示选择。

图4

说几点,本文创建的工程文件为前后台模式,不采用任何实时操作系统,如果你对keil5工具自带的RTX感兴趣,可以进一步研究,目前我们公司开发用的都是UCOS。另外不太建议直接从Manage Run-Time Environment中加载比如GPIO、UART等等硬件相关的代码,一般针对某款MCU开发时,大多数情况下都可以从网上获得相关的开发例程,如各个硬件初始化、简单应用代码等。所以,建议采用开发例程的代码。

如图5所示,一个初步的工程文件搭建好了,接下来的工作主要就是配置工程文件、加载自己编写的代码丰富工程文件功能。

图5

如图6所示,在"Target1"位置右击,点击“Manage Project Items”,进入图7所示界面,可以增加、删除“Project Targets”"Groups",或者修改名称。还有重要一步,就是配置目标选项。

图6

图7

点击该按钮,进入配置目标选项。

图8、图9跟所选芯片相关,图8就是选择的MCU,图9的ROM、RAM大小自动跟图8所选芯片匹配,采用默认即可。

图8

图9

图10注意勾选“Create Hex File”,否则编译完程序在output里找不到hex文件,图11、图12、图13、图14、图15采用默认配置即可。

图10

图11

图12

图13

图14

图15

图16需要注意的是,你所用的仿真器选择,在这之前一定要安装好仿真器的驱动,否则在图16里找不到你要配置的仿真器,目前我都是用AK100仿真器,对应的就是“TKScope Debug for ARM”,然后点击右边的“Settings”按钮。如图17所示,进行“硬件选择”配置,如图18所示,进行“程序烧写”配置,其他选项可以不用改动,感兴趣的话再细究。

图16

图17

图18

2 开始编写代码

在编写代码前,要根据项目的功能要求,确定使用哪些硬件,根据硬件使用情况,决定主频、外设频率大小。

(这个时候,手头上肯定要准备好芯片用户手册和相关开发例程)。关于主频该取多大,一是考虑芯片最大支持多少,肯定不能超过芯片的要求,二是如果外设使用的不太多也不复杂,建议主频不要太大,太大功耗大,太小对于SPI等读写速率有影响,对于lpc1759,主频定为48MHz(外部晶振频率为12MHz)或主频定为44236800Hz(外部晶振频率为11059200Hz),统一外设频率定为二分之一的主频,至于SPI的CLK到底多大,可以通过SPI相关寄存器分频设置。主频、外设频率设定等系统初始化(一般main函数的首行代码),在“system_LPC17xx.c”文件里修改,内容比较少也比较简单,遇到一些寄存器的设置,可以查用户手册。

如图19所示,新建一个文件,按照图20所示保存。

图19

图20

把main.c文件加载到工程里的UserCode下,如图21所示。接下来开始编写main函数框架,一个简单的框架如图22所示。之后的工作就是根据项目要求,一点一点添加功能,应用层或底层驱动都会涉及到。

图21

图22

3 使用一个硬件,要编写哪些代码?

这一小节,通过UART的例子,跟大家详解一下。牵扯到硬件,对于菜鸟而言,有例程会大大降低开发难度,也容易避免掉进不知名的坑里。用到硬件,首先要初始化,参考例程加上查询芯片用户手册,根据自己的应用要求,写好应该不难。

void UART_Ini(uint8_t PortNum, UARTMODE set,uint32_t baudrate) { uint16_t ulFdiv; //参数过滤保护 if((set.datab<5) ||(set.datab>8)) return; if( (set.stopb==0)||(set.stopb>2) ) return; if( set.parity>4 ) return; if(PortNum == 0) //UART0 { LPC_PINCON->PINSEL0 |= (0x01 << 4)|(0x01 << 6); LPC_SC->PCONP |= 0x08; //打开串口0功能 LPC_UART0->LCR = 0x80; //允许设置波特率 ulFdiv = (Fpclk /16) / baudrate; //设置波特率 Fpclk为外设频率 LPC_UART0->DLM = ulFdiv / 256; LPC_UART0->DLL = ulFdiv % 256; LPC_UART0->LCR = 0x00; //锁定波特率 LPC_UART0->FCR = 0x87; //使能FIFO 设置8个字节触发点 LPC_UART0->LCR |= (set.datab-5); //数据位设置

if(set.stopb ==2 ) //2位停止位 { LPC_UART0->LCR |= 0x04; } if(set.parity !=0 ) //有校验位 { LPC_UART0->LCR |= 0x08; LPC_UART0->LCR |=((set.parity-1)<<4); //奇偶校验设置 } NVIC_EnableIRQ(UART0_IRQn); NVIC_SetPriority(UART0_IRQn, 4); LPC_UART0->IER = 0x01; //使能接收中断 }

在硬件初始化函数里调用情况如图23所示。

图23

一般使用UART收发数据,都是采用中断方式,所以还要写相应的中断服务函数。在上面创建的工程文件中,UART0的中断服务函数名有默认的,为UART0_IRQHandler,在Starup_LPC17xx.s中可以找到,采用默认函数名称即可。中断函数如下:

void UART0_IRQHandler (void) { uint8_t i; Start: if((LPC_UART0->IIR & 0x0F ) == 0x02 ) //发送中断 { if (GETBIT(ui_FlgUART[UART0],6)) //在发送状态中 { for (i=0; i<8; i++) { if(uc_UartPtrTx[UART0] >= uc_UartTxLen[UART0]) //发送完数据 { CLRBIT(ui_FlgUART[UART0],6); uc_UartPtrTx[UART0] = 0; uc_UartPtrRx[UART0] = 0; LPC_UART0->IER = 0x01; //使能接收中断 goto End; } LPC_UART0->THR = uc_UartTxbuf[UART0][uc_UartPtrTx[UART0]]; uc_UartPtrTx[UART0] ++ ; } goto Start; } else { LPC_UART0->IER = 0x01; //使能接收中断 } } if((LPC_UART0->IIR & 0x0F ) == 0x04 ||(LPC_UART0->IIR & 0x0F ) == 0x0C) //接收数据 { if(!GETBIT(ui_FlgUART[UART0],6)) //不在发送状态 { s_Tmr10ms.ui_UartRxTimeOut[UART0] = 5; for(i=0; i<8; i++) { if( (LPC_UART0->LSR & 0x01)==0 ) //FIFO空 { uint8_t uc_Buf; uc_Buf = LPC_UART0->RBR; break; } uc_UartRxbuf[UART0][uc_UartPtrRx[UART0]] = LPC_UART0->RBR; //接收数据 uc_UartPtrRx[UART0] ++ ; uc_UartRxLen[UART0] = uc_UartPtrRx[UART0]; } goto Start; } else { LPC_UART0->IER = 0x02; //使能发送中断 } } End:; }

在接收数据中断里,通过 s_Tmr10ms.ui_UartRxTimeOut字节超时定时器,来判断数据收没收全,时间到了,数据接收标志置起(在10ms定时器里做)。对于一些有固定帧头帧尾格式的数据报文,在接收里可做详细判断,不必采用字节超时方法。在main函数的主循环中,接收数据处理代码如图24所示。ui_FlgUART[UARTNum]的bit1位即为接收数据标志。

图24

接收完数据做了相关处理后,要发送回复数据,代码构成如图25所示。

图25

void SetRTS(eUARTNum UARTNum) { ui_FlgUART[UARTNum] |= 0x0020; //setbit 5 uc_UartPtrTx[UARTNum] = 0; } 如果是通过硬件RTS控制数据发送的话,SetRTS里还要增加相关的硬件控制,我这里就是置起发送标志,另外清除了一下发送数据长度。

void StartTD485(eUARTNum UARTNum) //发送启动函数 { uc_UartPtrTx[UARTNum] = 0; memset(uc_UartRxbuf[UARTNum],0,sizeof(uc_UartRxbuf[UARTNum])); SETBIT(ui_FlgUART[UARTNum],6); CLRBIT(ui_FlgUART[UARTNum],5); if(UARTNum==UART0) { LPC_UART0->THR = uc_UartTxbuf[UART0][uc_UartPtrTx[UART0]]; uc_UartPtrTx[UART0] ++ ; if(uc_UartPtrTx[UART0] >= uc_UartTxLen[UART0]) //发送完数据 { CLRBIT(ui_FlgUART[UART0],6); uc_UartPtrTx[UART0] = 0; uc_UartPtrRx[UART0] = 0; LPC_UART0->IER = 0x01; //使能接收中断 return; } if( uc_UartPtrTx[UART0]!=0) { LPC_UART0->IER = 0x02; //使能发送中断还有未发送完的数据进入发送中断接着发送 } }

}

使用UART收发数据,基本就涉及到以上方面。

最后附一张,我做的一个小项目的工程文件结构图26。建议大家,应用层代码、不同硬件的底层代码放在不同的文件目录里,方面维护,增加或删除文件都比较方便,养成好习惯哦~

图26

代码功能完成好了,接下来就是结合硬件仿真调试了,期间可能会出现各种各样的问题,多跟硬件工程师沟通,很重要哦~

以前总是通过公式来计算串口的波特率。还有人开发了工具。其实Keil就可以。而且很简单。步骤如下

1、在编译选项中设置好你的晶振频率

2、通过仿真运行你的程序

3、在运行到串品初始化后停止

4、在调试窗口的菜单中选择Peripherals/Serial,介面如下

看到实际的波特率了吧。

皇家推荐

2016款qq汽车
365bet现场走地盘

2016款qq汽车

📅 09-02 👁️ 4364
【图】光头穿衣搭配图片展示 11种搭配方式大盘点
365bet现场走地盘

【图】光头穿衣搭配图片展示 11种搭配方式大盘点

📅 07-12 👁️ 7034
稀饭和米饭哪个容易胖
365bet现场走地盘

稀饭和米饭哪个容易胖

📅 08-25 👁️ 6743
塞尔达传说王国之泪铠甲蘑菇在哪里
日博best365

塞尔达传说王国之泪铠甲蘑菇在哪里

📅 07-14 👁️ 2739
阿根廷世界杯全程回顾与精彩瞬间分析
日博best365

阿根廷世界杯全程回顾与精彩瞬间分析

📅 08-20 👁️ 1540
支付宝交电费最便捷的四种方式详解
365bet现场走地盘

支付宝交电费最便捷的四种方式详解

📅 07-22 👁️ 2131