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

📄 examplec.c

📁 Implementing a Software UART on the TMS320C54x with the McBSP and DMA
💻 C
字号:
/****************************************************************
* Filename: ExampleC.c						*
* Function: Software UART Access code in C			*
* Author:   Robert J. DeNardo					*
* 	    Texas Instruments, Inc				*
* Revision History:						*
* 11/12/99  Original Code			Robert DeNardo	*
* 12/21/99  Modified example loop structure.	Robert DeNardo	*
* 09/05/00  Fixed address of PMST register.	Robert DeNardo	*
*           Setup for 5402DSK.                                  *  
* 10/23/00  Fixed LSI int to update TxHeadPtr	Robert DeNardo	*
*	    instead of TxTailPtr. 
*            							*
* This code performs basic accesses to the software UART	*
* using C code.							* 
*								*
* Defining the INTERRUPTBASED keyword below will setup the	*
* UART to receive a block of 10 chars and then transmit that	*
* block of 10 chars using the UART interrupt routines.		* 
* If this is used, make sure the INTERRUPT_BASED definition	*
* in UARTsetup.inc is set to 1.					*
*								*
* Not defining the INTERRUPTBASED keyword will setup the	*
* UART to use a polling method to receive and transmit		*
* one char at a time.  If this is used, make sure the 		*
* INTERRUPT_BASED definition in UARTsetup.inc is set to 0.	* 
*                                                               *
* This code is set to run on 5402DSK.  Make sure to set CPLD    *
* to use McBSP0 from daughterboard (0x4@io = 0xFF03).           *
*****************************************************************/
#if 0
#define INTERRUPTBASED
#endif


extern volatile struct StatusStruct{           	/* structure to model the UARTLSR status bits */
	unsigned int reserved:10;
   	unsigned int THRE:1;         	/* Transmit Holding Register Empty */
   	unsigned int BI:1;		/* Break Indicator */
   	unsigned int FE:1;		/* Frame Error */
   	unsigned int PE:1;		/* Parity Error */
   	unsigned int OE:1;		/* Overrun Error */
   	unsigned int DR:1;		/* Data Ready */
   }UARTLSR;
  
#define TXNUM 10  
#define BUFSIZE	20
volatile int RxCharCnt;
int *RxHeadPtr;
int *RxTailPtr;
int *TxHeadPtr;
int *TxTailPtr;   
int RxCharBuf[50]={0};	/* create a received character buffer */
int TxCharBuf[50]={0};  /* create a transmit character buffer */

void InitPLL()  	/* sets up PLL for a 3.75 multiplier */
{
	volatile unsigned int *CLKMD=(volatile unsigned int*)0x58; /* set address of CLKMD reg */
	*CLKMD=0;             	/* set to DIV mode */
	while((*CLKMD&1)==1);   /* wait until PLLstatus reflects DIV mode */
	*CLKMD=0xfffb;          /* set to multipler of 3.75 and max count cycles, turn on PLL */
	while((*CLKMD&1)==0);   /* wait until PLLstatus reflects in PLL mode */
}	

#ifdef INTERRUPTBASED
interrupt void UARTRBFint()    /* called from the UART code when a character is received */
{
     	*RxHeadPtr++=UARTRxChar();  /* call UART routine to receive char & move character to receive buffer */
	if(RxHeadPtr>=(RxCharBuf+BUFSIZE))
		RxHeadPtr=RxCharBuf;	/* keep pointer in circular buffer */		
	RxCharCnt++;                /* increment the character count */
}	
	
interrupt void UARTTBEint()   	/* called from the UART code when another character can be transmitted */
{
	if(TxTailPtr!=TxHeadPtr)   		/* if a character to transmit is in buffer, */
	{
		if((*TxTailPtr==0)||(*TxTailPtr==1))	/* send break if char=1 or 0 */
		{        
			UARTSetBreak(*TxTailPtr++); 	/* 1 sends break, 0 sends end of break */
			if(TxTailPtr>=(TxCharBuf+BUFSIZE))
				TxTailPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		}					        		    
		else					/* send character */
		{
			UARTTxChar(*TxTailPtr++);  	/* call UART routine to transmit the character */
			if(TxTailPtr>=(TxCharBuf+BUFSIZE))
				TxTailPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		}
	}
}  

interrupt void UARTLSIint()  	/* called from UART code when a char is received and an error is detected */
{ 
		UARTLSR.OE=0;   		/* clear error flags */
		UARTLSR.PE=0;
		UARTLSR.BI=0;
		UARTLSR.FE=0;
		*TxHeadPtr++=1;			/*put break into tx buffer */
		if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
			TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		*TxHeadPtr++=0; 		/*put end of break into buffer */
		if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
			TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
}

main()
{      
	int i; 
	volatile unsigned int *PMST=(volatile unsigned int*)0x1D;  /* define the PMST reg */
	
	*PMST=0x4020; 		/* IPTR=0x4000, OVLY=1, DROM=0, MP/MC=0 */ 
	InitPLL(); 		/* initialize the DSP Clock to 75MHz (with a 20MHz crystal) */
	UARTInit(); 		/* initialize the McBSP and DMA for UART */
	RxCharCnt=0;		/* init received char count to 0 */
	RxHeadPtr=RxCharBuf;    /* init rx head pointer to start of buffer */
	RxTailPtr=RxCharBuf;    /* init rx tail pointer to start of buffer */
	TxHeadPtr=TxCharBuf;    /* init tx head pointer to start of buffer */
	TxTailPtr=TxCharBuf;    /* init tx tail pointer to start of buffer */
     
	UARTStart(0);    	/* start UART Rx and Tx(begins receiving) */
        for(;;)			/* infinite loop */
        {
        	while(RxCharCnt<TXNUM);	/* wait until TXNUM chars received */
        	for(i=0;i<TXNUM;i++)
       		{
        		*TxHeadPtr++=*RxTailPtr++;  /* copy the TXNUM chars to transmit buffer */
			if(RxTailPtr>=(RxCharBuf+BUFSIZE))
				RxTailPtr=RxCharBuf;	/* keep pointer in circular buffer */		
			if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
				TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		}		
		RxCharCnt-=TXNUM;       		/* reduce number of received chars */
		UARTTxChar(*TxTailPtr++);  		/* kickstart: call UART routine to tx the char */
		if(TxTailPtr>=(TxCharBuf+BUFSIZE))
			TxTailPtr=TxCharBuf;		/* keep pointer in circular buffer */		
		UARTTxChar(*TxTailPtr++);  		/* (put 2 chars in buf to get consecutive transmits) */
							/* It will transmit these TXNUM chars and then stop */
		if(TxTailPtr>=(TxCharBuf+BUFSIZE))
			TxTailPtr=TxCharBuf;		/* keep pointer in circular buffer */		
    	}
}       

#else /*polling method*/
main()
{
	volatile unsigned int *PMST=(volatile unsigned int*)0x1D;  /* define the PMST reg */
	int RxCharBuf[BUFSIZE]={0};	/* create a received character buffer */
	int TxCharBuf[BUFSIZE]={0};  /* create a transmit character buffer */
	
	*PMST=0x4020; 		/* IPTR=0x4000, OVLY=1, DROM=0, MP/MC=0 */ 
	InitPLL(); 		/* initialize the DSP Clock to 75MHz (with a 12MHz crystal) */
	UARTInit(); 		/* initialize the McBSP and DMA for UART */
	RxCharCnt=0;		/* init received char count to 0 */
	RxHeadPtr=RxCharBuf;    /* init rx head pointer to start of buffer */
	RxTailPtr=RxCharBuf;    /* init rx tail pointer to start of buffer */
	TxHeadPtr=TxCharBuf;    /* init tx head pointer to start of buffer */
	TxTailPtr=TxCharBuf;    /* init tx tail pointer to start of buffer */
     
	UARTStart(0);    	/* start UART Rx and Tx(begins receiving) */
	for(;;)                 /* infinite loop */
	{
		if(UARTLSR.DR==1)  			/* if new char is available */
		{
			*RxHeadPtr++=UARTRxChar();	/* get the new char */
			if(RxHeadPtr>=(RxCharBuf+BUFSIZE))
				RxHeadPtr=RxCharBuf;	/* keep pointer in circular buffer */		
		}		
		if(UARTLSR.THRE==1)    		/* if able to transmit a char */
		{	
			if(TxTailPtr!=TxHeadPtr)   		/* if a character to transmit is in buffer, */
			{
				UARTTxChar(*TxTailPtr++);  	/* call UART routine to transmit the character */
				if(TxTailPtr>=(TxCharBuf+BUFSIZE))
					TxTailPtr=TxCharBuf;	/* keep pointer in circular buffer */		
			}
		}
		if((UARTLSR.BI|UARTLSR.FE|UARTLSR.PE|UARTLSR.OE)==1)	/* if any errors */
		{				
			UARTLSR.OE=0;           	/* clear error flags.*/  
			UARTLSR.PE=0;
			UARTLSR.BI=0;
			UARTLSR.FE=0;
			*TxHeadPtr++=1;			/*put break into tx buffer */
			if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
				TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
			*TxHeadPtr++=0; 		/*put end of break into buffer */
			if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
				TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		}
		if(RxTailPtr!=RxHeadPtr)   		/* if new character is in rx buffer, */ 
		{
			*TxHeadPtr++=*RxTailPtr++;	/* put the char in the tx buffer */
			if(RxTailPtr>=(RxCharBuf+BUFSIZE))
				RxTailPtr=RxCharBuf;	/* keep pointer in circular buffer */		
			if(TxHeadPtr>=(TxCharBuf+BUFSIZE))
				TxHeadPtr=TxCharBuf;	/* keep pointer in circular buffer */		
		}			

	}		
}
#endif



⌨️ 快捷键说明

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