首先硬件是OK的..
程序在上电后初始化UART4. Tx+Rx均使能. 最开始通讯是正常的.
当改动代码中很小的一部分程序. 重新编译后. Tx脚就成了低电平. 数据也发送不出去. 但Rx正常. 可以受到外面发送的数据.
程序的改动跟串口完全没有关系.改动后的代码也没有运行(必须进入某个对话框才会执行). 因此怀疑是原来系统中就隐藏着某个BUG. 在map编译链接改变后. 就导致了UART4不能发送.
哪位大侠可以告诉我,什么条件可以使得Tx一直为低?我通过IAR的调试插件观察寄存器.
发现异常时UART4的SR、CR与能正常工作的版本是一样的. TE RE UE 等几个重要bit都是1. 不知道是不是寄存器被篡改了. 但插件看不出来的缘故?.
救命啊...
又查看了一下. 异常时RCC的GPIO与UART4都是使能的. GPIO的配置寄存器也没有问题 AF_PP 50MHz
刚刚又重新写了一个函数. 光用于重新初始化UART4. 在进入某个菜单后调用此函数. 发现TX还是没有反应.
这个函数在另外一个工程里. USART_Cmd(ENABEL)后. Tx就为高了. 没有任何问题
到底是什么情况啊...晕
回楼上. 做了.. 很早久排除硬件的问题了. 更换了几快板卡也是同样的现象.
好像并不是其他的程序篡改了UART的寄存器.. 而是打算初始化UART的时候就出问题了
运行同一个串口初始化函数..
如果不改另外一个应用文件. 则USART_Cmd(UART4, ENABLE);后 Tx变高
如果改另外一个应用文件(map有很大变化). 则USART_Cmd(UART4, ENABLE);后 Tx仍是低
通过插件观察外设寄存器. 两者没有任何区别. UE都是由0->1
先确保硬件肯定没问题。
1. 写一个简单的uart测试程序。
2. 如果正常,那么用你现在的完整程序,先隐去其他部分,只保留uart初始化,然后while(1)发送,接收,看看TX是否正常。
3. 如果此时也正常,那么把其他代码打开,正常运行。 这时候看寄存器设置,是否被其他硬件初始化修改了。
一步一步,循序渐进,肯定能找到问题。
谢谢大家!问题已找到.与大家分享痛苦经历..
[这个问题绕了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版.
呵呵,谢谢分享。
另一个非常要注意的事情是:使用任何变量前,一定要先初始化这个变量。
那确实..
那个函数是我写的..自己在用时候在每一个分支里面都初始化了..但别人在添加功能的时候就没注意到了..结果就出错了.. 应该至少要在一开始给一个默认值
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;