你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F407的USART1只能映射到PB6-7,如果选择PA9-10就乱码

[复制链接]
wenyangzeng 提问时间:2015-7-3 21:05 /
阅读主题, 点击返回1楼
收藏 评论29 发布时间:2015-7-3 21:05
29个回答
qiu-368230 回答时间:2015-7-4 16:43:15
时钟打开了么
wenyangzeng 回答时间:2015-7-4 16:59:08

由于我是在同一块板上只改变PA和PB口来连接USART1,PB口工作正常,PA口也可以发送,只不过错码,时钟肯定是打开的,没有打开是无法发送的。
wenyangzeng 回答时间:2015-7-4 20:29:04
本帖最后由 wenyangzeng 于 2015-7-4 20:46 编辑
安 发表于 2015-7-4 16:09
现在用排除法来判断,先通过短接A9 A10,自测收发数据是否正常。
通过代码配置,没有4XX的板子帮忙测试。只 ...

感谢版主的关注。
按照您的建议先短接PA9-PA10做一次PA口的USART1实验,再短接PB6-PB7做一次PB口的USART1实验。分别从发送缓冲区送出22(0x0d,0x0a是结束符)个数据,然后观察接收缓冲区的数据。结果如下:
1、PA口实验
发送缓冲区数据
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x0d,0x0a

接收缓冲区数据

0x98,0xcc,0xee,0x77,0xf7,0xf7,0xff,0xb8,0xef,0xbd,0xbe,0xff,0x80,0xc0,0xe0,0xf0,0x00,0x00,0x00,0x00,0x00


2、PB口实验
发送缓冲区数据

0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x0d,0x0a

接收缓冲区数据

0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43

//#define P_A_EN 1            //使用PA口或PB口
#define USART_REC_LEN                          22
uint8_t USART_TX_BUF[ USART_REC_LEN], USART_RX_BUF[ USART_REC_LEN];
uint16_t  USART_RX_STA=0;  
//主函数
int main(void)
{uint8_t i;
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(9600);        
        for(i=0;i<20;i++)USART_TX_BUF=i+0x30;
        USART_TX_BUF[20]=0x0d;
        USART_TX_BUF[21]=0x0a;// 0D0A是给接收中断判断结束的标志
        for(i=0;i<20;i++)
        {
        USART_SendData(USART1,USART_TX_BUF);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);
        }
        __nop();
        while(1){;};

}

//usart初始化函数
void uart_init(uint32_t  bound)
{  GPIO_InitTypeDef GPIO_InitStructure;
   USART_InitTypeDef USART_InitStructure;
   NVIC_InitTypeDef NVIC_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
#ifdef  P_A _EN
        {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
        GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOA,&GPIO_InitStructure);
        }
#else
        {
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_USART1);
        GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_USART1);
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
        }
#endif
        USART_InitStructure.USART_BaudRate = bound;
        USART_InitStructure.USART_WordLength = USART_WordLength_8b;
        USART_InitStructure.USART_StopBits = USART_StopBits_1;
        USART_InitStructure.USART_Parity = USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
        USART_Init(USART1, &USART_InitStructure);
        USART_Cmd(USART1, ENABLE);
        USART_ClearFlag(USART1, USART_FLAG_TC);
        USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);        
}
//接收中断函数
void USART1_IRQHandler(void)
{
        uint8_t  Dat;
        if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
        {
                 Dat =USART_ReceiveData(USART1);
                if((USART_RX_STA&0x8000)==0)
                {
                        if(USART_RX_STA&0x4000)
                        {
                                if(Dat!=0x0a)USART_RX_STA=0;
                                else USART_RX_STA|=0x8000;
                        }
                        else
                        {        
                                if( Dat==0x0d)USART_RX_STA|=0x4000;
                                else
                                {
                                        USART_RX_BUF[USART_RX_STA&0X3FFF]= Dat ;
                                        USART_RX_STA++;
                                        if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
                                }                 
                        }
                }                    
  }


从上面接收数据判断,有可能是使用库函数对PA口进行波特率设置未能达到预设波特率值,而对PB口设置则能得到正确波特率。










yvonn 回答时间:2015-7-4 21:17:41
1。首先确认一下,初始化的都初始化了,ST的库函数,真正使用起来,很少使用断言函数来检查其输入的有效性,这就要求你除非你定义的是静态变量,否则,一定要是其处于你的可控状态。
2.既然楼主都说了,是乱码,那证明数据是有发送出来,那就看一下,是不是因为缺省了某些东西造成初始化的结果不理想。进入调试模式,一看便有结论
3.不要太相信库函数,即便是一行代码都有可能存在BUG,何况一堆,哈哈 希望对楼主有所帮助
wenyangzeng 回答时间:2015-7-5 07:58:28
本帖最后由 wenyangzeng 于 2015-7-6 09:50 编辑

发现STM32F4-DISCOVERY的PA口数据出错后,认为还是用数据来说话。临时编写一段代码,每隔0.1秒从发送端发送一次0x55,然后用示波器来观察数据发送状况。
    先在正常的PB口测试,结果见图1。
图1.jpg
            图1  STM32F4-DISCOVERY PB口正常的发送波形
    而从非正常的PA口发送,结果见图2.
图2.jpg
  图2  STM32F4-DISCOVERY PA口非正常的发送波形
    可以看到从PA口发送的数据严重变形,当然出现错码。查STM32F4-DISCOVERY手册,PA9,PA10是可以映射到USART1的,见图3。但是查看原理图,发现PA9在STM32F4-DISCOVERY板上已经外挂了不少外设,让它工作在USART1,不把这些外设断开肯定不行的。
图3.JPG
       图3  STM32F4-DISCOVERY PA口说明         

图4.JPG

                图4  STM32F4-DISCOVERY PA9
    从以上实验可以得出第一个结论:
    关于在STM32F4-DISCOVERY上使用PA口工作在USARU1不成功的原因是由于PA9上已经外挂了其他外设,发送端发送的数据在低电平时被这些外设拉高,从而出现图2所示非正常波形而导致通讯失败。
    教训:花点时间读读手册是很有用的,如果先读了手册再来调试,就不会走那么多弯路,时间反而会节省不少。
    接下来还要解决工程板的故障,才是最终目的。
同样对工程板的USART1发送端进行测试,发送0X55时的波形见图5,从图5中我们可以看出,发送的波形基本是正常的,但周期确比图2(3.8格)的要短(3.4格)。
图5.jpg
  图5 工程板的波形
   可见工程板工作不正常的原因是波特率偏高了。本例中波特率设定为9600,于是试将工程板的波特率降低看看,当降到9000时,USART的工作竟然正常了。天哪:竟然误差16%。先看看晶振再说。 图7.jpg
图6  STM32F4-DISCOVERY上的晶振频率8.00063 MHZ
图6.jpg
图7 工程板上的晶振频率 8.00065 MHZ
    晶振误差很小呀!这16%的波特率误差从何而来一时无法理解,如果找到原因一定再贴上来与大家分享。哪位网友有高招也欢迎赐教。
结论2:工程板上的通讯乱码是由于波特率误差太大所引起的,但同样的配置,误差达到16%确实从来没遇到过。而当在用 STM32F4-DISCOVERY验证时,恰好也是PA口的外挂引起工作不正常,让我误认为STM32F407的PA口用在USART1上会有问题,才有本帖的主题出现,按理应该改成《STM32F407 串行通讯USART1故障排除一例》,算了,就保持原来的也无妨。



watershade 回答时间:2015-7-5 22:54:36
用MX验证了一下,默认情况下在F4上PA9配置的是VBUS_FS,PA10连接的是OTD_FS_ID。而且有别针锁住,说明硬件有关联。和楼主的说法一致。但是PB6其实也连接到audio相关的CS43L22上了。尚不清楚为什么配置到PB6没问题。

不过我坚持以为是外围电路引起的。请注意PA9充当的是VBUS,也连接到了EMIF02-USB03F2这个芯片。这个片子是USB保护芯片,如果你想确认是不是它影响的话你可以尝试吧PA9设置成浮空输出看看电平是什么样子。我还没做实验,不过我估计很难拉低。不过没有试验过。

没有实验就没有发言权,以上只能算是估计。
祝你好运,你自己的板子PA9和PA10的状态看了吗?
watershade 回答时间:2015-7-5 23:08:43
不好意思,我的分析有问题:PA9当然能拉底。可能是受图中电路影响。如果方便可以焊去R56试试。

PA9连接部分

PA9连接部分
wenyangzeng 回答时间:2015-7-6 07:41:35
本帖最后由 wenyangzeng 于 2015-7-6 09:52 编辑

应该是C49充电把PA9一直拉高而出现锯齿波。20楼中的图2锯齿波可以很好解释C49在其中所起的关键作用。
未命名.JPG
北斗光寒 回答时间:2015-7-6 08:51:50
貌似有些意思   回头试试
废鱼 回答时间:2015-7-6 09:10:05
从波形来看,还有硬件电路的分析,应该是外设影响的。楼主可以测试一下接收是否正常。如果接收正常,说明发送引脚受到外设影响。
wjandsq 回答时间:2015-7-6 10:04:38

USB FS 和USART1(PA9 PA10)能同时用,本人已经测试过。

本帖最后由 wjandsq 于 2015-7-6 10:08 编辑

USART1(PA9 PA10)不可能有问题。连接OUT的线割掉就好了,电容影响发送。
wenyangzeng 回答时间:2015-7-6 22:29:05
本帖最后由 wenyangzeng 于 2015-7-6 22:45 编辑

为真正找出问题所在,临时编制一小段代码,每100mS让GPIOC_9翻转一次,用示波器观察波形周期。
while(1)
{
delay_ms(100);
GPIOC->ODR ^=0X0200;
};
照片 002.jpg
  图1 STM32F407-STM32F4-DISCOVERY上的正确波形

照片 003.jpg
         图2 故障机上的波形:2个延时周期只有7.2格
     现在终于能看到“庐山真面目”了,故障机MCU的工作周期比STM32F407-STM32F4-DISCOVERY缩短了1.2倍左右。这是导致故障机波特率偏高的原因。更换一只晶振后故障排除。就是还有点不明白的是用示波器直接测量晶振的工作频率(参见20楼的图6、 图7)为何2机的结果却都非常接近?
    至此,本贴终于得到圆满解决。换一只晶振所花费的时间不足1分钟,查找故障所花费的时间累计不少于24小时。虽然表面上看比例太悬殊。但能有一次这样的过程,机会实在难得,让我们长进不少。同时还节外生枝,导出对STM32F407-STM32F4-DISCOVERY的误判。     期间得到版主和许多网友的热情帮助。非常感谢!



watershade 回答时间:2015-7-10 22:32:05
wenyangzeng 发表于 2015-7-6 07:41
应该是C49充电把PA9一直拉高而出现锯齿波。20楼中的图2锯齿波可以很好解释C49在其中所起的关键作用。 ...

你说的很有可能,毕竟4.9uF也不小了。试过了吗?
watershade 回答时间:2015-7-10 22:36:08
wenyangzeng 发表于 2015-7-6 22:29
为真正找出问题所在,临时编制一小段代码,每100mS让GPIOC_9翻转一次,用示波器观察波形周期。
while(1)
{

楼主我不明白,那为什么你说PB可以PA不可以。难道你说的是你之前板子的晶振有问题?
又及,你换的是同一批次的还是更换了别的型号的?
wenyangzeng 回答时间:2015-7-12 08:53:31
watershade 发表于 2015-7-10 22:36
楼主我不明白,那为什么你说PB可以PA不可以。难道你说的是你之前板子的晶振有问题?
又及,你换的是同一 ...

回复楼上,故障经过大概是这样的:我的工程板绘制时USART1是接PA口,无法改接PB口进行验证。8M晶振频率偏高导致通讯失败后,用一片STM32F407DISCOVERY板来对比调试,恰好这片板的PA9连接了一部分外设,其中就有那只C49的电解电容,由于这只电容的滤波作用让PA口输出波形严重失真,得到这片板上的PA口接USART1也是失败的结论,而PB口由于没有那只滤波电容所以通讯成功。
      因为找到STM32F407DISCOVERY板PA口通讯错误的原因,才回过头来查找到工程板是晶振不良引起通讯失败的原因。同样是PA口通讯失败,原因却是不同的。
12
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版