1、栈溢出
调试时发现有个调节PWM占空比的参数会莫名其妙的乱跳。观察代码,求这个系数的函数只在系统初始化的时候求过一次,之后就再也没有调用过。
单步执行代码,发现初始化时第一次运行时求出的系数是对的,但是全速运行后,这里面的系数就变了。
既然我没有调用函数来修改这个值,那肯定是被别的区域的值覆盖了。
打开map文件,看一下Trans_1_BaseStructre这个结构体周围都有哪些数据
ModbusSend这数组是用来发送串口数据的,空运行的时候里面全是0,那只可能是__initial_sp影响了。而__initial_sp是栈底地址,所以应该是栈溢出了。
想起来之前因为某种原因把栈空间改成512字节,所以才导致溢出。把栈大小改为1024字节后就都正常了。
2、串口不正常。用上位机软件发送一串数字,单片机收到的全是乱码,都不知道是啥。
首先检查了一下串口初始化的各个参数,并和以前正常的代码对比了一下,发现参数都正确。
一番对比后,发现是串口的波特率不对
我明明想初始化成4800bps,但是出来的是6635这个鬼东西。
心想莫非是系统时钟出问题了?可是仿真界面的时钟也是对的:
在定时器里面写了个IO口翻转的测试代码,发现IO口翻转的频率和设想的一致,所以系统的时钟应该没问题。
单步跟踪USART_Init(USART1, &USART_InitStructure)串口初始化函数,发现里面的RCC_GetClocksFreq(&RCC_ClocksStatus)这个函数得出的系统时钟竟然是24M。。
再单步运行进去,最终发现是HSE_VALUE这个宏定义没有修改
把这个宏定义修改成正确值后就都正常了。
这个宏定义也可以在keil的魔术棒里预定义,这样就不用改头文件了。截图如下:
关键字:STM32 BUG 栈溢出 串口调试
引用地址:
STM32--今天下午遇到了两个BUG
推荐阅读最新更新时间:2024-11-11 22:33
stm32专题十七:AT24C02
AT24C02的数据手册 1 硬件连接:直接是连接到I2C1的SCL SDA引脚(PB6 PB7)上,因此可以使用硬件I2C 2 存储容量描述 可以看到,AT24C02共有256个字节。跟Flash类似,EEPROM也分成不同的页。AT24C02共有32页,每页8个字节,共256字节。 支持400kHz的通讯速率(IIC快速模式) 3 引脚说明 4 设备描述 5 地址选择 6 写数据 字节写入 字节写入操作,需要8位的数据字地址跟随在设备字地址和应答位之后。当EEPROM接收到这个地址后,会再次响应0(初次响应为设备地址)。然后计时第一个8位数据。在收到8位数据后,EEPROM会输出
[单片机]
STM32串口使用
STM32的串口大多数情况下会预留USART1作为烧录接口或者调试接口。 通常做法是调用 stdio.h 将串口的输入输出重新定向,可以直接调用printf. 代码如下: /** ****************************************************************************** * 文件名程: bsp_usartx.c * 版 本: V1.0 * 编写日期: * 功 能: 串口底层驱动程序 */ /* 包含头文件 ----------------------------------------------------------------*
[单片机]
STM32 IAP/BOOT,三步速成
Stm32的IAP现在已经是非常简单了,下面就教大家三步学成: 前提条件:已经有Flash读写函数,这个函数好弄,很多stm32例程里面都有 第一步(对于Boot程序):跳转到指定Flash位置函数,如下: void Jump_To_Application(const u32 startAddr) { Jump_To_App = (pFunction)(*(vu32*) (startAddr + 4)); MSR_MSP(*(vu32*) startAddr); Jump_To_App(); } 第二步(对于APP):在keil工程配置里设置程序起始地址和APP程序大小,如图: 第三步(对于APP):如果APP中涉及
[单片机]
GPIO资源总结
STM32Fx系列 GPIO基本结构 保护二极管:IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入。当引脚电压高于VDD时,上方的二极管导通;当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁。但是尽管如此,还是不能直接外接大功率器件,须加大功率及隔离电路驱动,防止烧坏芯片或者外接器件无法正常工作。 P-MOS管和N-MOS管:由P-MOS管和N-MOS管组成的单元电路使得GPIO具有“推挽输出”和“开漏输出”的模式。这里的电路会在下面很详细地分析到。 TTL肖特基触发器:信号经过触发器后,模拟信号转化为0和1的数字信号。但是,当GPIO引脚作为ADC采集电压的输入通道时,用其“
[单片机]
STM32的GPIO口使用
STM32的GPIO类似于51单片机的IO口。只不过STM32的IO口使用时要配置输入/输出模式、速度、而且时钟使能后才能使用。 配置相关代码: GPIO_InitTypeDef GPIO_InitStructure;//定义初始化类型结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA时钟 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//引脚 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度 GPIO_InitStructure.GPIO_M
[单片机]
STM32的16位编码器溢出问题
STM32定时器有编码器接口,但是它的计数器只有16位。当要记录的数过大时,会溢出。下文介绍了一种方法,能有效解决因计数器位数过少引起的溢出问题。 (在网上搜了好多,感觉不他们说的方法都不准。这个方法经过我自己验证,可以准确记录编码器的位置) 原理一: unsigned short int j;(j的长度为16bit) ① 当j=65535 ,运行j++后,j=0; ② 当j=0 , 运行j- -后,j=65535; 定时器的16位计数器寄存器(CNT)同样符合上面的逻辑。在编码器模式时, (一)当加计数时(up计数),加到65535后,再加1,CNT的值变为0,且溢出标志位 被置1(UIF=1),
[单片机]
利用STM32的定时器输出PWM
使用芯片:STM32F103ZET6 目的:利用stm32的定时器3输出PWM 所用寄存器及相应位(参考STM32参考手册): (1)控制寄存器1(TIM1_CR1) 第0位CEN:计数器使能位;通过函数void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState) 来实现。 第4位DIR:计数方式,默认向上,也可以设置为向下计数; 第5、6位CMS:设置计数对齐方式; 第7位ARPE:自动重装载预装载允许位,为0时TIMx_ARR没有缓冲,为1时TIMx_ARR被装入缓冲器 第8、9位CKD:设置定时器的时钟分频因子为1、2、4。 (2)DMA/中断使能寄存器(TIM
[单片机]
STM32学习1:GPIO输出实验——点亮三色LED
一、概述: 1、发光二极管简介 发光二极管是半导体二极管的一种,可以把电能转化为光能,常简写为LED。常用的是发红光、绿光或黄光的二极管。发光二极管的反向击穿电压约为5V。它的正向伏安特性曲线很陡,使用时必须串联限流电阻以控制通过管子的电流。限流电阻R可用下式计算: R = (E - UF)/IF 式中E为电源电压,UF为LED的正向压降,IF为LED的一般工作电流。LED广泛应用于各种电子电路、家电、仪表等设备中,做电源或电平指示。 2、STM32 GPIO简介 STM32F4每组通用I/O 端口包括4 个32 位配置寄存器(MODER、OTYPER、OSPEEDR 和PUPDR)、2 个32 位数据寄存
[单片机]