程序编译通过后才能调试,点击调试后会自动下载程序。
不是万能的,就是它会“忽略”标志位啥,我也没弄清楚,调试上能完整执行,但是真实硬件上还是卡死的。
进入/退出调试模式
(1)首先需要连接 ST-Link

(2)进入/退出调试页面【Ctrl + F5】
或者点击放大镜里面有 d 的图标:

查看内存
打开内存窗口【View】【Memory Windows】
代码执行调试
进入调试页面后它会默认运行到 main 函数开始。
1、单步执行
【F11】或者:

点击一次执行一条语句。
2、若执行语句时进入了函数

使用【Ctrl + F11】或者点击:

直接执行完这个函数并返回。
3、如果想要以一行为单位的执行,而不是要跳入到函数中:

【F10】或者点击

4、跳转到光标处
当项目中程序卡死在了某个函数中,可以先找到该函数,点击前面有深灰色标记的行:

然后【Ctrl + F10】或:

让程序直接运行到那里。
用断点,一样的效果。
断点调试
keil断电调试——4窗口输出信息_keil4软件中我想输出程序中某个变量的值怎么做-CSDN博客
断点,意思是程序运行到那里就暂停了。
如果以前设置了断点,重新进入调试后会弹出:

这时候要选择“否”,否则以前的设置都没了。
打断点
当在断点停止时,打断点的那个语句是还没有执行的。
第一种方法,在前面有深灰色标记的地方,左键单击,设置/取消断点:

第二种方法,直接输入函数名,
file:///E:/0.%E8%B5%84%E6%96%99%E6%95%B4%E7%90%86/DshanMCU_F407%E5%BC%80%E5%8F%91%E6%9D%BF%E8%B5%84%E6%96%99/6_%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B/%E5%8D%95%E7%89%87%E6%9C%BARTOS%E8%B0%83%E8%AF%95%E4%B8%93%E9%A2%98%EF%BC%88%E5%85%A8%E5%A5%97%EF%BC%8C%E4%B8%8D%E6%96%AD%E6%9B%B4%E6%96%B0%E5%AE%9E%E4%BE%8B%EF%BC%89/02_%E5%B8%B8%E8%A7%84%E7%9A%84%E8%B0%83%E8%AF%95%E6%8A%80%E6%9C%AF/01_%E5%B8%B8%E8%A7%84%E8%B0%83%E8%AF%95%E6%96%B9%E6%B3%95.mp4
4分39秒
清空所有断点:Ctrl+B 然后全删除。
执行到断点停止
【F5】
或者:

或者:

代码指定执行次数
在一个循环,或者中断函数中,设置断点的话,每次执行到断点就会停下来。假如要观察100次后的结果,不可能说手动点击100次。
keil 提供了这个方法,运行 n 次后才会暂停。

【Ctrl + B】或者:



可以看到后面多了个 count 参数:

数据访问
数据匹配
调试信息输出
通常使用硬件串口进行调试,但是串口打印很慢,还造成程序体积大。
各有各的好处,混合使用。
传统做法:

给它们前面打上断点:

然后设置:

格式:printf(\"123\n\")
123 为要打印的内容
\n 必须写上,否则不打印
双引号必须 \" 转义
打印的话,程序不会在该断点处停止
查看变量的方法
计算执行时间
通过 GPIO 波形
GPIO操作是需要一定时间的,对于ms级别的时间,可以忽略这个时间。
使用断点
在执行语句前后打上断点,
STM32F0的芯片无法这样,因为 Cortex-M0 是没有DWT定时器的,所以Keil的计时器无法工作。
对于有dwt的单片机:
上面是keil自动的,手动:
可以通过查看CYCLECOUNTER(在CPU registers中)的值,计算两个断点的差值,乘以指令周期(MCLK)便是待测代码的运行时间。
使用硬件定时器
如果 gpio 也不行,板子上没有引出来的引脚。
/**
* 1us计数一次,上限65536us,65.536ms
*/
void Tim_Count_Init(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure1;
TIM_TimeBaseStructure1.TIM_RepetitionCounter = 0;
TIM_TimeBaseStructure1.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure1.TIM_Prescaler =47;
TIM_TimeBaseStructure1.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure1.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure1);
}
TIM_Cmd(TIM6, ENABLE);
int i = 0;
for ( i=0; i<1000; i++) {}; // 必须有一个短暂的延时,否start的值不准,一直为0.
while(1)
{
// 检测IO状态
volatile uint16_t start = TIM6->CNT;
IO_state_update();
volatile uint16_t end = TIM6->CNT;
volatile uint16_t delta = (end - start) & 0xFFFF;
}打断点

【View】【Watch Windows】
谁这几个变量,没运行到变量,Value不显示。

运行到断点,值显示了:

执行时间 34 us
而使用gpio+裸机分析仪测得16us,说明上面的测的不准。
这种方法不适合测短时间的代码。