精华内容
下载资源
问答
  • 基于RK3399 串口扩展4个串口的驱动代码。
  • 串口扩展芯片

    千次阅读 2020-06-24 14:50:51
    串口扩展芯片 WK2124 实现SPI桥接/扩展4个增强功能串口(UART)功能。扩展的子通道具备以下功能特点: 每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供2Mbps的通道速率; 每个子通道可以独立...

    串口扩展芯片

    WK2124

    实现SPI桥接/扩展4个增强功能串口(UART)功能。扩展的子通道具备以下功能特点:

    1. 每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供2Mbps的通道速率;
    2. 每个子通道可以独立设置工作在IrDA红外通信;
    3. 每个子通道具备收/发独立的256 BYTE FIFO,FIFO的中断可按用户需求进行编程触发点;

    封装:SSOP20
    工作电压:2.5~5.0V
    具备自动休眠/唤醒功能

    原理框图

    在这里插入图片描述

    封装引脚图

    在这里插入图片描述

    与控制器接口

    在这里插入图片描述

    1. SPI总线:WK2124通过SPI和MCU进行数据通信。SPI会传输命令字节和数据字节。
    2. 中断:WK2124的IRQ连接到MCU的外部中断输入引脚。这个连接非必须,未连接时只能通过查询的编程方式实现对子串口的数据收发,效率较低;
    3. 复位控制:低电平有效,时间长度为10ms。复位以后,所有寄存器值恢复到默认值,SPI总线上的命令解析同时复位;
    4. 时钟电路:采用无源晶振,晶振大小和子串口波特率相关;晶振必须并联的匹配电阻是1M欧姆;
    展开全文
  • 本驱动程序基于wk2166串口扩展芯片,实现了spi转串口的linux驱动程序的设计。本驱动源代码在为开微电子的网站也能找到源码。。
  • 8串口扩展芯片CH438驱动,C语言。并口,地址线与数据线共用。主程序只要简单地调用几个函数即可,初始化,接收,发送
  • 用于1串口扩展4路232串口,SPI接口,每路带有中断和RST,适用于串口服务器等领域
  • 同类方案比较目前比较通用的串口扩展方案有两种,一是用硬件实现,使用多串口单片机或专用串口扩展芯片,可供选择的串口扩展芯片有TI等公司开发的16C554系列串口扩展芯片,该系列芯片实现的功能是通过并行口扩展串行...
  • 串口扩展芯片XR16L784在水文监测系统中的应用.pdf
  • SJXXX系列产品,串口扩展芯片,是由1串口扩展4串口IC
  • 4串口扩展芯片

    2011-11-01 11:30:40
    The XR16C8641 (864) is an enhanced quad Universal Asynchronous Receiver and Transmitter (UART) each with 128 bytes of transmit and receive FIFOs, transmit and receive FIFO counters and ...
  • 串口扩展芯片,支持UART/IIC/SPI/并行总线接口,可扩展4路串口。硬件简单,电源种类单一。串口设计简单易操作。
  • 摘 要 本文介绍了一种新器件GM8123/25串口扩展芯片,利用该系列芯片实现的串口扩展方案具有成本低、速度快、控制简单等优点,可广泛应用于数据采集、工业控制等需要串口通讯的场合。 关键词 GM8123 GM8125 ...
  • SP2338串口扩展芯片在汽车行驶记录仪中的应用 林颖 在由单片机组成的汽车行驶记录仪中,为了适应不同用户的需要,该记录仪需要配置串口打印、与上位机通信串口以及与GPS通信接口等三个以上(含三个)串口,直接利用...
  • SP2338串口扩展芯片在汽车行驶记录仪中的应用 林颖 在由单片机组成的汽车行驶记录仪中,为了适应不同用户的需要,该记录仪需要配置串口打印、与上位机通信串口以及与GPS通信接口等三个以上(含三个)串口,直接利用...
  • WK系列串口扩展芯片详解(含电路例程)  很多单片机,比如51单片机,只有一个或两个串口。所以,有时会遇到串口不够用的情况,这时候可以换一款串口更多的单片机。而有时你又不想换一款单片机,那可以使用本文要介绍...

     很多单片机,比如51单片机,只有一个或两个串口。所以,有时会遇到串口不够用的情况,这时候可以换一款串口更多的单片机。而有时你又不想换一款单片机,那可以使用本文要介绍的通过IIC来扩展串口的芯片。
     成都为开微电子,在串口扩展芯片上有很多选择,有2个串口、4个串口等。本文以2串口的WK2132为例进行介绍。二话不说,先上简介。

    在这里插入图片描述
     WK串口芯片的特色,在于每个串口有256级FIFO,这可以节省你的单片机的RAM,同时,不容易因为没读取WK接收缓冲里的数据而使缓冲区溢出。
     在我的串口扩展模块中,使用IIC来操作WK,它的好处是有应答信号,可以知道WK芯片是否正常工作。上电路图

    在这里插入图片描述
     SCL、SDA接到单片机就可以了,IRQ是中断信号,可不接,单片机采用查询方式来检测是否有接收到数据。R7~R10用来选择IIC地址,这样可以用同一个IIC线最多接4个扩展模块,8个串口。
     我的模块中,还可以选择TTL输出还是232输出。

    在这里插入图片描述
     现在来上代码

    main()
    {
    	//P1.6為IIC SDA引腳,配置成開漏,輸出高電平
    	//P1.7為IIC SCL引腳,配置成開漏,輸出高電平
    	P1M0 |= (1<<6) | (1<<7);
    	P1M1 |= (1<<6) | (1<<7);
    	P1 |= (1<<6) | (1<<7);
    	
    	WK21xx_Init();
    	
    	while(1)
    	{
    		//测试自收自发
    		WK21xx_UARTxRcv(0, a, &RcvNum);
    		if (RcvNum)
    		{
    			WK21xx_UARTxSend(0, a, RcvNum);
    		}
    		
    		WK21xx_UARTxRcv(1, a, &RcvNum);
    		if (RcvNum)
    		{
    			WK21xx_UARTxSend(1, a, RcvNum);
    		}
    	}
    }
    
    

     先配置一下I2C的IO口,然后调用一下WK21xx_Init(),接下来就可以用WK21xx_UARTxRcv读取接收缓存里的数据,以及用WK21xx_UARTxSendByte和WK21xx_UARTxSend发送数据了。

     WK的驱动如下

    /*********************************************************************************************************
    ** Func:    WK21xx串口初始化
    ** Input:   UARTx: 串口号, 0~15
    ** Return:   成功返回1,失败返回0
    ** Remarks: WK21xx串口初始化
    *********************************************************************************************************/
    unsigned char WK21xx_UARTxInit(unsigned char UARTx, unsigned long Baud)
    {
    	unsigned long BaudReg = WK21xx_CLK / 16 * 100 / Baud;
    	unsigned short BaudReg_IntPart = BaudReg / 100 - 1;
    	unsigned short BaudRegB = BaudReg % 100 << 4;
    	unsigned char BaudReg_DecPart = BaudRegB / 100;
    	if (BaudRegB%100 >= 50)
    	{
    		BaudReg_DecPart += 1;
    	}
    	
    	if (!WK21xx_WriteSubReg(UARTx, REG_SPAGE_ADDR, 1)) return 0;       //选择寄存器页
    	if (!WK21xx_WriteSubReg(UARTx, REG_BAUD1_ADDR, BaudReg_IntPart>>8)) return 0;     //设置波特率
    	if (!WK21xx_WriteSubReg(UARTx, REG_BAUD0_ADDR, BaudReg_IntPart)) return 0;        //设置波特率
    	if (!WK21xx_WriteSubReg(UARTx, REG_PRES_ADDR, BaudReg_DecPart)) return 0;         //设置波特率
    	
    	if (!WK21xx_WriteSubReg(UARTx, REG_SPAGE_ADDR, 0)) return 0;        //选择寄存器页
    	if (!WK21xx_WriteSubReg(UARTx, REG_SCR_ADDR, 0x03)) return 0;       //使能串口发送和接收
    	if (!WK21xx_WriteSubReg(UARTx, REG_LCR_ADDR, 
    		(0 << 3)             //0 No parity; 1 Enable parity
    		| (0 << 1)           //0 Force 0 parity; 1 Odd parity; 2 Even parity; 3 Force 1 parity
    		| 0)) return 0;      //0 1 stop bit; 1 2 stop bit
    	if (!WK21xx_WriteSubReg(UARTx, REG_FCR_ADDR, 0x0f)) return 0;      //使能并重置FIFO
    	if (!WK21xx_WriteSubReg(UARTx, REG_SIER_ADDR, 0)) return 0;        //禁止所有子串口中断	
    		
    	return 1;
    }
    
    /*********************************************************************************************************
    ** Func:    WK21xx初始化
    ** Input:   无
    ** Return:   成功返回1,失败返回0
    ** Remarks: WK21xx初始化
    *********************************************************************************************************/
    unsigned char WK21xx_Init(void)
    {
    	I2C_PinInit();
    
    	//全局初始化
    	if (!WK21xx_WriteGlobalReg(0, REG_GENA_ADDR, 0x03)) return 0;     //使能子串口时钟
    	if (!WK21xx_WriteGlobalReg(0, REG_GMUT_ADDR, 
    		(0 << 3)             //0 No parity; 1 Enable parity
    		| (0 << 1)           //0 Force 0 parity; 1 Odd parity; 2 Even parity; 3 Force 1 parity
    		| 0)) return 0;      //0 1 stop bit; 1 2 stop bit
    	if (!WK21xx_WriteGlobalReg(0, REG_GIER_ADDR, 0)) return 0;     //禁止全局串口中断
    	
    	//子串口初始化
    	if (!WK21xx_UARTxInit(0, WK21xx_UART0_BAUD)) return 0;
    	if (!WK21xx_UARTxInit(1, WK21xx_UART1_BAUD)) return 0;
    	return 1;
    }
    
    /*********************************************************************************************************
    ** Func:    WK21xx UARTx发送一个字节
    ** Input:   UARTx: 串口号, 0~15
    ** Input:   Data: 要发送的字节
    ** Output:  无
    ** Return:   成功返回1,失败返回0
    ** Remarks: 同步模式,发送完毕函数才返回
    *********************************************************************************************************/
    unsigned char  WK21xx_UARTxSendByte(unsigned char UARTx, unsigned char Data)
    {
    	unsigned char FsrReg;
    	
    	if (!WK21xx_WriteFIFO(UARTx, &Data, 1)) return 0;
    	while (1)
    	{
    		if (!WK21xx_ReadSubReg(UARTx, REG_FSR_ADDR, &FsrReg))
    		{
    			return 0;
    		}
    		if ((FsrReg & 0x05) == 0)
    		{
    			return 1;
    		}
    	}
    }
    
    /*********************************************************************************************************
    ** Func:    WK21xx UARTx发送数据
    ** Input:   UARTx: 串口号, 0~15
    ** Input:   pData: 要发送的数据
    ** Input:   Num: 要发送的字节数
    ** Output:  None
    ** Return:   成功返回1,失败返回0
    ** Remarks: 同步模式,发送完毕函数才返回
    *********************************************************************************************************/
    unsigned char WK21xx_UARTxSend(unsigned char UARTx, unsigned char *pData, unsigned char Num)
    {
    	unsigned char FsrReg;
    	
    	if (!WK21xx_WriteFIFO(UARTx, pData, Num)) return 0;
    	while (1)
    	{
    		if (!WK21xx_ReadSubReg(UARTx, REG_FSR_ADDR, &FsrReg))
    		{
    			return 0;
    		}
    		if ((FsrReg & 0x05) == 0)
    		{
    			return 1;
    		}
    	}
    }
    
    /*********************************************************************************************************
    ** Func:    WK21xx UARTx读取数据
    ** Input:   UARTx: 串口号, 0~15
    ** Output:  pData: 存放读取到的数据的指针
    ** Output:   pRcvNum: 读取到的字节数
    ** Return:   成功返回1,失败返回0
    ** Remarks: 数据最多256个
    *********************************************************************************************************/
    unsigned char WK21xx_UARTxRcv(unsigned char UARTx, unsigned char *pData, unsigned char *pRcvNum)
    {
    	unsigned char RcvNum;
    	
    	if (!WK21xx_ReadSubReg(UARTx, REG_RFCNT_ADDR, &RcvNum))
    	{
    		*pRcvNum = 0;
    		return 0;
    	}
    	if (RcvNum == 0)
    	{
    		*pRcvNum = 0;
    		return 1;
    	}
    	if (!WK21xx_ReadFIFO(UARTx, pData, RcvNum))
    	{
    		*pRcvNum = 0;
    		return 0;
    	}
    	*pRcvNum = RcvNum;
    	return 1;
    }
    
    

     后面附上源码,有兴趣可以查看
    WK2132驱动 C语言源码

    展开全文
  • 基于STM32的ch438串口扩展芯片使用

    万次阅读 热门讨论 2019-06-22 18:52:25
    CH438串口扩展芯片是一个一对八的串口扩展芯片,在一些串口需要过多的场合比较有用。这个串口芯片事实上并没有占用MCU的串口它实际上是使用了8个IO口做数据的传输。下面我就简单介绍一下怎么使用STM32驱动这个串口...

    CH438串口扩展芯片是一个一对八的串口扩展芯片,在一些串口需要过多的场合比较有用。这个串口芯片事实上并没有占用MCU的串口它实际上是使用了8个IO口做数据的传输。下面我就简单介绍一下怎么使用STM32驱动这个串口扩展芯片。并演示一个用CH438发送一段MODBUS码给电脑,电脑发给STM32的数据数据也回显示到电脑上.

    CH438我用的是44管脚的LQFP44封装。

    54。还有

    实际的电路是这样的:

     

    需要注意的几点就是:RXT代表的是复位应该接上拉电阻到电源,我用的是STM32的复位电路共用。这里不能悬空。

    晶振使用的是22.1184MHz晶振频率很高注意起振电容的选择。我采用的是20pf。

    D0~D7与STM32 的PC0~7连接,这八位是数据传输位,其他的几位都是控制位。本次接收数据使用到了本芯片和STM32的中断,INT叫对应的就是中断线。注意这个管脚不能连接到PC口上因为PC口已经当做数据口用了,如果连接到PC口高八位上,在芯片读写数据的时候出异常。

    下面这些是芯片内部的寄存器:主要就是配置他们。

    #ifndef _CH438_H
    #define _CH438_H
    #include "sys.h"
    #include "delay.h"
    #define REG_RBR_ADDR        0x00      /* 串口0接收缓冲寄存器地址 */
    #define REG_THR_ADDR        0x00      /* 串口0发送保持寄存器地址 */
    #define REG_IER_ADDR        0x01      /* 串口0中断使能寄存器地址 */
    #define REG_IIR_ADDR        0x02      /* 串口0中断识别寄存器地址 */
    #define REG_FCR_ADDR        0x02      /* 串口0FIFO控制寄存器地址 */
    #define REG_LCR_ADDR        0x03      /* 串口0线路控制寄存器地址 */
    #define REG_MCR_ADDR        0x04      /* 串口0MODEM控制寄存器地址 */
    #define REG_LSR_ADDR        0x05      /* 串口0线路状态寄存器地址 */
    #define REG_MSR_ADDR        0x06      /* 串口0MODEM状态寄存器地址 */
    #define REG_SCR_ADDR        0x07      /* 串口0用户可定义寄存器地址 */
    #define REG_DLL_ADDR        0x00      /* 波特率除数锁存器低8位字节地址 */
    #define REG_DLM_ADDR        0x01      /* 波特率除数锁存器高8位字节地址 */
    
    /* CH438内部串口0~7 专用状态寄存器 */
    
    #define REG_SSR_ADDR        0x4F       /* 专用状态寄存器地址 */
    
    
    /* IER寄存器的位 */
    
    #define BIT_IER_RESET       0x80      /* 该位置1则软复位该串口 */
    #define BIT_IER_LOWPOWER    0x40      /* 该位为1则关闭该串口的内部基准时钟 */
    #define BIT_IER_SLP         0x20      /* 串口0是SLP,为1则关闭时钟震荡器 */
    #define BIT_IER1_CK2X       0x20      /* 串口1是CK2X,为1则强制将外部时钟信号2倍频后作为内部基准时钟 */
    #define BIT_IER_IEMODEM     0x08      /* 该位为1允许MODEM输入状态变化中断 */
    #define BIT_IER_IELINES     0x04      /* 该位为1允许接收线路状态中断 */
    #define BIT_IER_IETHRE      0x02      /* 该位为1允许发送保持寄存器空中断 */
    #define BIT_IER_IERECV      0x01      /* 该位为1允许接收到数据中断 */
    
    /* IIR寄存器的位 */
    
    #define BIT_IIR_FIFOENS1    0x80
    #define BIT_IIR_FIFOENS0    0x40      /* 该2位为1表示起用FIFO */
    
    /* 中断类型:0001没有中断,0110接收线路状态中断,0100接收数据可用中断,1100接收数据超时中断,0010THR寄存器空中断,0000MODEM输入变化中断 */
    #define BIT_IIR_IID3        0x08
    #define BIT_IIR_IID2        0x04	//接受数据可用
    #define BIT_IIR_IID1        0x02	//THR寄存器空中断
    #define BIT_IIR_NOINT       0x01
    
    /* FCR寄存器的位 */
    
    /* 触发点: 00对应1个字节,01对应16个字节,10对应64个字节,11对应112个字节 */
    #define BIT_FCR_RECVTG1     0x80      /* 设置FIFO的中断和自动硬件流控制的触发点 */
    #define BIT_FCR_RECVTG0     0x40      /* 设置FIFO的中断和自动硬件流控制的触发点 */
    
    #define BIT_FCR_TFIFORST    0x04      /* 该位置1则清空发送FIFO中的数据 */
    #define BIT_FCR_RFIFORST    0x02      /* 该位置1则清空接收FIFO中的数据 */
    #define BIT_FCR_FIFOEN      0x01      /* 该位置1则起用FIFO,为0则禁用FIFO */
    
    /* LCR寄存器的位 */
    
    #define BIT_LCR_DLAB        0x80      /* 为1才能存取DLL,DLM,为0才能存取RBR/THR/IER */
    #define BIT_LCR_BREAKEN     0x40      /* 为1则强制产生BREAK线路间隔*/
    
    /* 设置校验格式:当PAREN为1时,00奇校验,01偶校验,10标志位(MARK,置1),11空白位(SPACE,清0) */
    #define BIT_LCR_PARMODE1    0x20      /* 设置奇偶校验位格式 */
    #define BIT_LCR_PARMODE0    0x10      /* 设置奇偶校验位格式 */
    
    #define BIT_LCR_PAREN       0x08      /* 为1则允许发送时产生和接收校验奇偶校验位 */
    #define BIT_LCR_STOPBIT     0x04      /* 为1则两个停止位,为0一个停止位 */
    
    /* 设置字长度:00则5个数据位,01则6个数据位,10则7个数据位,11则8个数据位 */
    #define BIT_LCR_WORDSZ1     0x02      /* 设置字长长度 */
    #define BIT_LCR_WORDSZ0     0x01
    
    /* MCR寄存器的位 */
    
    #define BIT_MCR_AFE         0x20      /* 为1允许CTS和RTS硬件自动流控制 */
    #define BIT_MCR_LOOP        0x10      /* 为1使能内部回路的测试模式 */
    #define BIT_MCR_OUT2        0x08      /* 为1允许该串口的中断请求输出 */
    #define BIT_MCR_OUT1        0x04      /* 为用户定义的MODEM控制位 */
    #define BIT_MCR_RTS         0x02      /* 该位为1则RTS引脚输出有效 */
    #define BIT_MCR_DTR         0x01      /* 该位为1则DTR引脚输出有效 */
    
    /* LSR寄存器的位 */
    
    #define BIT_LSR_RFIFOERR    0x80      /* 为1表示在接收FIFO中存在至少一个错误 */
    #define BIT_LSR_TEMT        0x40      /* 为1表示THR和TSR全空 */
    #define BIT_LSR_THRE        0x20      /* 为1表示THR空*/
    #define BIT_LSR_BREAKINT    0x10      /* 该位为1表示检测到BREAK线路间隔 */
    #define BIT_LSR_FRAMEERR    0x08      /* 该位为1表示读取数据帧错误 */
    #define BIT_LSR_PARERR      0x04      /* 该位为1表示奇偶校验错误 */
    #define BIT_LSR_OVERR       0x02      /* 为1表示接收FIFO缓冲区溢出 */
    #define BIT_LSR_DATARDY     0x01      /* 该位为1表示接收FIFO中有接收到的数据 */
    
    /* MSR寄存器的位 */
    
    #define BIT_MSR_DCD         0x80      /* 该位为1表示DCD引脚有效 */
    #define BIT_MSR_RI          0x40      /* 该位为1表示RI引脚有效 */
    #define BIT_MSR_DSR         0x20      /* 该位为1表示DSR引脚有效 */
    #define BIT_MSR_CTS         0x10      /* 该位为1表示CTS引脚有效 */
    #define BIT_MSR_DDCD        0x08      /* 该位为1表示DCD引脚输入状态发生变化过 */
    #define BIT_MSR_TERI        0x04      /* 该位为1表示RI引脚输入状态发生变化过 */
    #define BIT_MSR_DDSR        0x02      /* 该位为1表示DSR引脚输入状态发生变化过 */
    #define BIT_MSR_DCTS        0x01      /* 该位为1表示CTS引脚输入状态发生变化过 */
    
    /* 中断状态码 */
    
    #define INT_NOINT           0x01      /* 没有中断 */
    #define INT_THR_EMPTY       0x02      /* THR空中断 */
    #define INT_RCV_OVERTIME    0x0C      /* 接收超时中断 */
    #define INT_RCV_SUCCESS     0x04      /* 接收数据可用中断 */
    #define INT_RCV_LINES       0x06      /* 接收线路状态中断 */
    #define INT_MODEM_CHANGE    0x00      /* MODEM输入变化中断 */
    
    #define CH438_IIR_FIFOS_ENABLED 0xC0  /* 起用FIFO */
    
    
    #define WR   PDout(3)
    #define ALE  PDout(7)
    #define RD   PDout(4)
    #define CS   PDout(5)
    #define AMOD PDout(6)
    #define INT  PDout(1)
    void SetOutPut(void);
    void SetInPut(void);
    void CH438_Init(void);
    void CH438WriteReg(u8 add,u8 data);
    u8 CH438ReadReg(u8 add);
    unsigned char CH438_CheckIIR(unsigned char num);
    void CH438_CloseSeril(unsigned char num);
    void CH438_CloseALLSeril(void);
    void CH438_ResetSeril(unsigned char num);
    void CH438_SetBandrate(unsigned char num, unsigned long value);
    void CH438_UARTInit(unsigned char num);
    void CH438_SendDatas(unsigned char num, unsigned char* sendbuff,unsigned char len);
    unsigned char CH438_RecvDatas(unsigned char num, unsigned char* revbuff);
    void CH438_TranConfig(unsigned char num);
    void CH438_INTConfig(unsigned char num);
    void CH438_AutoHFCtrl(unsigned char num);
    void CH438_RegTEST(unsigned char num);
    void CH438_Uart_Init(unsigned char num,unsigned long value);
    #endif
    

    上面就是CH438.h头文件,以下就是main函数,本程序只打开了串口2

    
    int  main()
    {
    	u8 ssr =0 ;
            u8 AddCom[8] =	  {01,05,01,17,255,00,221,195};   	//增压
    
    	delay_init();	    	 
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2	  	
    	uart_init(9600);
    	LCD_Init();
    	CH438_Init();  
    	
    	CH438_ResetSeril(2);  //软件复位串口2
    	CH438_Uart_Init(2,9600); //串口2打开 波特率9600
    	delay_ms(100);
    	
    	while(1)
    	{
    		CH438_SendDatas(2,AddCom,8);
    		CH438_SendDatas(2,(u8*)"\r\n",2);
    		delay_ms(1000);	
    	}
    }

    下面是主要的函数

    #include "ch438.h"
    #include "delay.h"
    #include "usart.h"
    #include "lcd.h"
    #define Fpclk    	  1843200         /* 定义内部时钟频率,默认外部晶振的12分频    */
    #define MaxRecvLen    50         	  /* 接收缓冲区大小    */
    
    const unsigned char offsetadd[] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,};		/* 串口号的偏移地址 */
    const unsigned char Interruptnum[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,};	/* SSR寄存器中断号对应值 */
    
    unsigned char Revbuff[MaxRecvLen];		/* 接收缓存区 */
    unsigned char RevLen;					/* 接收计数 */
    
    
    
    
    void SetOutPut()  //IO输出模式
    {
    	GPIOC->CRL &=0;
    	GPIOC->CRL = 0X33333333;
    
    }
    void SetInPut()//IO输入模式
    {
    	GPIOC->CRL &=0;
    	GPIOC->CRL = 0X88888888;
    }
    void CH438_Init() //IO口中断等初始化
    {
    	GPIO_InitTypeDef GPIO_InitStructure;
    	NVIC_InitTypeDef NVIC_InitStructure;
    	EXTI_InitTypeDef EXTI_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    	GPIO_InitStructure.GPIO_Pin  = 0X00FF;
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    	GPIO_Init(GPIOC,&GPIO_InitStructure);
    	
    	
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
    	GPIO_Init(GPIOD,&GPIO_InitStructure);
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_1;
    	GPIO_Init(GPIOD,&GPIO_InitStructure);
    	GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource1);
    	EXTI_InitStructure.EXTI_Line = EXTI_Line1;
    	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;	
    	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
    	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    	EXTI_Init(&EXTI_InitStructure);
    	
    	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStructure);
    	EXTI_ClearITPendingBit(EXTI_Line1);
    	AMOD = 1;
    
    }
    
    void CH438WriteReg(u8 add,u8 data)  //写一个字节到寄存器
    {
    	u16  value ;
    	CS = 1;
    	WR = 1;
    	RD = 1;
    	SetOutPut();
    	GPIOC->ODR = (GPIOC->ODR&0XFF00)|add; //低八位十数据位确保高八位数据不变  写寄存器地址 
    	CS = 0;
    	ALE =1;
    	delay_us(1);
    	ALE = 0;
    	
    	GPIOC->ODR = (GPIOC->ODR&0XFF00)|data; //写数据
    	WR =0 ;
    	delay_us(1);
    	WR =1;
    	CS =1;
    }
    
    
    u8 CH438ReadReg(u8 add) //读取一个字节
    {
    	u8 value;
    	u8 value1;
    	CS = 1;
    	WR =1;
    	RD =1;
    	SetOutPut();   //
    	CS = 0;
    	ALE =1;
    	GPIOC->ODR = (GPIOC->ODR&0XFF00)|add;
    	ALE = 0;
    	SetInPut();
    	RD = 0;
    	value = GPIO_ReadInputData(GPIOC);
    	
    
    	RD =1;
    	CS =1;
    	
    	return value;
    }
    
    unsigned char CH438_CheckIIR(unsigned char num)
    {
    	unsigned char value;
    	
    	value = CH438ReadReg( offsetadd[num] | REG_IIR_ADDR );
    	return value;
    }
    void CH438_CloseSeril(unsigned char num) //关闭某位串口
    {
    	CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_LOWPOWER);
    }
    
    void CH438_CloseALLSeril(void) //关闭所有串口
    {
    	CH438WriteReg(offsetadd[0]|REG_IER_ADDR, BIT_IER_LOWPOWER|BIT_IER_SLP);
    }
    void CH438_ResetSeril(unsigned char num) //复位串口
    {
    	CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_RESET);
    }
    void CH438_SetBandrate(unsigned char num, unsigned long value)//设置波特率 未使用此函数
    {
    	uint8_t dlab=0;
    	uint16_t bandspeed;
    	
    	
    	bandspeed = Fpclk/16/value;
            CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_DLAB );  
    	CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
    	CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
    	
    
    	printf("bandrate: %d\n", bandspeed);
    	printf("DLM: %d\n", CH438ReadReg(offsetadd[num]|REG_DLM_ADDR));
    	printf("DLL: %d\n", CH438ReadReg(offsetadd[num]|REG_DLL_ADDR));
    
    }
    void CH438_UARTInit(unsigned char num)//初始化  未使用到
    {
    	CH438_SetBandrate(num, 9600);	/* CH438串口1波特率设置 */
    	CH438_TranConfig(num); 			/* CH438串口1数据格式配置及FIFO大小 */	
    }
    //发送数据
    
    void CH438_SendDatas(unsigned char num, unsigned char* sendbuff,unsigned char len)
    {
    	
    	do
    	{
    		while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_THRE)==0);    //LSR->THRE==1  保持寄存器空
    		
    			CH438WriteReg(offsetadd[num]|REG_THR_ADDR,*sendbuff++);	
    	}while(--len);
    	
    }
    //接收数据
    
    unsigned char CH438_RecvDatas(unsigned char num, unsigned char* revbuff)
    {
    	uint8_t len=0;
    	uint8_t *p_rev;
    	
    	p_rev = revbuff;
    
    	while( ( CH438ReadReg( offsetadd[num]|REG_LSR_ADDR ) & BIT_LSR_DATARDY ) == 0 );    /*等待数据准备好 */
    	while((CH438ReadReg(offsetadd[num]|REG_LSR_ADDR)&BIT_LSR_DATARDY))	//LSR->DATARDY==1
    	{
    		*p_rev = CH438ReadReg(offsetadd[num]|REG_RBR_ADDR);
    		p_rev++;
    		len++;
    	}
    	return len;
    }
    void CH438_TranConfig(unsigned char num)
    {	
    	/* 发送数据格式:8位数据,无校验,1个停止位  */
    	CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0);
    	/* 设置FIFO模式,触发点为112字节 */
    	CH438WriteReg(offsetadd[num]|REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN);	
    	CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
    }
    
    void CH438_INTConfig(unsigned char num)
    {	
    	/* 注意: CH438打开BIT_IER_IETHRE中断(0->1),会产生一个发生空中断 */	
    	CH438WriteReg(offsetadd[num]|REG_IER_ADDR, BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV );
    	CH438_CheckIIR(num);
    	CH438WriteReg(offsetadd[num]|REG_MCR_ADDR, BIT_MCR_OUT2    | BIT_MCR_RTS     | BIT_MCR_DTR);//可以产生一个实际的中断	
    }
    
    void CH438_AutoHFCtrl(unsigned char num)
    {
        CH438WriteReg( offsetadd[num]|REG_MCR_ADDR, BIT_MCR_AFE | BIT_MCR_OUT2 | BIT_MCR_RTS );/* 设置MCR寄存器的AFE和RTS为1 */
    }
    //中断处理函数
    
    void EXTI1_IRQHandler()
    {
    	u8 gInterruptStatus;
    	u8 InterruptStatus;
    	u8 i;
    	static u8 j ;
    	if(EXTI_GetITStatus(EXTI_Line1)!= RESET)
    	{
    			gInterruptStatus = CH438ReadReg( REG_SSR_ADDR );
    			
    			if(!gInterruptStatus)
    			{ 
    				EXTI_ClearITPendingBit(EXTI_Line1);
    				return ;
    			}
    			
    			
    				for(i=0; i<8; i++)
    			{
    				if( gInterruptStatus & Interruptnum[i] )    /* 检测哪个串口发生中断 */
    				{
    					InterruptStatus = CH438ReadReg( offsetadd[i] | REG_IIR_ADDR ) & 0x0f;    /* 读串口的中断状态 */	
    					
    					switch( InterruptStatus )
    					{
    						case INT_NOINT:			/* 没有中断 */					
    							break;
    						case INT_THR_EMPTY:		/* THR空中断 */						
    							break;
    						case INT_RCV_OVERTIME:	/* 接收超时中断 */
    							RevLen = CH438_RecvDatas(i, Revbuff);					
    							CH438_SendDatas(i, Revbuff, RevLen);
    							break;
    						case INT_RCV_SUCCESS:	/* 接收数据可用中断 */
    							RevLen = CH438_RecvDatas(i, Revbuff);
    							CH438_SendDatas(i, Revbuff, RevLen);
    							break;
    						case INT_RCV_LINES:		/* 接收线路状态中断 */
    							CH438ReadReg( offsetadd[i] | REG_LSR_ADDR );
    							break;
    						case INT_MODEM_CHANGE:	/* MODEM输入变化中断 */
    							CH438ReadReg( offsetadd[i] | REG_MSR_ADDR );
    							break;
    						default:
    							break;
    
    					}
    				}
    			}
    	
    		EXTI_ClearITPendingBit(EXTI_Line1);
    	}
    }
    void CH438_RegTEST(unsigned char num)//测试使用的函数
    {
    
    	printf("current test serilnum: %d \r\n",(unsigned short)offsetadd[num]);
    	printf("IER: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IER_ADDR));//?IER
    	printf("IIR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_IIR_ADDR));//?IIR
    	printf("LCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LCR_ADDR));//?LCR
    	printf("MCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MCR_ADDR));//?MCR
    	printf("LSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_LSR_ADDR));//?LSR
    	printf("MSR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_MSR_ADDR));//?MSR
    	//CH438WriteReg(offsetadd[num] | REG_SCR_ADDR, 0x78);
    	printf("SCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_SCR_ADDR));//?SCR
    	printf("FCR: %02x\r\n",(unsigned short)CH438ReadReg(offsetadd[num] | REG_FCR_ADDR));//?SCR
    
    }
    //串口初始化函数 输入参数 串口号和波特率
    void CH438_Uart_Init(unsigned char num,unsigned long value)
    {
    
    	uint8_t dlab=0;
    	uint16_t bandspeed;
    	dlab = CH438ReadReg(offsetadd[num]|REG_IER_ADDR);
    	dlab &= 0xDF;
    	CH438WriteReg(offsetadd[num]|REG_IER_ADDR, dlab);
    	
    	dlab = CH438ReadReg(offsetadd[num]|REG_LCR_ADDR);
    	dlab |= 0x80;		//置LCR寄存器DLAB位为1
    	CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
    	
    	bandspeed = Fpclk/16/value;
    	CH438WriteReg(offsetadd[num]|REG_DLL_ADDR, (uint8_t)bandspeed);
    	CH438WriteReg(offsetadd[num]|REG_DLM_ADDR, (uint8_t)(bandspeed>>8));
    	dlab &= 0x7F;		//置IIR寄存器DLAB位为0
    	CH438WriteReg(offsetadd[num]|REG_LCR_ADDR, dlab);
    	CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN );
    	CH438WriteReg(offsetadd[num]|REG_LCR_ADDR,BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0 );
    	CH438WriteReg(offsetadd[num]|REG_IER_ADDR,BIT_IER_IELINES | BIT_IER_IETHRE | BIT_IER_IERECV);
    	CH438WriteReg(offsetadd[num]|REG_MCR_ADDR,BIT_MCR_OUT2    | BIT_MCR_RTS     | BIT_MCR_DTR);
    	CH438WriteReg(offsetadd[num]|REG_FCR_ADDR,CH438ReadReg(offsetadd[num]|REG_FCR_ADDR)| BIT_FCR_TFIFORST|BIT_FCR_RFIFORST);
    
    
    }
    

     

    实验结果如下:

     

    垃圾CSDN

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • EU104是具有5个UART接口的数据转发芯片,可实现将1个UART扩展为4个UART接口,主接口通讯速率最高460800bps,子接口通讯速率最高38400bps,各接口通讯速率可由软件独立设置,包括数据位、校验位、停止位等,可适应绝...

    概述

    EU104是具有5个UART接口的数据转发芯片,可实现将1个UART扩展为4个UART接口,主接口通讯速率最高460800bps,子接口通讯速率最高38400bps,各接口通讯速率可由软件独立设置,包括数据位、校验位、停止位等,可适应绝大部分串口设备的通讯要求,紧凑的SOP16封装、2.0~5.5V供电电压、工业级温度范围等特性方便集成嵌入。

    每个接口均有独立缓存(最多1024字节),有按字节或按数据帧两种模式。

    内置RC振荡器或者外接高精度温补晶振,在整个工业级温度范围保持准确时钟。

    功能特点

    供电:2.0~5.5V

    功耗:

    • 正常运行5.8mA
    • 休眠
      11uA@VDD=3.0V   40uA@VDD=5.0V

    通讯

    • 主UART:1200~460800bps(默认115200)
    • 从UART:1200~38400bps(默认9600)
    • 缓存:共用1024字节

    封装:SOP16

    工作温度:-40~85℃,内置RC振荡器温漂范围-1.8%~0.8%,允许软件校准。

    其它特性:64bits唯一识别码

    引脚定义

    编号

    标识

    标识

    编号

    1

    TXD5

    RXD5

    16

    2

    TXD4

    RXD4

    15

    3

    TXD3

    RCV2

    14

    4

    TXD2/XIN

    RCV1

    13

    5

    SND1

    RXD3

    12

    6

    VCC

    RXD2

    11

    7

    SND2

    TXD1

    10

    8

    GND

    RXD1

    9

    所有引脚(电源除外)均为准双向弱上拉

    SND2

    SND1

    子UART号

    RCV2

    RCV1

    子UART号

    0

    0

    2

    0

    0

    2

    0

    1

    3

    0

    1

    3

    1

    0

    4

    1

    0

    4

    1

    1

    5

    1

    1

    5

    设置SND引脚电平

    选择数据从哪个UART输出

    检测RCV引脚电平

    获取接收到的数据来自哪个子UART

    EU104数据手册下载https://download.csdn.net/download/xulikai/12717067

    展开全文
  • 可以通过模式选择使得该芯片工作于以上任何一种主接口模式,将选 定的主接口扩展为4个增强功能的UART。 扩展的子通道的UART具备如下功能特点: 1.每个子通道UART的波特率、字长、校验格式可以独立设置,最高可以提供...
  • SJXX串口扩展芯片1 概述SJ000是一款具备I2C总线/SPI总线/UART接口的四通道异步收发器件,通过模式选择使得该器件工作于以上任何一种主接口模式下。器件的四个通道UART可提供高达2Mbps的数据率,低功耗模式和睡眠电流...
  • GM8125串口扩展芯片,是由成都国腾电子开发的芯片,是将1串口扩展为5串口的IC
  • SJXXX串口扩展芯片 UART(1) to UART(4)

    千次阅读 2017-07-17 16:18:12
    SJXX串口扩展芯片 1 概述 SJ000是一款具备I2C总线/SPI总线/UART接口的四通道异步收发器件,通过模式选择使得该器件工作于以上任何一种主接口模式下。器件的四个通道UART可提供高达2Mbps的数据率,低功耗模式和睡眠...
  • 嵌入式系统中串口扩展的需求:  而在嵌入式领域,由于UART具有操作简单,工作可靠,抗干扰强,传输距离远(组成485网络可以传输1200米以上),设计人员普遍认为UART是从CPU或微控制器向系统的其他部分传输数据的...
  • 针对地理信息系统在获取定位信息中存在的问题,提出了基于串口扩展芯片GM8123的新型通信处理系统设计思想,该系统一方面可接收GPS和激光测距系统提供的定位信息,另一方面可上传定位数据并响应上位PC机和...
  • SPI扩展4串口芯片

    2018-12-07 15:47:07
    通过SPI扩展串口,简单实用,适合在嵌入式平台中,芯片资源较少但又不想改设计方案时使用
  • 本例程是基于主控stm32,实现spi串口扩展4个子串口,基于wk2124芯片。 本例程是基于主控stm32,实现spi串口扩展4个子串口,基于wk2124芯片
  • 本文简单介绍了串口扩展芯片在汽车行驶记录仪的一些应用,希望对大家有所帮助。
  • RK3399-Wk2114串口扩展驱动,串口扩展芯片wk2124,C,C++源码.rar
  • RK3399-Wk2114串口扩展驱动,串口扩展芯片wk2124,C,C++源码.zip

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,317
精华内容 4,926
关键字:

串口扩展芯片