UART4Tx为低电平.数据无法发送..请教

weilwo   2010-1-29 08:45 楼主
首先硬件是OK的..

程序在上电后初始化UART4. Tx+Rx均使能. 最开始通讯是正常的.

当改动代码中很小的一部分程序. 重新编译后. Tx脚就成了低电平. 数据也发送不出去. 但Rx正常. 可以受到外面发送的数据.

程序的改动跟串口完全没有关系.改动后的代码也没有运行(必须进入某个对话框才会执行). 因此怀疑是原来系统中就隐藏着某个BUG. 在map编译链接改变后. 就导致了UART4不能发送.

哪位大侠可以告诉我,什么条件可以使得Tx一直为低?我通过IAR的调试插件观察寄存器.
发现异常时UART4的SR、CR与能正常工作的版本是一样的. TE RE UE 等几个重要bit都是1.  不知道是不是寄存器被篡改了. 但插件看不出来的缘故?.

救命啊...

回复评论 (10)

又查看了一下. 异常时RCC的GPIO与UART4都是使能的. GPIO的配置寄存器也没有问题 AF_PP 50MHz

刚刚又重新写了一个函数. 光用于重新初始化UART4.  在进入某个菜单后调用此函数. 发现TX还是没有反应.

这个函数在另外一个工程里. USART_Cmd(ENABEL)后. Tx就为高了. 没有任何问题

到底是什么情况啊...晕
点赞  2010-1-29 10:43
                                 做一个简单的程序,先看看硬件有没有问题。
点赞  2010-1-29 11:12
                                 回楼上.  做了.. 很早久排除硬件的问题了. 更换了几快板卡也是同样的现象.
点赞  2010-1-29 13:32
好像并不是其他的程序篡改了UART的寄存器.. 而是打算初始化UART的时候就出问题了

运行同一个串口初始化函数..

如果不改另外一个应用文件. 则USART_Cmd(UART4, ENABLE);后 Tx变高
如果改另外一个应用文件(map有很大变化). 则USART_Cmd(UART4, ENABLE);后 Tx仍是低

通过插件观察外设寄存器. 两者没有任何区别. UE都是由0->1
点赞  2010-1-29 13:32
                                 先测试一下硬件,再找其他原因
点赞  2010-1-29 14:54
先确保硬件肯定没问题。
1. 写一个简单的uart测试程序。
2. 如果正常,那么用你现在的完整程序,先隐去其他部分,只保留uart初始化,然后while(1)发送,接收,看看TX是否正常。
3. 如果此时也正常,那么把其他代码打开,正常运行。 这时候看寄存器设置,是否被其他硬件初始化修改了。

一步一步,循序渐进,肯定能找到问题。
点赞  2010-1-29 15:51
谢谢大家!问题已找到.与大家分享痛苦经历..

[这个问题绕了2个弯.
程序初始化AHB外设时钟时.使用了一个未赋值的临时变量作为外设掩码输入. 导致错误的把SDIO的时钟打开了.
STM32勘误表中提到了如果要使用SDIO就不能使用UART4_TX. 两者会有冲突. 因此即使正确的初始化了GPIO与UART寄存器Tx也不会为高电平.

而改动应用程序将导致内存map发生变化. 局部变量的初始值也有所差别. 某些情况下不会将SDIO外设时钟打开. 故可正常运行.]

其实一开始我知道肯定是哪个地方内存出现问题了, 但死也找不到. 因为通过插件看GPIO, UART, RCC几个寄存器值完全配置正确了. 还不能工作.
有一次点击寄存器列表的时候打开了AHB看了一下,发现SDIOEN = 1. 而程序并没有使用SDIO. 当时没在意.
后面在看勘误表的时候发现SDIO与UART4_TX有冲突...才想起问题的所在.. 很快就定位了..

最后..血的教训:画原理、写驱动前一定要看勘误表!!! 在AT91,STM32上已经出了4-5个相关的问题了. 至少导致重新做了2版.
点赞  2010-1-29 16:23
呵呵,谢谢分享。

另一个非常要注意的事情是:使用任何变量前,一定要先初始化这个变量
点赞  2010-1-29 16:36
                                 是的,完全赞同,一定要初始化
点赞  2010-1-29 18:18
那确实..
那个函数是我写的..自己在用时候在每一个分支里面都初始化了..但别人在添加功能的时候就没注意到了..结果就出错了..  应该至少要在一开始给一个默认值

int a;
int b;
int c;

if  (x == 1)
{
    a = 1;
    b = 2;
    c  = 3;
}
else if (x == 2)
{
   ...
}
else if (别人添加的)
{
    a = 1;
    c  = 2;
}

#use a;
#use b;
#use c;
点赞  2010-1-29 20:30
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复