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

📄 16c552.c

📁 在ARM7和UC/OSII的平台上实现了GPS自动报站的功能,涉及GPS模块LEA_4S的驱动,位置速寻算法,语音芯片ISD4004的录放音驱动,LED页面管理等等.从启动代码到操作系统的移植以及到业
💻 C
字号:
/****************************************************************
**                                                              *
**  FILE         :  16C552.C                                    *
**  COPYRIGHT    :  (c) 2001 .Xiamen Yaxon NetWork CO.LTD       *
**                                                              *
**                                                              *
**  By : CCH 2005.5.28                                          *
****************************************************************/
#include "includes.h"
#include "bsp.h"
#include "uart_drv.h"
#include "roundbuf.h"
#include "16c552.h"

#ifndef IRQ0_INTERRUPT_PRIO
#define IRQ0_INTERRUPT_PRIO		0
#endif

#ifndef IRQ1_INTERRUPT_PRIO		
#define IRQ1_INTERRUPT_PRIO		1
#endif

#define ExtUartResetPinID		AT91C_PIO_P8
/*
********************************************************************************
* 定义配置参数
********************************************************************************
*/
#define frequency                   1843200L        /* 16C552外部晶振频率 */
#define MAX_RBUF                    1024             /* 接收缓冲区大小 */
#define MAX_SBUF                    1024             /* 发送缓冲区大小 */

/*
********************************************************************************
* 定义16C552寄存器
********************************************************************************
*/

#define THR                         RHR
#define ISR                         FCR
#define DLL                         RHR
#define DLM                         IER

typedef struct{
    volatile INT16U   RHR;
    volatile INT16U   IER;
    volatile INT16U   FCR;
    volatile INT16U   LCR;
    volatile INT16U   MCR;
    volatile INT16U   LSR;
    volatile INT16U   MSR;
    volatile INT16U   SPR;
}REG_16C552;

/*
********************************************************************************
* 定义UART结构
********************************************************************************
*/
typedef struct {
    INT8U   r_buf[MAX_RBUF];                /* 接收数据缓冲区 */
    INT8U   s_buf[MAX_SBUF];                /* 发送数据缓冲区 */
    ROUNDBUF_STRUCT     r_round;            /* 接收环形缓冲区 */
    ROUNDBUF_STRUCT     s_round;            /* 发送环形缓冲区 */
} UART;

/*
********************************************************************************
* 定义模块变量
********************************************************************************
*/
static INT8U uart_flag;
static UART  uart[2];
static volatile REG_16C552 *uartreg[2] = {(REG_16C552 *)EXT_SR_CSA_BASE,(REG_16C552 *)EXT_SR_CSB_BASE};
#pragma O0

INT16S ReadExtUart(INT8U ch)
{
    if (ch >= 2) return -1;
    return ReadRoundBuf(&uart[ch].r_round);
}

BOOLEAN WriteExtUart(INT8U ch, INT8U c)
{
    INT16S tempch;

    if (ch >= 2) return false;
    if (!WriteRoundBuf(&uart[ch].s_round, c)) {
        return false;
    }
    if (uartreg[ch]->LSR & 0x20) {                       /* 发送缓冲区为空 */
        if ((tempch = ReadRoundBuf(&uart[ch].s_round)) != -1) {
            uartreg[ch]->THR = tempch;
            //while((uartreg[ch]->LSR & 0x20) == 0){} //查询时打开,中断时关闭
        }
    }
    return true;
}

BOOLEAN WriteExtUart_Block(INT8U ch, INT8U *ptr, INT8U len)
{
    if (ch >= 2) return false;
    if (len > LeftOfRoundBuf(&uart[ch].s_round)) return false;

    for (; len > 0; len--) {
        WriteExtUart(ch, *ptr++);
    }
    return TRUE;
}

INT16U ExtUart_ready(INT8U ch)
{
    return LeftOfRoundBuf(&uart[ch].s_round);
}

static void IRQ0_handler(void)
{
    INT8U  i;
    INT16S c;    
    uart_flag = uartreg[0]->ISR & 0x0e;				/* 读中断标志寄存器 */
#if EN_DEBUG_BSP
    //PrintFromUART(DEBUG_UARTNo_DRIV, "\nuart_flag=");
    //SendFromUART_HEX(DEBUG_UARTNo_DRIV, uart_flag);
#endif                 
if (uart_flag == 0x04 || uart_flag == 0x0c) {       /* 处理接收中断 */

    for (i = 1; i <= 16; i++) {
        if (uartreg[0]->LSR & 0x01) {                   /* 接收缓冲区存在未读数据 */
            WriteRoundBuf(&uart[0].r_round, uartreg[0]->RHR);
        } else {
            break;
        }
    }
  } else if (uart_flag == 0x02) {                     /* 处理发送中断 */
    
    for (i = 1; i <= 16; i++) {
        if (uartreg[0]->LSR & 0x20) {                   /* 发送缓冲区为空 */
            if ((c = ReadRoundBuf(&uart[0].s_round)) != -1) {
                uartreg[0]->THR = c;
            } else {
                break;
            }
        } else {
            break;
        }
    }
  }
}

static void IRQ1_handler(void)
{
	INT8U  i;
    INT16S c;
    uart_flag = uartreg[1]->ISR & 0x0e;                 /* 读中断标志寄存器 */   
  if (uart_flag == 0x04 || uart_flag == 0x0c) {       /* 处理接收中断 */

    for (i = 1; i <= 16; i++) {
        if (uartreg[1]->LSR & 0x01) {                   /* 接收缓冲区存在未读数据 */
            WriteRoundBuf(&uart[1].r_round, uartreg[1]->RHR);
        } else {
            break;
        }
    }

  } else if (uart_flag == 0x02) {                     /* 处理发送中断 */
    
    for (i = 1; i <= 16; i++) {
        if (uartreg[1]->LSR & 0x20) {                   /* 发送缓冲区为空 */
            if ((c = ReadRoundBuf(&uart[1].s_round)) != -1) {
                uartreg[1]->THR = c;
            } else {
                break;
            }
        } else {
            break;
        }
    }
  }
}

void ResetExtUart(void)
{
#if EN_XR16L2552 > 0
    AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
	AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
#else
    AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
	AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
#endif
}
 
void InitExtUart(INT8U ch, INT16U baud)
{
    INT16U *ptr;
    INT8U i, temp;
    if (ch >= 2) return;
    
    AT91C_BASE_PIO->PIO_PER  = AT91C_PIO_P8;
    AT91C_BASE_PIO->PIO_OER  = AT91C_PIO_P8;
#if EN_XR16L2552 > 0
    AT91C_BASE_PIO->PIO_CODR = AT91C_PIO_P8;
#else
	AT91C_BASE_PIO->PIO_SODR = AT91C_PIO_P8;
#endif
    InitRoundBuf(&uart[ch].r_round, uart[ch].r_buf, sizeof(uart[ch].r_buf), 0);     /* 初始化接收环形缓*/
    InitRoundBuf(&uart[ch].s_round, uart[ch].s_buf, sizeof(uart[ch].s_buf), 0);     /* 初始化发送环形缓*/
    ptr = (INT16U *)uartreg[ch];
    for (i = 1; i <= 8; i++) {                          /* 读16C552寄存器 */
        temp = *ptr++;
    }


    /* 配置16C552寄存器 */
    uartreg[ch]->LCR = 0x83;                             
    uartreg[ch]->DLL = frequency / 16L / baud;          /* 配置串口波特率 */
    uartreg[ch]->DLM = (frequency / 16L / baud) >> 8;
    uartreg[ch]->LCR = 0x03;							/* 设置1位起始位,8位数据位,1位停止位,无奇偶校验码 */
    uartreg[ch]->FCR = 0x87;                            /* 使能FIFO模式,复位接收发送FIFO,每收8个字节中断一次 */
    uartreg[ch]->IER = 0x03;                            /* 允许接收发送中断 */
    uartreg[ch]->MCR = 0x08;
#if EN_DEBUG_BSP > 0
    PrintFromUART(DEBUG_UARTNo_DRIV, "\nafter write uartreg[");
    SendFromUART_HEX(DEBUG_UARTNo_DRIV, ch);
    PrintFromUART(DEBUG_UARTNo_DRIV, "]=");
#endif
	ptr = (INT16U *)uartreg[ch];
    for (i = 1; i <= 8; i++) {                          /* 读16C552寄存器 */
        temp = *ptr++;
#if EN_DEBUG_BSP > 0 
        SendFromUART_HEX(DEBUG_UARTNo_DRIV, temp);
#endif       
    }
 
    if (ch == 0) {                                      
        PIO_Close(AT91C_P9_IRQ0);
		AIC_Install( AT91C_ID_IRQ0,IRQ0_INTERRUPT_PRIO,AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, IRQ0_handler);
		AIC_Int_Enable(AT91C_ID_IRQ0);
    } else { 
   																							
    	PIO_Close(AT91C_P10_IRQ1);
		AIC_Install( AT91C_ID_IRQ1,IRQ1_INTERRUPT_PRIO,AT91C_AIC_SRCTYPE_EXT_POSITIVE_EDGE, IRQ1_handler);
		AIC_Int_Enable(AT91C_ID_IRQ1);
                 
    }
}


#if EN_DEBUG_BSP > 0
static INT8U temp[120];
void Poll16c552(void)
{ 
 	INT16S j;
 	INT16U i,usedlen;
 	
 	for(j=0;j<2;j++){
 	usedlen = UsedOfRoundBuf(&uart[j].r_round);
 	if(usedlen >100) {
 		for(i=0;i<usedlen;i++) {
 			temp[i] = ReadRoundBuf(&uart[j].r_round);
 		}
 		PrintFromUART(DEBUG_UARTNo_DRIV,"\nextuartID=");
 		SendFromUART_HEX(DEBUG_UARTNo_DRIV, j); 		
 		PrintFromUART(DEBUG_UARTNo_DRIV,"\nrecvdatalen=");
 		SendFromUART_HEX(DEBUG_UARTNo_DRIV, usedlen);
 		PrintFromUART(DEBUG_UARTNo_DRIV,"\ndata=");
 		SendFromUART_MEM_HEX(DEBUG_UARTNo_DRIV, temp, usedlen);
 	}
 	}
}

static INT8U checkarray[200];
void check16c552send(void)
{
    INT16U i,j;
    INT8U *ptr;     
    InitExtUart(0, 9600);
	InitExtUart(1, 9600); 
    for(;;) {
    	ptr = checkarray;
    	for(i=1; i<65535; i++) {
    		*ptr++ = i;
    		if(i%200 == 0) {
    			ClearWatchdog();
    			//PrintFromUART(DEBUG_UARTNo_DRIV, "\n");
    			//SendFromUART_MEM_HEX(DEBUG_UARTNo_DRIV, checkarray, 200);    			
    			WriteExtUart_Block(0, checkarray, 200);
    			WriteExtUart_Block(1, checkarray, 200);
    			ptr = checkarray;
    			for(j=65535; j>0; j--);
    			for(j=65535; j>0; j--);
    	    		
    		}
    	ClearWatchdog();
		for(j=5000; j>0; j--);
    	Poll16c552();
    	ClearWatchdog();
		}
	}
    
}
#endif

⌨️ 快捷键说明

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