0
点赞
收藏
分享

微信扫一扫

GD32F103ZKT6替换STM32F103调试手记

酷子腿长一米八 2022-04-25 阅读 93
stm32c语言

STM32芯片近年来涨价太厉害,翻了几乎10倍,如此情况下只能更换国产芯片,考虑之前有换过GD的,这次还是采用GD的芯片。

2022.4.20

首先:按照网上都能下载的替换说明改了启动时间以及内部FLASH擦除等位置后,程序烧录成功。 然鹅并没有那么简单,程序卡住无法启动。

排除问题,发现是GPIO模拟I2C总线读取时钟的代码卡住,暂时屏蔽,启动终于成功。

能正常启动,LED运行灯亮起来了,也算是初步有些进展,但是面临的问题还是很多;

2022.4.21

第一个问题就是串口问题,由于采用GD32芯片替换STM32,所以库函数并没有更换,沿用的STM的,低速波特率9600通讯无问题,但是在115200会出现丢包的情况。

1)在网上找到这样一个可能的原因:

GD32IDLEF中断需要先读STAT再读DATA才会清除。

而STM32可以直接清除对应的标志位 。因此代码加入如下几行:

/*--------------------USART1中断函数--------------------*/
void USART1_IRQHandler(void)
{
  if (USART1_func) (*USART1_func)(USART1_para);
  USART_ClearITPendingBit(USART1, USART_IT_RXNE);

  if(RESET != USART_GetITStatus(USART1, USART_IT_IDLE))
  {
    USART_ReceiveData(USART1);
  }
  else if(RESET != USART_GetITStatus(USART1, USART_IT_ORE))
  {
    USART_ReceiveData(USART1);
  }

  
}

重新下载后发现并没有解决,看了还是没有找到真正的原因。

2)又找到这样一个可能的原因:原文:GD32F450的USART接收数据错误bug - 知乎

UART判断起始位的时候,16倍过采样,需要16个点全部为0才能确认。

实测115200波特率,正常低电平为1e6/115200=8.68us,实测经过422接口芯片以后,低电平比正常短7%(高电平长6%),刚好在临界点上。

7%超过了6.25%的误差容限,会导致16个采样点至少有一个不为0,采样不到起始位,导致出错。

将过采样降低到8倍,那么误差容限为1/8=12.5%,这样,115200波特率就不会有问题了,230400还是不行。

但是采样降低到8倍后还是不行。

进一步测试发现,当代码减少一部分,只是单独测试串口等有限的代码时在115200波特率是可以正常接收的。因此初步怀疑有可能是代码过多执行串口中断时候执行速度不够快,所以接收有确实。

3)GD的片子flash有高低速之分,而ST的全部为高速flash(贵有贵的道理哈),我用的这款GD芯片,flash一共是2M字节—高速区是flash的前256K字节(0x08000000-0x08040000),低速区是flash的后1792K字节(0x80400000-0x82000000),于是猜想是串口中断处理函数编译在了低速区flash,导致每次中断内代码执行时间过长,波特率越高,中断频率越高,也就自然会丢失字节。
————————————————

因此考虑采用分散加载来测试,把串口中断及服务子程序全部放入高速区。

;LR_IROM1 是flash 0x08000000-0x08040000 (高速区)区域
LR_IROM1 0x08000000 0x08040000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00100000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   main.o (+RO)
   intr.o  (+RO)
   scom.o  (+RO)
   ;*是通配符,写过脚本的应该都理解,不理解的自行百度,这样就把stm32f4xx_it.c,stm32f4xx_hal_gpio.c都编译进了高速区
   ;(+RO)代表将stm32f4xx*.c文件中的代码段,全局变量,静态变量编译进去。
   stm32f10x*.o (+RO)
   
  }
  RW_IRAM1 0x20000000 0x00030000  {  ; RW data
   .ANY (+RW +ZI)
  }
  RW_IRAM2 0x10000000 0x00010000  {
   .ANY (+RW +ZI)
  }
}
;LR_IROM1 是flash 0x08040000 0x08200000(低速区)区域
LR_IROM2 0x08040000 0x08200000  {    ; load region size_region
  ER_IROM2 0x08040000 0x08200000  {  ; load address = execution address
   .ANY (+RO)
   ;同理,这样就把user_a.c,user_b.c都编译进了低速区
   
  }
}

经过测试,发现正常了。终于解决GD32串口高波特率丢包问题。

2022.4.25

第二个问题是模拟I2C的问题,主板有一个时钟芯片PCF8563,采用GPIO模拟I2C来读写。改成GD后无法正常读取。

​​​​​​https://blog.csdn.net/lmgandxka/article/details/119932876?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=3

在CSDN查到这样一个类似的问题:模拟IIC的时序好像不同(没做具体测试,也可能与我使用的通信芯片有关),STM32是delay_us(2),GD改为STM32是delay_us(4)后正常。

按照此方法修改后果然可以正常通讯,初步推测是由于I2C代码在GD的高速区,所以采用空炒作来延时需要增加时间。

第三个问题是内部FLASH的IAP读写问题。主板的配置参数是存储在内部FLASH里的,改成GD芯片后,参数无法正常存入。 

 

查看芯片手册发现有这样一句: GD32F10x_XD,使用了两片闪存;前512KB容量在第一片闪存(bank0)中,后续的容量在第 二片闪存(bank1)中。其中bank0的闪存页大小为2KB,bank1的闪存页大小为4KB。

而之前用ST的芯片都是按每页2KB来处理的,存储参数用的又刚好是512KB之后的FLASH,所以改成GD芯片后,读操作应该可以按原来的操作都没问题,就是在擦除时按页擦除就有问题了,而写的时候通常要先擦除,所以这里需要修改擦除的代码。

修改对应代码后,功能正常。

举报

相关推荐

0 条评论