有些坑还说不出原因,但是记着总比忘掉好~✿(。◕ᴗ◕。)✿
-
1、编译后报错 - Error: L6406E: No space in execution regions with .ANY selector matching xxxx.o(.data).
- 已解决:这种情况可以适当增加图上显示的RAM,ROM大小。我遇到的情况解决途径是:点击“魔术棒” → 点击“Target ”→ 将下图绿色框框里的值改大一点就可以了,我的本来是0x10000,编译会报错,改成0x20000,然后再点编译,就没有出现报错了。
-
2、使能UART串口接收中断之后,串口接收到数据,进入接收中断,此时要清除RXNE接收标志位:
-
正常的读DR寄存器就可以清除RXNE接收标志。所以除了多缓存通讯的情况下,没必要增加清除标志位的函数。(没有懂这里的多缓存通讯是什么意思,求科普)
-
代码举例
void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { RcvBuff[RcvIndex++] = USART_ReceiveData(USART2); // 此处对USART_DR 进行了读操作 } }
-
-
3、串口没有接收到数据,但是代码一直进接收中断里运行
-
ORE溢出错误
-
没有使能USART_IT_ERR中断时,ORE中断只能使用USART_GetFlagStatus(USART2, USART_FLAG_ORE) 读到,USART_GetITStatus(USART2, USART_IT_RXNE)这个函数读不到。
-
这里用USART_ClearITPendingBit(USART2, USART_IT_ORE);去清除ORE位是没有任何作用的。
-
复位ORE需要顺序执行对 USART_SR 和 USART_DR 寄存器的读操作
-
代码举例
void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { RcvBuff[RcvIndex++] = USART_ReceiveData(USART2); // 此处对USART_DR 进行了读操作 } // 若发生ORE溢出错误 if(USART_GetFlagStatus(USART2,USART_FLAG_ORE) == SET) // 此处对USART_SR 进行了读操作 { USART_ReceiveData(USART2); // 此处对USART_DR 进行了读操作 } }
-
-
4、一些关于串口接收和发送的标志位
- USART_FLAG 值
- 放串口发送函数里用 - 《USART_FLAG_TC 与 USART_FLAG_TXE - 附举例代码及说明》
- 放串口接收中断函数里用
- 放串口发送函数里用 - 《USART_FLAG_TC 与 USART_FLAG_TXE - 附举例代码及说明》
- USART_IT 值
- 放串口底层配置里用,用于使能串口接收中断
- 放串口底层配置里用,用于使能串口接收中断
- USART_FLAG 值
-
5、USART2 重映像
- STM32F103VCT6,想配置引脚PD5、PD6实现串口2通信收发功能,可是配置后,串口2收发不了数据,查手册才发现,要用PD5、PD6的话,需要在配置引脚前,对USART2 进行重映射。
- 代码举例
// 在配置引脚前,增加以下代码 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE); // 使能AFIO,GPIOD时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // 使能UART2 GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE); // USART2重映射
- STM32F103VCT6,想配置引脚PD5、PD6实现串口2通信收发功能,可是配置后,串口2收发不了数据,查手册才发现,要用PD5、PD6的话,需要在配置引脚前,对USART2 进行重映射。
-
6、串口接收中断函数注意事项
- 尽量不要在接收中断函数里直接增加数据处理函数,避免在中断函数里长时间运行,导致数据丢失。可以通过增加接收标志位,在中断函数外面处理接收到的数据。
- 尽量不要在接收中断函数里添加延时函数。
-
7、memset
-
void *memset(void *buffer, int ch, int count)
buffer:为指针或是数组
ch:是赋给buffer的值
count:是buffer的长度(单位 - 字节). -
memset函数按字节对内存块进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值。
-
举例:要将uint32_t DataBuff[6]这个数组清零
memset(DataBuff, 0, sizeof(DataBuff));
或memset(DataBuff, 0, 6 * sizeof(DataBuff));
-
8、堆栈溢出
- 定义局部变量时,长度不要过大,以免导致栈溢出,程序跑乱跑飞
- 定义局部变量时,长度不要过大,以免导致栈溢出,程序跑乱跑飞
-
9、代码运行时,某些数组、变量的值会被莫名其妙清零或者无故变化
- 一般的原因就是堆栈溢出/数组越界/指针越界
- 可以尝试修改这两个值,适当改大一些,不要太大了,不然编译器会报错的。
欢迎纠正,(づ ̄3 ̄)づ╭❤~
如果此文能帮助到素未谋面的你,那真是太开心了喵~( * Φ ω Φ * )