⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tl16a.c

📁 串口扩展芯片TL16C554驱动代码
💻 C
字号:
#include "commrtos.h"
#include "tl16a.h"
#include "pin.h"
#include "VIC.h"
#include "int.h"
#include "app.h"
#include "pictureh.h"

#define  EXCOMM_RX_BUF_SIZE      1024                /* Number of characters in Rx ring buffer             */
static  volatile INT8U *exUART_BASE_ADDR[]={0,0,UART2_BASE,UART3_BASE,UART4_BASE,UART5_BASE};

typedef struct {
    INT16U     RingBufRxCtr;                /* Number of characters in the Rx ring buffer              */
    OS_EVENT  *RingBufRxSem;                /* Pointer to Rx semaphore                                 */
    INT8U     *RingBufRxInPtr;              /* Pointer to where next character will be inserted        */
    INT8U     *RingBufRxOutPtr;             /* Pointer from where next character will be extracted     */
    INT8U      RingBufRx[EXCOMM_RX_BUF_SIZE]; /* Ring buffer character storage (Rx)            */
    
}COMM_EX_BUF;

COMM_EX_BUF  Com3RcvBuf;
COMM_EX_BUF  Com4RcvBuf;
COMM_EX_BUF  Com5RcvBuf;
COMM_EX_BUF  Com6RcvBuf;

void delay_ms (INT32U i)
{
    INT32U j;
    for (j=0; j<i; j++)
    {
    	EX_WDG();
    }
}

//初始化串口数据结构
//         ch      串口号
void  EXCommInit (INT8U ch,INT8U *err)
{
    COMM_EX_BUF *pbuf;
    
    switch (ch) 
    {                                          
        case 2:
             pbuf = &Com3RcvBuf;
             break;

        case 3:
             pbuf = &Com4RcvBuf;
             break;

        case 4:
             pbuf = &Com5RcvBuf;
             break;

        case 5:
             pbuf = &Com6RcvBuf;
             break;

        default:
            {
             *err = COMM_BAD_CH;
             return;
            } 
    }   
    
    //pbuf                  = &Comm1Buf;  /* Initialize the ring buffer for GPSCOMM     */    
    pbuf->RingBufRxCtr    = 0;
    pbuf->RingBufRxInPtr  = &pbuf->RingBufRx[0];
    pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
    pbuf->RingBufRxSem    = OSSemCreate(0);
}

//16C554缓冲初始化
void L16_inibuf (void)
{
    INT8U err;
    
	EXCommInit(TestCOMM,&err);
	EXCommInit(LCDCOMM,&err);
	EXCommInit(JJQCOMM,&err);
	EXCommInit(JFQCOMM,&err);
}

//16C554A初始化
void Init16 (void)
{  
	IRQClose(IRQ_EXINT0);
	IRQClose(IRQ_EXINT2);
	IRQClose(IRQ_EXINT3);

	SetPinMode(rst_16c554,0,1);
	SetPin(rst_16c554);
	delay_ms(1000*1000/30);    //100ms
	ClrPin(rst_16c554);
	delay_ms(1000*1000/30);
	
	OS_ENTER_CRITICAL();
	uc_554a_lcr = 0x80;									// 使能波特率设置
	uc_554a_dll = (INT8U)(xt_554_mhz*1000000/16/bps_554a)%256; // 设置通讯波特率为9600
	uc_554a_dlm = (xt_554_mhz*1000000/16/bps_554a)/256;

	uc_554a_lcr = 0x03;									// 8 bit_data, 1 bit_stop, no parity
	uc_554a_fcr = 0x00;									// FIFO模式  10001111
	uc_554a_ier = 0x01;									// 使能接收和发送中断03,mcr中断
	uc_554a_mcr = 0x08;									// 使能串口中断
	
	
	uc_554b_lcr = 0x80;									// 使能波特率设置
	uc_554b_dll = (INT8U)(xt_554_mhz*1000000/16/bps_554b)%256; // 设置通讯波特率为9600
	uc_554b_dlm = (xt_554_mhz*1000000/16/bps_554b)/256;

	uc_554b_lcr = 0x03;									// 8 bit_data, 1 bit_stop, no parity
	uc_554b_fcr = 0x00;									// FIFO模式  10001111
	uc_554b_ier = 0x01;									// 使能接收和发送中断03,mcr中断
	uc_554b_mcr = 0x08;									// 使能串口中断
	
	
	uc_554c_lcr = 0x80;									// 使能波特率设置
	uc_554c_dll = (INT8U)(xt_554_mhz*1000000/16/bps_554c)%256; // 设置通讯波特率为9600
	uc_554c_dlm = (xt_554_mhz*1000000/16/bps_554c)/256;

	uc_554c_lcr = 0x03;									// 8 bit_data, 1 bit_stop, no parity
	uc_554c_fcr = 0x00;									// FIFO模式  10001111
	uc_554c_ier = 0x01;									// 使能接收和发送中断03,mcr中断
	uc_554c_mcr = 0x08;									// 使能串口中断

	
	uc_554d_lcr = 0x80;									// 使能波特率设置
	uc_554d_dll = (INT8U)(xt_554_mhz*1000000/16/bps_554d)%256; // 设置通讯波特率为9600
	uc_554d_dlm = (xt_554_mhz*1000000/16/bps_554d)/256;

	uc_554d_lcr = 0x03;									// 8 bit_data, 1 bit_stop, no parity
	uc_554d_fcr = 0x00;									// FIFO模式  10001111
	uc_554d_ier = 0x01;									// 使能接收和发送中断03,mcr中断
	uc_554d_mcr = 0x08;									// 使能串口中断
	OS_EXIT_CRITICAL();

	SetPinMode(int1_16c554,1,0);
	SetPinMode(int2_16c554,3,0);
	SetPinMode(int3_16c554,2,0);
	SetPinMode(int4_16c554,3,0);
	EXTINT = 0x0F;
    EXTMODE |= 0x00;            //电平触发
    EXTPOLAR = 0x0f;            //低触发
    IRQOpen(IRQ_EXINT0,PRIO_EXINT0,(int)IRQEXTINT0);
//    IRQOpen(IRQ_EXINT1,PRIO_EXINT1,(int)IRQEXTINT1);
    IRQOpen(IRQ_EXINT2,PRIO_EXINT2,(int)IRQEXTINT2);
    IRQOpen(IRQ_EXINT3,PRIO_EXINT3,(int)IRQEXTINT3);

}

//串口中断处理
void  IRQCUart3(void)
{
	ExCommISR(LCDCOMM);
	VICVectAddr = 0;		
}

//void  IRQCUart4(void)
//{
//	ExCommISR(JFQCOMM);	
//	VICVectAddr = 0;
//}

void  IRQCUart5(void)
{
	ttExCommISR(TestCOMM);	
	VICVectAddr = 0;
}

void  IRQCUart6(void)
{
	ExCommISR(JJQCOMM);
	VICVectAddr = 0;		
}

void  CommPutRxChar16 (const INT8U ch, INT8U c)
{
    COMM_EX_BUF *pbuf;


    switch (ch) {                                          /* Obtain pointer to communications channel */
        case 2:
             pbuf = &Com3RcvBuf;
             break;

        case 3:
             pbuf = &Com4RcvBuf;
             break;

        case 4:
             pbuf = &Com5RcvBuf;
             break;

        case 5:
             pbuf = &Com6RcvBuf;
             break;

        default:
             return;
    }
    
    if (pbuf->RingBufRxCtr < COMM_RX_BUF_SIZE) {           /* See if buffer is full                    */
        pbuf->RingBufRxCtr++;                              /* No, increment character count            */
        *pbuf->RingBufRxInPtr++ = c;                       /* Put character into buffer                */
        if (pbuf->RingBufRxInPtr == &pbuf->RingBufRx[EXCOMM_RX_BUF_SIZE]) { /* Wrap IN pointer           */
            pbuf->RingBufRxInPtr = &pbuf->RingBufRx[0];
        }
        OSSemPost(pbuf->RingBufRxSem);                     /* Indicate that character was received     */
    }
}

//CAM和Test串口中断接收程序
void  ttExCommISR(const int CommNum)
{
    INT8U  cc;
	volatile INT8U *BaseAddr;
    
    BaseAddr = exUART_BASE_ADDR[CommNum];             

	switch (*(BaseAddr+iir) & 0x0F)
	{
		case 4:
			cc = *(BaseAddr+rbr);
			CommPutRxChar16(CommNum, cc);
    	    break; 

	}
	EXTINT |= (1 << (CommNum-2));						// 清除EINT中断标志
	
    BaseAddr = exUART_BASE_ADDR[CommNum+1];             

	switch (*(BaseAddr+iir) & 0x0F)
	{
		case 4:
			cc = *(BaseAddr+rbr);
			CommPutRxChar16(CommNum+1, cc);
    	    break; 

	}
	
	EXTINT |= (1 << (CommNum-1));						// 清除EINT中断标志
}

//串口中断接收程序
void  ExCommISR(const int CommNum)
{
    INT8U  cc;
	volatile INT8U *BaseAddr;
    
	EXTINT |= (1 << (CommNum-2));						// 清除EINT中断标志
	
    BaseAddr = exUART_BASE_ADDR[CommNum];             

	switch (*(BaseAddr+iir) & 0x0F)
	{
		case 4:
			cc = *(BaseAddr+rbr);
			CommPutRxChar16(CommNum, cc);
    	    break; 

	}
	EXTINT |= (1 << (CommNum-2));						// 清除EINT中断标志
}

//发送一个字节
void ExStartSent (const INT8U ch,INT8U UData)
{
	INT8U  UartValue;
	INT16U i;
	volatile INT8U *BaseAddr;

    BaseAddr = exUART_BASE_ADDR[ch];             
       
    if ((ch > 1) && (ch < 6))
	{
		*(BaseAddr+thr) = UData;
		i = 0;
		do
		{
			UartValue = *(BaseAddr+lsr);
			if (i++ > 1000)
			{
				EX_WDG();
				break;
			}
        }while((UartValue&0x40) == 0);
    }
}

//REMOVE CHARACTER FROM RING BUFFER
INT8U  CommGetChar16 (const INT8U ch, INT16U to, INT8U *err)
{
    #if OS_CRITICAL_METHOD == 3                      /* Allocate storage for CPU status register */
    OS_CPU_SR      cpu_sr;
	#endif    
	INT8U          c;
    INT8U          oserr;
    COMM_EX_BUF    *pbuf;


    switch (ch) {                                   /* Obtain pointer to communications channel */
        case 2:
             pbuf = &Com3RcvBuf;
             break;

        case 3:
             pbuf = &Com4RcvBuf;
             break;

        case 4:
             pbuf = &Com5RcvBuf;
             break;

        case 5:
             pbuf = &Com6RcvBuf;
             break;

        default:
             *err = COMM_BAD_CH;
             return (NUL);
    }
    OSSemPend(pbuf->RingBufRxSem, to, &oserr);             /* Wait for character to arrive             */
    if (oserr == OS_TIMEOUT) {                             /* See if characters received within timeout*/
        *err = COMM_RX_TIMEOUT;                            /* No, return error code                    */
        return (NUL);
    }
    else {
        OS_ENTER_CRITICAL();
        pbuf->RingBufRxCtr--;                              /* Yes, decrement character count           */
        c = *pbuf->RingBufRxOutPtr++;                      /* Get character from buffer                */
        if (pbuf->RingBufRxOutPtr == &pbuf->RingBufRx[EXCOMM_RX_BUF_SIZE]) {     /* Wrap OUT pointer     */
            pbuf->RingBufRxOutPtr = &pbuf->RingBufRx[0];
        }
        OS_EXIT_CRITICAL();
        *err = COMM_NO_ERR;
        return (c);
    }
}

//------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -