GD32F103ZKT6替换STM32F103调试手记

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

2022.4.20

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

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

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

2022.4.21

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

1)在网上找到这样一个可能的原因:GD32F103ZKT6替换STM32F103调试手记_第1张图片

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

GD32F103ZKT6替换STM32F103调试手记_第2张图片而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,导致每次中断内代码执行时间过长,波特率越高,中断频率越高,也就自然会丢失字节。
————————————————
版权声明:本文为CSDN博主「雪狐JXH」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_39525606/article/details/117925772

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

;LR_IROM1 是flash 0x08000000-0x08040000 (高速区)区域
LR_IROM1 0x08020000 0x08040000  {    ; load region size_region
  ER_IROM1 0x08020000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
   main.o (+RO)
   intr.o  (+RO)
   clock.o  (+RO)
   uart.o  (+RO)
   scom.o  (+RO)
   ;*是通配符,写过脚本的应该都理解,不理解的自行百度,这样就把stm32f4xx_it.c,stm32f4xx_hal_gpio.c都编译进了高速区
   ;(+RO)代表将stm32f4xx*.c文件中的代码段,全局变量,静态变量编译进去。
   stm32f10x*.o (+RO)
   
  }
  RW_IRAM1 0x20000000 0x00018000  {  ; RW data
   .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的低速区,所以采用空炒作来延时的时间指数性增加,导致整个I2C运行非常卡,不能正常读写。把模拟I2C通过分散加载到高速区后解决。

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

GD32F103ZKT6替换STM32F103调试手记_第3张图片

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

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

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

第四个问题是SPI读取AD7799的问题。

STM32里可以通过SPI正常读取AD7799,而换成GD后则不能。在网上查到这样一句话:“GD32 在使用SPI 时,IO 的配置必须严格遵守主从模式下的输入与输出配置,而STM32 无此要求”,GD芯片手册上写到:输入引脚配置为浮空输入模式,而之前STM32都是配置复用推挽输出(GPIO_Mode_AF_PP)。SPI主模式下MISO引脚为输入引脚,因此需要把MISO配置为浮空输入模式(GPIO_Mode_IN_FLOATING)

第五个问题是EXMC读取NAND FLASH的问题

直接沿用原来在STM32的驱动,发现写入的数据再读出来以后会错位,刚好往后移了一个字节。查看GD32关于EXMC操作NAND FLASH的内容,发现有这么一段:

GD32F103ZKT6替换STM32F103调试手记_第4张图片

 核对了一下这个位置的参数,原来配的分别是0-1-2-0,问题就出在这里,把参数改为0-1-2-1后,读取就正常了。分析原因应该是如果存储器建立时间设置为0,那么并没有等到存储器建立就去读取了数据,读的第一个字节很可能是错误的信息。

你可能感兴趣的:(嵌入式编程,stm32,c语言,mcu,驱动开发,arm)