www.pudn.com > RS485_USART-ok.rar > usart.c, change:2008-12-15,size:6111b


 
#include "includes.h" 
 
 
  char PCRxBuf1[COMM_REC_DATA_FIFO_SIZE]; 
  char PCRxBuf2[COMM_REC_DATA_FIFO_SIZE]; 
static char PCRxBuf_Index; 
COMM_REC_DATA_FIFO   USART_FIFO; 
 
/************************************************************* 
说明:COMM_USART0_Interrupt_Handler函数,中断句柄 
参数:无 
返回:值无 
**************************************************************/ 
void COMM_USART0_Interrupt_Handler(void)__irq  //适用于KEIL平台 
{ 
    AT91C_BASE_AIC->AIC_IVR   = 0;            // Debug variant of vector read (protect mode is used)   
                                                                        
    AT91C_BASE_AIC->AIC_ICCR  = 1 << AT91C_ID_US0;  // 清除中断    
    AT91C_BASE_AIC->AIC_EOICR = 0;            // 结束中断         
             
    //USART_DATA_IRQ_Handle(AT91C_BASE_US0);    //中断方式 
     
    PC_USART_INTERRUPT();                                       //DMA方式 
         
} 
 
void PC_USART_INTERRUPT(void) 
{ 
    INT32U status;       
    status = AT91C_BASE_US0->US_CSR; 
    status &=  AT91C_BASE_US0->US_IMR; 
    if(status & AT91C_US_RXBUFF) 
    { 
        //Toggle_LED(LED0);   //通讯状态指示 
 
        // 2个接收缓冲区交替工作 
        if(PCRxBuf_Index==0) 
            { 
                AT91F_PDC_SetRx(AT91C_BASE_PDC_US0, PCRxBuf2, COMM_REC_DATA_FIFO_SIZE); 
                //调用函数保存PCRxBuf0[] 待完善 
                PCRxBuf_Index =1; 
            } 
        else 
            { 
                AT91F_PDC_SetRx(AT91C_BASE_PDC_US0, PCRxBuf1, COMM_REC_DATA_FIFO_SIZE); 
                //调用函数保存PCRxBuf1[] 待完善 
                PCRxBuf_Index = 0; 
            }        
    } 
 
    if(status & AT91C_US_TIMEOUT)  //错误监测 
    { 
        //Toggle_LED(LED1);   //通讯状态指示 
        status = COMM_REC_DATA_FIFO_SIZE - AT91C_BASE_US0->US_RCR; 
        if(status!=0) 
            { 
                // 2个接收缓冲区交替工作 
                if(PCRxBuf_Index==0) 
                    { 
                        AT91F_PDC_SetRx(AT91C_BASE_PDC_US0, PCRxBuf2, COMM_REC_DATA_FIFO_SIZE); 
                        //调用函数保存PCRxBuf0[] 待完善 
                        PCRxBuf_Index =1; 
                    } 
                else 
                    { 
                        AT91F_PDC_SetRx(AT91C_BASE_PDC_US0, PCRxBuf1, COMM_REC_DATA_FIFO_SIZE); 
                        //调用函数保存PCRxBuf1[] 待完善 
                        PCRxBuf_Index = 0; 
                    }    
                AT91C_BASE_US0->US_CR = AT91C_US_STTTO; 
            } 
         
    } 
     
    AT91C_BASE_US0->US_CR = AT91C_US_RSTSTA;  //复位状态位 
} 
 
     
 void US_Init(void) 
{ 
   
    // Init the US0 USART 
    AT91F_PIO_CfgPeriph( 
                        AT91C_BASE_PIOA, // PIO controller base address 
                        ((unsigned int) AT91C_PA0_RXD0    ) | 
                        ((unsigned int) AT91C_PA3_RTS0    ) | 
                        ((unsigned int) AT91C_PA1_TXD0    ), // Peripheral A 
                        0); // Peripheral B 
    AT91F_US0_CfgPMC(); 
    AT91C_BASE_US0->US_IDR = (unsigned int) -1;     // 禁止该串口的所有中断 
     
    // 复位发送和接收功能 
     
     AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS ; 
     
 
      AT91C_BASE_US0->US_MR =         //设置串口工作模式 
        AT91C_US_USMODE_RS485| 
        AT91C_US_CLKS_CLOCK  | 
        AT91C_US_CHRL_8_BITS| 
         AT91C_US_PAR_NONE| 
           AT91C_US_NBSTOP_1_BIT; 
       
    AT91F_US_SetBaudrate(AT91C_BASE_US0, (unsigned int)AT91B_MCK, (unsigned int)baud_rate); 
     
    AT91F_US_EnableTx (AT91C_BASE_US0);  // 允许串口发送 
    AT91F_US_EnableRx (AT91C_BASE_US0);  // 允许串口接受 
 
    // 设置 USART0 中断 
    AT91F_AIC_ConfigureIt(AT91C_BASE_AIC,               //基地址 
                          AT91C_ID_US0,                             //ID 
                          PC_USART_INTERRUPT_LEVEL,                 //中断优先级为6 
                          AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL,         //内部高电平触发 
                          0);                       //中断处理函数 
      AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned int) COMM_USART0_Interrupt_Handler ; 
 
     
    // PDC  设置 
    AT91F_PDC_Open(AT91C_BASE_PDC_US0); 
    AT91F_PDC_SetRx(AT91C_BASE_PDC_US0, PCRxBuf1, COMM_REC_DATA_FIFO_SIZE); 
    //AT91F_PDC_SetNextRx(AT91C_BASE_PDC_US0, PCRxBuf2, COMM_REC_DATA_FIFO_SIZE); 
    AT91F_PDC_SetNextRx(AT91C_BASE_PDC_US0,  (char *)0, 0); 
    PCRxBuf_Index = 0; 
     
    // 只允许PDC接收缓冲区满中断,采用2缓冲区交替方式 
    
    AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_US0, AT91C_US_RXBUFF);   // DMA 方式接收 
    //AT91F_US_EnableIt((AT91PS_USART)AT91C_BASE_US0, AT91C_US_RXRDY); // 中断方式接受   
    AT91F_AIC_EnableIt (AT91C_BASE_AIC, AT91C_ID_US0); 
  
  
} 
 
/******************************************************* 
说明:Usart_Send()函数通过串口发送字符串 
参数char *str   字符串指针 
函数返回值无 
*******************************************************/ 
void Usart_Send(char *str) 
{ 
    //int achar; 
    //int flag; 
    //achar = character; 
    while(*str !='\0') 
         
        { 
            while( !AT91F_US_TxReady (AT91C_BASE_US0)); 
                AT91C_BASE_US0->US_THR = *str++; 
        }    
} 
 
//********************************************************* 
//函数功能中断处理,将接受到的数据发送到一结构数组 
//返回无 
//********************************************************* 
void USART_DATA_IRQ_Handle(AT91PS_USART pUSART) 
{ 
    INT8U buff_ptr; 
    INT32U status; 
     
    buff_ptr = USART_FIFO.comm_ptr; 
    status = pUSART-> US_CSR; 
 
// 读取状态,以清除中断标志  
    status = AT91C_BASE_US0->US_CSR & AT91C_BASE_US0->US_IMR; 
    if(status & AT91C_US_RXRDY) 
 
         {     USART_FIFO.DATA_BUF[buff_ptr] = (INT8S)AT91F_US_GetChar(AT91C_BASE_US0);             
            USART_FIFO.comm_ptr +=1; 
             
            buff_ptr = USART_FIFO.comm_ptr;              
            if(buff_ptr == COMM_REC_DATA_FIFO_SIZE) 
                    USART_FIFO.comm_ptr = 0; 
        } 
}