发新帖我要提问
12
返回列表
打印
[研电赛技术支持]

STM32到GD32移植攻略

[复制链接]
楼主: 原来是wjc
手机看帖
扫描二维码
随时随地手机跟帖
21
原来是wjc|  楼主 | 2021-11-30 20:11 | 只看该作者 回帖奖励 |倒序浏览
解决方法:对于一般的通讯来说,不会有影响,只对于一般在通讯上有特殊协议的,才会产生数据不准确的情况所以,特定情况,修改程序。

使用特权

评论回复
22
原来是wjc|  楼主 | 2021-11-30 20:14 | 只看该作者
7. I2C 总线

    1) 硬件I2C 特殊配置

    描述:GD 的I2C 相对STM 的来说要少一个标志位

    解决方法

    1、宏地址定义改变

#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED

((uint32_t)0x00060002)

#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED

((uint32_t)0x00070002)

    2、硬件I2C 在会在向从机发送7bits 地址完成后,从机还没来得及识别。(看客户应用)我们可以在发送完7bits 后加个延时,让从机完全识别:

I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

{
int i = 0xfff;

while(i --);

}

    3、检测ADDR 不能使用I2C_CheckEvent 函数,因为他会清除ADDR,可以使用I2C_GetFlagStatus 函数。

就是把while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

改为while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));

    4、还有个关于编程步骤的严谨性,跟STM 想比,我们是先Clear_ACK,再Clear_ARRD。

使用特权

评论回复
23
原来是wjc|  楼主 | 2021-11-30 20:16 | 只看该作者
8. ADC 采集

    1) ADC 采样设置

    描述:ADC 启动

    解决方法:

    1. 当ADON=0 时写入1 后,需要等待一段时间t_WAIT,如果用ST 库的话就在ADC_CMD 后面加20us 左右的延时。

    2. 如果采用中断获得采样数据后,需要软件清除中断。

使用特权

评论回复
24
原来是wjc|  楼主 | 2021-11-30 20:17 | 只看该作者
9. SDIO

    1) SDIO DAT 3 pin 的在 1 bit bus mode 和4 bit bus mode 下的配置

    描述:

    1、 SDIO 在 1 bit bus mode 下,DAT 3 pin 是低电平,这样会导致 SD Card 进入SPI 模式。

    原因:初始化失败的原因主要是因为GD32 的芯片SDIO 的DAT3 口存在BUG。

    2、 在4 位模式下,通过上面的方法,程序能正常初始化,但不能正常读写SD卡。

    原因:因为DAT3 口在前面已经配置成推挽输出,所以在4 位模式下,不能正常读下。在调用4 位模式前,把DAT3 的端口配置成复用推挽输入即可解决问题。

使用特权

评论回复
25
原来是wjc|  楼主 | 2021-11-30 20:17 | 只看该作者
解决方法 1、 1 bit bus mode 的解决方法:建议在SDIO 使能之前,先把 SDIO DAT 3 pin 配置成推挽输出,并且要置成高电平,使 SDIO DAT 3 pin 保持高电平即可.

    2、 4 bit bus mode 的解决方法:在调用4 位模式前,把DAT3 的端口配置成复用输出即可解决问题。

    2) 程序在刚烧完后能正常读写SD 卡,断电再上电后,SD 卡初始化失败,需要手动复位一次后才正常

描述 在某些SD 卡中,GD32 断电再上电,会引起SD 卡上的时钟信号不正常,导致SD 卡发送命令失败。

使用特权

评论回复
26
原来是wjc|  楼主 | 2021-11-30 20:34 | 只看该作者
解决方法:在程序中,打开SD 卡时钟后,增加一小段延时,以保证SD 卡时钟信号稳定。这个延时添加的地方:在sdcard.c(即SDIO 的配置文件中),然后在SD_Error SD_Init(void)这个函数中找到SDIO_DeInit();就在这个后面加个延时。

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

SDIO_DeInit();

{
int i = 0xffff;

while(i --);

}

使用特权

评论回复
27
原来是wjc|  楼主 | 2021-11-30 20:41 | 只看该作者
10. USB

    A. USB_OTG

    1) 客户使用STM32 的DFU 原工程时需要注意几点

    解决方法:


    1、 在usb_istr.c 中,增加如下语句

for (i=0;i<8;i++) EP[i] = _GetENDPOINT(i);

for (i=0;i<8;i++)

_SetENDPOINT(i, EP[i] & 0x7070);

    2、 在usb_conf.h 中,按照下图红色字体语句进行修改

#if defined(STM32L1XX_MD) || defined(STM32L1XX_HD)||

defined(STM32L1XX_MD_PLUS)

#define INTERN_FLASH_SECTOR_ERASE_TIME 100

#define INTERN_FLASH_SECTOR_WRITE_TIME 104

#else

#define INTERN_FLASH_SECTOR_ERASE_TIME 100

#define INTERN_FLASH_SECTOR_WRITE_TIME 100

    3、 把固件库中的stm32f10x_flash.c 使用附件的进行替换。

    4、 软件进行读保护位时需要选使用FLASH_Unlock();函数

int main(void)

{
#if defined (USE_STM32L152D_EVAL)

FLASH_Unlock();

FLASH_ClearFlag(FLASH_FLAG_OPTVERRUSR);

#endif

FLASH_Unlock();

FLASH_ReadOutProtection(ENABLE);

FLASH_Lock();

使用特权

评论回复
28
原来是wjc|  楼主 | 2021-11-30 20:56 | 只看该作者
   2) 部分USB 兼容性

    解决方法:

    1. 部分U 盘有3 个端点,数组越界导致Itf_Desc 被清空,所以主机不能识别设备类型。USBH_conf.h 文件的USBH_MAX_NUM_ENDPOINTS 的定义由2 改成3 就可以了将:#define USBH_MAX_NUM_ENDPOINTS 2

改为:#define USBH_MAX_NUM_ENDPOINTS 3

使用特权

评论回复
29
原来是wjc|  楼主 | 2021-11-30 20:58 | 只看该作者
2. 在In 端点中断处理程序USB_OTG_USBH_handle_hc_n_In_ISR 中,对于NAK 中断,V1.0.0 版本的处理如下:

else if (hcint.b.nak)

{
if(hcchar.b.eptype == EP_TYPE_INTR)

{
UNMASK_HOST_INT_CHH (num);

USB_OTG_HC_Halt(pdev, num);

CLEAR_HC_INT(hcreg , nak);

}

else if ((hcchar.b.eptype == EP_TYPE_CTRL)||

(hcchar.b.eptype == EP_TYPE_BULK))

{
/* re-activate the channel */

hcchar.b.chen = 1;

hcchar.b.chdis = 0;

USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);

}

pdev->host.HC_Status = HC_NAK;

}

而V2.1.0 版本的NAK 处理过程如下:

else if (hcint.b.nak)

{
if(hcchar.b.eptype == EP_TYPE_INTR)

{
UNMASK_HOST_INT_CHH (num);

USB_OTG_HC_Halt(pdev, num);

}

else if ((hcchar.b.eptype == EP_TYPE_CTRL)||

(hcchar.b.eptype == EP_TYPE_BULK))

{
/* re-activate the channel */

hcchar.b.chen = 1;

hcchar.b.chdis = 0;

USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);

}

pdev->host.HC_Status[num] = HC_NAK;

CLEAR_HC_INT(hcreg , nak);


}

使用特权

评论回复
30
原来是wjc|  楼主 | 2021-11-30 21:03 | 只看该作者
  唯一的区别就是CLEAR_HC_INT(hcreg , nak)的位置,在V1.0.0 版本中对于CTRL 和BULK 端点的NAK 中断没有清除NAK,我们的芯片会因此产生多次IN 传输的请求,导致数据传输错 误。改为V2.1.1 的写法后传输正常。(注意HC_Status 在V2.1.0 是数组,在V1.0.0 是单个数据,直接拷贝的话要去掉后面的[num])

使用特权

评论回复
31
原来是wjc|  楼主 | 2021-11-30 21:07 | 只看该作者
B. USB 外设的工作频率有限制

    描述:有最低工作频率的要求,也就是APB1 分频后的时钟必须大于12MHz,比如HCLK 为56MHz,APB1 的最大分频系数为4,56/4 = 14MHz,可以正常工作。

使用特权

评论回复
32
原来是wjc|  楼主 | 2021-11-30 21:09 | 只看该作者
11. SPI

    1) 输入与输出配置要求(STM32 不需要如此要求)

    解决方法 :

    GD32 在使用SPI 时,IO 的配置必须严格遵守主从模式下的输入与输出配置,而STM32 无此要求,相关代码如下:主机模式下IO 配置(主机以SPI 为例):

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_Init(GPIOA,&GPIO_InitStructure);

从机模式下IO 配置(从机以SPI2 为例):

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15;

GPIO_Init(GPIOB,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;

GPIO_Init(GPIOB,&GPIO_InitStructure);

使用特权

评论回复
33
原来是wjc|  楼主 | 2021-11-30 21:23 | 只看该作者
  3) 在GD32 的SPI 的时钟信号,空闲状态需要配置成高电平,以保证数据的稳定性,具体代码如下

    解决方法

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;


SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure);

使用特权

评论回复
34
原来是wjc|  楼主 | 2021-11-30 21:24 | 只看该作者
4) 当作为从机时,在GD32 中,时钟信号必须为8 的整数倍。

    解决方法

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure);

    5) 在GD32 中,不能使用SPI_I2S_FLAG_BSY 该位来判断SPI 总线数据是否接收或发送完成。

使用特权

评论回复
35
原来是wjc|  楼主 | 2021-11-30 21:36 | 只看该作者
12. 看门狗

    1) 进入STOP 模式前打开看门狗,通过RTC 的ALR 唤醒后,程序会不断被复位的现像

    描述:IWDG 内部有个Reload 信号,KEY 寄存器写AAAA 会使其拉高,过一段时间自动拉低。在拉底之前进入STOP 状态会使Reload 信号一直为高,等到退出STOP 后也保持为高,之后再写AAAA 没有办法让Reload 产生上升沿,也就没办法更新计数器了。

    解决方法:进STOP 之前不要Reload,也可以调整下程序的顺序,把IWDG 的配置放到RTC配置之前,效果是一样的。

使用特权

评论回复
36
ZhaoB215| | 2022-9-26 10:55 | 只看该作者
你好博主,我想请问GD32f103VE串口发送数据一直乱码是什么原因?我是用的HAL库开发的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则