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

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

[复制链接]
wenyangzeng 提问时间:2015-7-3 21:05 /
阅读主题, 点击返回1楼
收藏 评论29 发布时间:2015-7-3 21:05
29个回答
watershade 回答时间:2015-7-4 14:06:44
随便问一下,你的PA9和PA10确定是只连接到了max3232,有没有可能是硬件上PA9和PA10有问题。或者和附近的走线有没有关联。

一种好的办法是你找块F4的经得起验证的板子试一下。乱码问题一般是硬件的问题。比如直接用ttl当作rs232输入输出都会造成乱码(又是不是烧掉)。
mark0668 回答时间:2015-7-4 14:09:38
wenyangzeng 发表于 2015-7-4 14:01
谢谢楼上,我就是只用USART,其他都不用,而且是在同一台开发板的不同GPIO口得到不同结果。 ...

1.jpg


2.jpg


看到你两个时钟有什么不同了吗? 第二个改错地方,串口1时钟没使能,
wenyangzeng 回答时间:2015-7-4 14:34:50
mark0668 发表于 2015-7-4 14:09
看到你两个时钟有什么不同了吗? 第二个改错地方,串口1时钟没使能,
...

谢谢楼上,我粘贴错了:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); //对不起,粘贴错了
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
wenyangzeng 回答时间:2015-7-4 14:36:24
watershade 发表于 2015-7-4 14:06
随便问一下,你的PA9和PA10确定是只连接到了max3232,有没有可能是硬件上PA9和PA10有问题。或者和附近的走 ...

我就是在工程板无法正常的情况下换用一片STM32F4-DISCOVERY来评估的。
回答时间:2015-7-4 16:09:10
现在用排除法来判断,先通过短接A9 A10,自测收发数据是否正常。
通过代码配置,没有4XX的板子帮忙测试。只能通过代码分析,也可以参考网友用STM32CubeMX测试一下。
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故障排除一例》,算了,就保持原来的也无妨。



所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版