????????最近在做一个项目,由于没有ST的芯片了,只有用GD的,但用的还是ST的标准库,所以还是按照原ST的USART配置。该型号单片机中有5个串口,用了前3个,软件测试过程中USART1、USART3都是可以正常收发的,唯独用到的USART2不行。
? ? ? ? 该问题困扰了我很久,光是这个USART2的配置前前后后看了不下10遍,确认真的没问题呀!由于手头有没有改对应型号的ST单片机,无法验证在ST是否也是这样,所以想当然的怪到了国产芯片GD的头上——不稳定!(后面证明怪我鲁莽了)。
? ? ? ? 先讲一下我为啥开始怪单片机,怀疑是有问题的,因为我配置正常的情况下,它的USART2的Tx引脚,根本没波形呀!这换成谁都会怀疑。我都去他们论坛发帖求助了,看的人不少,没一个回答的,只有自己再慢慢找了。同样的配置,USART3有输出,我又把程序初始部分捋了一遍,确定USART2的引脚后面没有被初始化为其它外设,结果还是不行!
? ? ? ? 这个时候开始不是程序配置的问题了,是不是可能从BootLoader跳过来的时候出问题了,于是不进行地址偏移,把代码一改,烧录地址再改一下,再次烧录。
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000); ? ? ? ? ? ? ?//重新映射中断向量表?? ?
?? ?__set_PRIMASK(0); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //开启总中断
? ? ? ? 重新抓取USART2的Tx引脚波形,有了!然后就把问题定位到我的引导程序中了。
打开引导程序,看到USART的配置,瞬间明了。配置如下
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
//配置USARTx_Tx为复合推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
//配置 USARTx_Rx 为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap_USART2,ENABLE);
? ? ? ? USART2的引脚直接被完全映射到PD5、PD6了,这个型号的单片机USART2不能被映射,给出官方数据。
?
? 我直接把引导中的USART2注释掉,反正也用不到,再重新烧录引导和应用程序,USART2有数据。另外我还专门在引导不注释USART2的配置情况下,烧录应用程序,Debug看了下寄存器,果然USART2的重映射寄存器被置1了。
?
?PS:GD的单片机USART是从0开始的。USART0、USART1、USART2·····
这就是单片机从100Pin改为64Pin遇到的坑呀,以后一定多加注意!回头再用ST的单片机试一下。
?
? ? ? ??
|