flynnjiang

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang  发布于  2016-12-06 10:26:40
采纳率 0%
14个问答
11034

【已解决】3516A UART1 / RS485 只能发送,不能接收

 
本帖最后由 flynnjiang 于 2016-12-7 11:05 编辑

大家好,我在论坛里搜了一下,只看到有提问相关问题的,但都没有解决办法,哪位大哥了解这个的能指点一下不?
我目前做了以下尝试:
* 设置好了PIN管脚复用
* 尝试直接从3516A的管脚直接引出UART1_RX,UART1_TX,排除485芯片的RTS,CTS问题,但仍然如此
* 尝试修改UART1_CR(0x20090030)控制寄存器,从0x101改为0xF01,但总会自动变回0x101

问题主要是目前直接从3516引出UART1_RXD和UART1_TXD都这样,应该能排除是485引起的方向问题吧?。另外,UART1除了RX,TX外,还提供了RTSN和CTSN,这两个管脚我是不是要怎么处理一下?

还请大神指点一下,谢谢!


===========================================================

说明:
我没有实现半双工,因为目前我只需要用到接收模式,所以只是固定在了接收模式,可以正常接收数据。


解决步骤:
1.管脚复用配置和485芯片配置
UART1_RXD, UART1_RXD要复用成TX/RX,UART1_RTSN和CTSN我复用成了GPIO,用于配置485的方向,即485芯片的/RE和DE。
/RE是接收状态OK,DE是发送状态OK。因为我是接收模式,所以我把其都配置为低。

ps:因为我的原理图把RTSN和CTSN 都接了,所以我两个都配了。

[code]
/app/bin # cat 485.sh
#!/bin/sh

############## PIN MUTEX ###############

# 00:GPIO9_2, 01:UART1_RTSN, 10:UART3_RXD
himm 0x200f0078 0x0 # GPIO9_2

# 0:GPIO9_3, 1:UART1_RXD
himm 0x200f007c 0x1 # UART1_RXD

# 00:GPIO9_4, 01:UART1_CTSN, 10:UART3_TXD
himm 0x200f0080 0x0 # GPIO9_4

# 0:GPIO9_5, 1:UART1_TXD
himm 0x200f0084 0x1 # UART1_TXD


# GPIO CFG
himm 0x201d0400 0x017  # 配置为GPIO输出,我这里还包含了其它的GPIO,可以自己调整

# GPIO9_2/RTSN
himm 0x201d0010 0x0  # 配置为低
#himm 0x201d0010 0x4

# GPIO9_4/CTSN
himm 0x201d0040 0x0 # 也配置为低
#himm 0x201d0040 0x10
/app/bin #

[/code]


2.串口参数设置

如果你发现UART_DR寄存器里都已经有值了,但就是读不出来,这时应该是串口的参数没配好。
(其实PC端此时发送一个CTRL-D (EOT)的话,它也能read()到)。串口参数比较繁杂,我配了以下这些,
使用的是原始(RAW)模式,可参考修改。






另外,可以用stty看一下当前串口的配置信息,以及“cat /proc/tty/driver/ttyAMA”看TX/RX的变化。


[code]
/app/bin # stty  -a -F /dev/ttyAMA1
speed 9600 baud;stty: /dev/ttyAMA1
line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = ;
eol2 = ; swtch = ; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 0; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff
-iuclc -ixany -imaxbel -iutf8
-opost -olcuc -ocrnl -onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0
ff0
-isig -icanon iexten -echo -echoe echok -echonl -noflsh -xcase -tostop -echoprt
echoctl echoke
/app/bin #
/app/bin #
/app/bin #
/app/bin # cat /proc/tty/driver/ttyAMA
serinfo:1.0 driver revision:
0: uart:PL011 rev2 mmio:0x20080000 irq:40 tx:238321 rx:48113 RTS|CTS|DTR|DSR|CD|RI
1: uart:PL011 rev2 mmio:0x20090000 irq:41 tx:0 rx:756 RTS|DTR|DSR|CD|RI
/app/bin #

[/code]
我来回答
回答18个
时间排序
认可量排序

fobyellow

0个粉丝

6

问答

0

专栏

0

资料

fobyellow 2016-12-06 10:30:47
认可0
海思的参考设计上使用RTSN来做485的方向设置,收的时候需要当GPIO切换方向

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 10:31:40
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42465&ptid=13585]fobyellow 发表于 2016-12-6 10:30[/url]
海思的参考设计上使用RTSN来做485的方向设置,收的时候需要当GPIO切换方向[/quote]




大哥,我现在电路搞成这样了,还有的改吗?

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 10:33:31
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42466&ptid=13585]flynnjiang 发表于 2016-12-6 10:31[/url]
大哥,我现在电路搞成这样了,还有的改吗?[/quote]

好像还有的救,我先试试,谢谢大哥!

fobyellow

0个粉丝

6

问答

0

专栏

0

资料

fobyellow 2016-12-06 11:03:08
认可0
请教下问题,我们使用UART1做485的半双工接口,收发都没有问题,但是在发送的时候,无法判断是否已经发送完成,我们现在的处理办法是发送后延时一段时间后切换到接收状态,会遇到外设响应太快总线发生冲突的问题,求解决思路,谢谢!

falloutmx

1个粉丝

15

问答

0

专栏

0

资料

falloutmx 2016-12-06 11:13:11
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42470&ptid=13585]fobyellow 发表于 2016-12-6 11:03[/url]
请教下问题,我们使用UART1做485的半双工接口,收发都没有问题,但是在发送的时候,无法判断是否已经发送完 ...[/quote]

直接在amba-pl011.c发送完成的函数里修改吧

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 11:26:30
认可0
再次请教下2位大哥,我现在把R97接上了,R247是断开的。 根据/RE和DE来看,我是不应该这样配置呢?

读取模式:RTSN->0, CTSN->0
发送模式:RTSN->1, CTSN->1

我对底层不太熟,请教下。另外,如果我只需要接收模式的话,是不是GPIO就可以这样长期配死了?

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 11:35:59
认可0

全部配低:

3516A往串口写数据,tx/rx都增加;从PC写数据,然后3516读数据,tx/rx也都增加




全部配高:

3516A往串口写数据,只有tx增加;从PC写数据,然后3516读数据,tx/rx都不增加



PS:现在RX总算有反映了,之前是怎么搞都没动静,一直为零。

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 11:37:48
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42470&ptid=13585]fobyellow 发表于 2016-12-6 11:03[/url]
请教下问题,我们使用UART1做485的半双工接口,收发都没有问题,但是在发送的时候,无法判断是否已经发送完 ...[/quote]

大哥,能把你的寄存器配置和485那块的原理图分享一下不,感激不尽!我还是没搞通

fobyellow

0个粉丝

6

问答

0

专栏

0

资料

fobyellow 2016-12-06 13:14:43
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42487&ptid=13585]flynnjiang 发表于 2016-12-6 11:26[/url]
再次请教下2位大哥,我现在把R97接上了,R247是断开的。 根据/RE和DE来看,我是不应该这样配置呢?

读取 ...[/quote]

看你的图纸应该需要把两个电阻都焊上

fobyellow

0个粉丝

6

问答

0

专栏

0

资料

fobyellow 2016-12-06 13:15:42
认可0
如果是使用现成的海思驱动就把两个都焊上,如果只接受可以固定状态

fobyellow

0个粉丝

6

问答

0

专栏

0

资料

fobyellow 2016-12-06 13:16:37
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42489&ptid=13585]flynnjiang 发表于 2016-12-6 11:37[/url]
大哥,能把你的寄存器配置和485那块的原理图分享一下不,感激不尽!我还是没搞通[/quote]

我的图纸就是海思的图纸,寄存器我没有,我是搞硬件的

flynnjiang

0个粉丝

14

问答

0

专栏

0

资料

flynnjiang 2016-12-06 15:46:54
认可0
本帖最后由 flynnjiang 于 2016-12-6 16:33 编辑

[quote][url=forum.php?mod=redirect&goto=findpost&pid=42500&ptid=13585]fobyellow 发表于 2016-12-6 13:16[/url]
我的图纸就是海思的图纸,寄存器我没有,我是搞硬件的[/quote]

2两个电阻全接上了还是不行。RTS/CTS全部配高,3516可以成功发送,全部配低,接收还是不通……
用示波器看,PC过来的数据好像已经通过485到了3516的管脚了,可是就是“cat /dev/ttyAMA1”不到,另外,“cat /proc/tty/driver/ttyAMA”可以看到rx在增加。


查看数据寄存器(0x20090000),寄存器里的数据也是PC发过来的字符,但就是read没有反映,有大神了解吗?

chengyinbing

1个粉丝

5

问答

0

专栏

0

资料

chengyinbing 2017-04-06 15:13:09
认可0
请问UART1不能接收的问题解决了吗?

chengyinbing

1个粉丝

5

问答

0

专栏

0

资料

chengyinbing 2017-04-06 15:13:45
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42510&ptid=13585]flynnjiang 发表于 2016-12-6 15:46[/url]
2两个电阻全接上了还是不行。RTS/CTS全部配高,3516可以成功发送,全部配低,接收还是不通……
用示波 ...[/quote]

请问UART1不能接收的问题解决了吗?

chengyinbing

1个粉丝

5

问答

0

专栏

0

资料

chengyinbing 2017-04-06 17:02:09
认可0
问题已解决,不是硬件问题,是参数设置问题:请参考以下代码
#include
#include
#include
#include

#define RS485_DEV                        "/dev/ttyAMA1"

CRS485::CRS485()
{
    hasRs485Inited = false;
    mFd = -1;
}

CRS485::~CRS485()
{
    DEBUG_INFO(DEV_MNG, "RS485 exit");
    if( mFd != -1 )
    {
        close( mFd );
    }
    hasRs485Inited = false;
}

int CRS485::setRS485(int band, int stopBit, int parity, int dataBit)
{
    int status = -1;

    struct termios options;
    tcgetattr( mFd, &options );
    tcflush( mFd, TCIOFLUSH ); // discard data written to RS485 that hasn't not been transmitted
    // set band rate
    switch( band )
    {
    case 1200:
        cfsetispeed( &options, B1200 );
        cfsetospeed( &options, B1200 );
        break;
    case 2400:
        cfsetispeed( &options, B2400 );
        cfsetospeed( &options, B2400 );
        break;
    case 4800:
        cfsetispeed( &options, B4800 );
        cfsetospeed( &options, B4800 );
        break;
    case 9600:
        cfsetispeed( &options, B9600 );
        cfsetospeed( &options, B9600 );
        break;
    case 19200:
        cfsetispeed( &options, B19200 );
        cfsetospeed( &options, B19200 );
        break;
    case 38400:
        cfsetispeed( &options, B38400 );
        cfsetospeed( &options, B38400 );
        break;
    case 57600:
        cfsetispeed( &options, B57600 );
        cfsetospeed( &options, B57600 );
        break;
    default:
        DEBUG_ERROR(DEV_MNG, "Band rate:%d is not supported, now use 9600", band);
        cfsetispeed( &options, B9600 );
        cfsetospeed( &options, B9600 );
        break;
    }
    status = tcsetattr( mFd, TCSANOW, &options );
    if( status != 0 )
    {
        DEBUG_API_ERROR( DEV_MNG, "tcsetattr(TCSANOW)");
        return -1;
    }
    tcflush( mFd, TCIOFLUSH );

    status = tcgetattr( mFd, &options );
    if( status < 0 )
    {
        DEBUG_API_ERROR( DEV_MNG, "tcgetattr()");
        return -1;
    }

    // set data bits
    options.c_cflag &= (~CSIZE);
    switch( dataBit )
    {
    case 5:
        options.c_cflag |= CS5;
        break;
    case 6:
        options.c_cflag |= CS6;
        break;
    case 7:
        options.c_cflag |= CS7;
        break;
    case 8:
        options.c_cflag |= CS8;
        break;
    default:
        DEBUG_ERROR(DEV_MNG, "Unsupported data bits(%d)", dataBit);
        return -1;
        break;
    }

    // set parity
    switch( parity )
    {
    case 0: // None
        options.c_cflag &= (~PARENB);
        options.c_iflag &= (~INPCK);
        break;
    case 1: // ODD
        options.c_cflag |= (PARODD | PARENB);
        options.c_iflag |= INPCK;
        break;
    case 2: // Even
        options.c_cflag |= PARENB;
        options.c_cflag &= (~PARODD);
        options.c_iflag |= INPCK;
        break;
    default:
        DEBUG_ERROR(DEV_MNG, "Unsupported parity type:%d", parity);
        return -1;
        break;
    }

    // set stop bits
    switch( stopBit )
    {
    case 1:
        options.c_cflag &= (~CSTOPB);
        break;
    case 2:
        options.c_cflag |= CSTOPB;
        break;
    default:
        DEBUG_ERROR(DEV_MNG, "Unsupported stop bits:%d", stopBit);
        return -1;
        break;
    }
    /* Set input parity option */
    if (parity != 0)
        options.c_iflag |= INPCK;
    /* Set Raw Mode */
    options.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);  /*Input*/
    options.c_oflag  &= ~OPOST;   /*Output*/
    tcflush( mFd, TCIFLUSH );
    options.c_cc[VTIME] = 150;
    options.c_cc[VMIN] = 7;

    status = tcsetattr( mFd, TCSANOW, &options );
    if( status != 0 )
    {
        DEBUG_API_ERROR(DEV_MNG, "tcsetattr()");
        return -1;
    }

    return 0;
}

int CRS485::init(int band, int stopBit, int parity, int dataBit)
{
    if( hasRs485Inited )
    {
        DEBUG_ERROR(DEV_MNG, "RS485 has been inited");
        return -1;
    }

    int ret = -1;

    // open device
    mFd = open( RS485_DEV, O_RDWR );
    if( mFd < 0 )
    {
        DEBUG_API_ERROR(DEV_MNG, "open()");
        return -1;
    }

    ret = setRS485(band, stopBit, parity, dataBit);
    if(ret == -1)
        goto ERROR;

    // success
    hasRs485Inited = 1;
    DEBUG_INFO(DEV_MNG, "RS485 init success");
    return 0;

ERROR:
    close( mFd );
    return -1;
}

int CRS485::sendData(char *data, int dataLen)
{
    if( data == NULL )
        return -1;
    if( dataLen <= 0 )
        return -1;

    if( hasRs485Inited != 1 )
    {
        DEBUG_ERROR(DEV_MNG, "Can't send 485 data before inited");
        return -1;
    }

    return write( mFd, data, dataLen );
}

int CRS485::recvData(char *data, int dataLen, int maxWaitTime)
{
    if( data == NULL )
        return -1;
    if( dataLen <= 0 )
        return -1;

    if( hasRs485Inited != 1 )
    {
        DEBUG_ERROR(DEV_MNG, "Can't recv 485 data before inited");
        return -1;
    }

    int index = 0;
    int rc = 0;
    int rcnum = dataLen;
    struct timeval tv;
    fd_set readfd;
    tv.tv_sec = maxWaitTime / 1000;
    tv.tv_usec = maxWaitTime % 1000 * 1000;
    FD_ZERO(&readfd);
    FD_SET(mFd, &readfd);
    rc = select(mFd + 1, &readfd, NULL, NULL, &tv);
    if(rc > 0)
    {
        while(dataLen)
        {
            rc = read(mFd, &data[index], 1);
            if(rc > 0)
                index = index + 1;
            dataLen = dataLen - 1;
        }
        if(index != rcnum)
            return -1;
        return rcnum;
    }
    else
    {
        return -1;
    }
    return -1;

    //return read( mFd, data, dataLen );
}

majinzhu

0个粉丝

1

问答

0

专栏

0

资料

majinzhu 2017-04-06 18:49:27
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42500&ptid=13585]fobyellow 发表于 2016-12-6 13:16[/url]
我的图纸就是海思的图纸,寄存器我没有,我是搞硬件的[/quote]

大哥,有没有GV7601接入hi3516的参考设计让我学习下?

13915426184

0个粉丝

15

问答

0

专栏

0

资料

13915426184 2017-09-08 10:40:27
认可0
楼主你说参数配置出错,但是你给的程序里面没有地方调用了init函数,所以没法看到你到底配成了什么参数啊,请问你能把对应的参数给出来一下吗?谢谢

qn1523580863

0个粉丝

2

问答

0

专栏

0

资料

qn1523580863 2018-04-24 01:23:46
认可0
[quote][url=forum.php?mod=redirect&goto=findpost&pid=42510&ptid=13585]flynnjiang 发表于 2016-12-6 15:46[/url]
2两个电阻全接上了还是不行。RTS/CTS全部配高,3516可以成功发送,全部配低,接收还是不通……
用示波 ...[/quote]

我网上查到了一下资料,好像配置串口的时候要配对,才能正确接收和发送
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区