KEIL/STM32 - 使用/开发笔记 之 突然遇到的坑

有些坑还说不出原因,但是记着总比忘掉好~✿(。◕ᴗ◕。)✿

  • 1、编译后报错 - Error: L6406E: No space in execution regions with .ANY selector matching xxxx.o(.data).

    Alt

    • 已解决:这种情况可以适当增加图上显示的RAM,ROM大小。我遇到的情况解决途径是:点击“魔术棒” → 点击“Target ”→ 将下图绿色框框里的值改大一点就可以了,我的本来是0x10000,编译会报错,改成0x20000,然后再点编译,就没有出现报错了。Alt
  • 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溢出错误
      Alt

    • 没有使能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_SRUSART_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、一些关于串口接收和发送的标志位

  • 5、USART2 重映像

    • STM32F103VCT6,想配置引脚PD5、PD6实现串口2通信收发功能,可是配置后,串口2收发不了数据,查手册才发现,要用PD5、PD6的话,需要在配置引脚前,对USART2 进行重映射。
      Alt
    • 代码举例
      // 在配置引脚前,增加以下代码
      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重映射
      

  • 6、串口接收中断函数注意事项

    • 尽量不要在接收中断函数里直接增加数据处理函数,避免在中断函数里长时间运行,导致数据丢失。可以通过增加接收标志位,在中断函数外面处理接收到的数据。
    • 尽量不要在接收中断函数里添加延时函数。

  • 7、memset

    • 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、代码运行时,某些数组、变量的值会被莫名其妙清零或者无故变化

    • 一般的原因就是堆栈溢出/数组越界/指针越界
    • 可以尝试修改这两个值,适当改大一些,不要太大了,不然编译器会报错的。
      Alt

欢迎纠正,(づ ̄3 ̄)づ╭❤~

如果此文能帮助到素未谋面的你,那真是太开心了喵~( * Φ ω Φ * )

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的小肥丸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值