请教一个串口通讯问题:232\485方式可通过跳线转变,232调通,485异常

goldfree   2008-6-12 16:49 楼主
  各位路过的大虾,请留步,帮忙看一下是什么问题:
      我使用的是研华的板子,串口芯片为0x16pci954,其中有4个串口可通过跳线方式进行通讯方式的转换,232/422/485,485支持自动流控制,我在vxworks测试程序中对串口进行初始化后,进行读写测试,通过另外一台pc与之相连进行检验。在232状态下进行测试数据收发完全正常,然而在485方式下收发都没有数据显示,我所做的改动仅仅就是跳线,其它地方未做改动。485口我专门做了检验,在xp系统下完全没有问题,不知道是什么原因导致这个现象,希望大家能给点建议,实在是没有头绪。。。
  谢谢驻足!

回复评论 (8)

对了,补充一点,当我控制其发送数据时,发送指示灯亮了,表示确实发送了,但是事实上另一端却没有收到数据;这几个通讯口为3,4,5,6,我把其中任何两个相连,双方都可以发送但对方都收不到数据,当我将该设备自身其它正常的通讯口com7与3456中的一个通讯口相连时,3456能收到数据,但是乱码,而com7则收不到任何数据。
点赞  2008-6-12 16:57
1、用示波器;
2、RS232/485在程序上可能有不同,区别在于RS485有总线占用控制,去看一下RS485的驱动芯片。。。
点赞  2008-6-12 20:01
1. 没有电路,无法确认硬件是否正确。
2. 没有配置,不知道各个相关配置是否正确。
3. 没有程序,不知道程序设计是否正确。

    还是自己用示波器慢慢抓波形看吧。
点赞  2008-6-12 21:41
先谢过楼上各位,我在xp系统测试过这些问题串口,完全正常。排除硬件问题。现把测试程序贴出来,大家帮忙看一下:
在232情况下是没有问题的:
#include "vxworks.h"
#include "stdio.h"
#include "stdLib.h"
#include "sysLib.h"
#include "ioLib.h"
#include "taskLib.h"
#include "math.h"
#include "string.h"
#include "logLib.h"
#include "copyright_wrs.h"
#include "intlib.h"
#include "iv.h"
#include "drv/pci/pciConfigLib.h"
#include "drv/pci/pciIntlib.h"
#include "drv/sio/ns16552Sio.h"

#define EXTEND_COM_NUM                                                4
#define OX16PCI954_VENDERID                         0x13FE
#define OX16PCI954_DEVID                                        0X1600
#define OX16PCI954_BOARDNO                                0
#define OX16PCI954_UART_REG_DELTA 4 /*Memory Access Mode*/
#define OX16PCI954_UART_XTAL                        14745600
#define OX16PCI954_DEFAULT_BAUD                9600

UINT32 OX16PCI954_IOBASE[EXTEND_COM_NUM];
UINT32 OX16PCI954_MEMBASE[EXTEND_COM_NUM];
UINT32 OX16PCI954_LCLMEMBASE;
int pciBusNum;
int pciDeviceNum;
int pciFuncNum;
UINT8 OX16PCI954_INT_LINE;
static NS16550_CHAN ox16pci954Chan[EXTEND_COM_NUM];

LOCAL void OX16PCI954Int(void);

/******************************************************************************************
*  函数名称:ox16pci954getInfo
*  功能描述: 读取OX16PCI954 PCI设备信息,
*
*  输入参数: 无
*                       
*  输出参数: 无
*
*  返回值:   int,读取正常返回TRUE,异常返回FALSE
*
******************************************************************************************/
int ox16pci954getInfo(void)
{
        UINT32 i;
        if (pciFindDevice(OX16PCI954_VENDERID, OX16PCI954_DEVID, OX16PCI954_BOARDNO,
                                                                                        &pciBusNum, &pciDeviceNum, &pciFuncNum) != OK)
        {
                printf("The %d board's OX16PCI954 pciFindDevice error.\n", OX16PCI954_DEVID);
                return (FALSE);
        }
       
        /*读各个串口的I/O基地址*/
        pciConfigInLong(pciBusNum, pciDeviceNum, pciFuncNum, PCI_CFG_BASE_ADDRESS_0, &(OX16PCI954_IOBASE[0]));
        OX16PCI954_IOBASE[0] &= 0Xfffffffe;
        for (i = 1; i < EXTEND_COM_NUM; i++)       
        {
                OX16PCI954_IOBASE = OX16PCI954_IOBASE[0] + 8 * i;
        }
                                       
        /*读各个串口的内存基地址和中断线*/
        pciConfigInLong(pciBusNum, pciDeviceNum, pciFuncNum, PCI_CFG_BASE_ADDRESS_1, &(OX16PCI954_MEMBASE[0]));
        pciConfigInByte(pciBusNum, pciDeviceNum, pciFuncNum, PCI_CFG_DEV_INT_LINE, &(OX16PCI954_INT_LINE));
        for (i = 1; i < EXTEND_COM_NUM; i++)
        {
                OX16PCI954_MEMBASE = OX16PCI954_MEMBASE[0] + OX16PCI954_UART_REG_DELTA * 8 * i;
        }
       
        /*读PCI LOCAL基地址*/
        pciConfigInLong(pciBusNum, pciDeviceNum, pciFuncNum, PCI_CFG_BASE_ADDRESS_3, &(OX16PCI954_LCLMEMBASE));
       
        return (TRUE);
}

/******************************************************************************************
*  函数名称:OX16PCI954Init
*  功能描述: 初始化OX16PCI954设备结构,使串口设备进入工作的状态。由于硬件使用4个串口设备,
*                                                 因此函数对4个串口设备初始化
*                                                 挂接OX16PCI954Int中断服务程序。
*
*  输入参数: 无
*                       
*  输出参数: 无
*
*  返回值:   void
*
******************************************************************************************/
void OX16PCI954Init(void)
{
        int i;
       
        if (ox16pci954getInfo() == FALSE)
        {
                printf("Getting PCI info error.\n");
                return;
        }

        for (i = 0; i < EXTEND_COM_NUM; i++)
        {
                ox16pci954Chan.regs = OX16PCI954_MEMBASE;
                ox16pci954Chan.level = OX16PCI954_INT_LINE;
                ox16pci954Chan.regDelta = OX16PCI954_UART_REG_DELTA;
                ox16pci954Chan.xtal = OX16PCI954_UART_XTAL;
                ox16pci954Chan.baudRate = OX16PCI954_DEFAULT_BAUD;
                ox16pci954Chan.ier = 0x40;
               
    /* Disable the UART */
    *((char *)(ox16pci954Chan.regs + (IER * ox16pci954Chan.regDelta))) = 0;

    /* Reset FIFOs */
    *((char *)(ox16pci954Chan.regs + (FCR * ox16pci954Chan.regDelta))) = 6;       
                                                               
                ns16550DevInit(&ox16pci954Chan);
               
/*                (void) pciIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ox16pci954Chan.level + 0x20),
                           (VOIDFUNCPTR) ns16550Int, &ox16pci954Chan);*/
                /*printf("COM%d initialized OK.\n", i+3);*/
        }
       

        (void) pciIntConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(OX16PCI954_INT_LINE + 0x20),
                                                                                                        (VOIDFUNCPTR) OX16PCI954Int, 0);
       
        sysIntEnablePIC(ox16pci954Chan[0].level);  
}
/******************************************************************************************
*  函数名称:OX16PCI954Int
*  功能描述: OX16PCI954设备的中断服务程序,响应4个串口中断.
*
*  输入参数: 无
*                       
*  输出参数: 无
*
*  返回值:   void
*
******************************************************************************************/
void OX16PCI954Int(void)
{
        UINT32 reg_GIS;
        UINT8 temp;
       
        reg_GIS = *((volatile UINT32 *)(OX16PCI954_LCLMEMBASE + 0x1c));
        logMsg("reg_GIS: %x\n.",reg_GIS,0,0,0,0,0);
       
        if (reg_GIS & 1)
        {
                logMsg("COM3 Interrupted.\n",0,0,0,0,0,0);
                ns16550Int(&ox16pci954Chan[0]);
        }       

        if (reg_GIS & 2)
        {
                logMsg("COM4 Interrupted.\n",0,0,0,0,0,0);
                ns16550Int(&ox16pci954Chan[1]);
        }       
       
        if (reg_GIS & 4)
        {
                logMsg("COM5 Interrupted.\n",0,0,0,0,0,0);
                ns16550Int(&ox16pci954Chan[2]);
        }       
       
        if (reg_GIS & 8)
        {
                                       
                logMsg("COM6 Interrupted.\n",0,0,0,0,0,0);
                ns16550Int(&ox16pci954Chan[3]);
        }       
}
点赞  2008-6-13 16:39
void send()
{
int i = 0;
        UINT32 reg_MCR,reg_LCR;
        UINT8 r1,r2,r3,r4;
       
/*InnerLoop Mode*/
        reg_MCR = sysInByte(0xd204);
        sysOutByte(0xd204, reg_MCR | 0x10);
        sysOutByte(0xd20c, reg_MCR | 0x10);
        sysOutByte(0xd214, reg_MCR | 0x10);
        sysOutByte(0xd21c, reg_MCR | 0x10);

/*        reg_LCR=sysInByte(0xd203);
        sysOutByte(0xd203, reg_LCR&0x7F);
        sysOutByte(0xd20B, reg_LCR&0x7F);
        sysOutByte(0xd213, reg_LCR&0x7F);
        sysOutByte(0xd21B, reg_LCR&0x7F);
*/
        sysOutByte(0xd201, 0x03);
        sysOutByte(0xd209, 0x03);
        sysOutByte(0xd211, 0x03);
        sysOutByte(0xd219, 0x03);       
        while(i++ < 100)
        {
                sysOutByte(0xd200, 0x33);
                sysOutByte(0xd208, 0x44);
                sysOutByte(0xd210, 0x55);
                sysOutByte(0xd218, 0x66);

       
        }
}
这是发送函数,发送数据,但是对方却收不到数据。物理接线没有问题,232方式使用的也是上面的初始化及发送程序,收发都正常,但调成485方式就不行了
点赞  2008-6-13 16:44
再补充:这几个串口为系统pci自动分配中断号,目前中断号为12,网卡中断号也为12,不知两者会发生冲突否?因为只要我一它发送数据,网络就不能用了
点赞  2008-6-13 16:51
一般情况下485通讯时都需要通过某一寄存器的置位来判断到底是发送数据还是接收数据的!建议你找硬件提供上要驱动程序!
实在还不行就换硬件提供商!
点赞  2008-7-8 13:52
这个问题目前已经解决,是串口驱动的问题。这个串口卡有点特殊的地方,跟其他串口操作有较大不同的操作方法,按照dataSheet里面介绍的操作步骤配置正确读写寄存器就可以了。
点赞  2008-9-8 10:45
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复