基于TI的C55XX系列DSP芯片上McBSP的UART通信(无DMA)

    技术2022-05-20  31

    本人采用的是C5509A芯片。下面代码可以直接用来做rs232串口收发。波特率9600,数据位8,停止位1,无校验。

     

    代码:

    /* Include files */ #include <stdio.h> #include <csl.h> #include <csl_mcbsp.h> #include <csl_irq.h> /* Create buffers and aligning them on an L2 cache line boundary. */ #pragma DATA_SECTION(xmitbuf,"xmit_buf"); unsigned short xmitbuf[0x0400]; #pragma DATA_SECTION(recvbuf,"recv_buf"); unsigned short recvbuf[0x0400]; /* Declare CSL objects */ MCBSP_Handle hMcbsp1; /* handle for McBSP1 */ #define BUFFER_SIZE 27 /* total number of UART data words */ /* Global Variables */ //char xmit_msg[BUFFER_SIZE] = "McBSP does UART on C5000!/n"; char xmit_msg[BUFFER_SIZE] = "McBSP does UART on PPPPPP/n"; char recv_msg[BUFFER_SIZE] = "Transmission didn't work!/n"; /* Get referenc to start of interrupt vector table */ /* This symbol is defined in file, vectors.s54 */ extern void VECSTART(void); /* Prototypes */ void ConfigMcBSP(void); void ProcessTransmitData(); void ProcessReceiveData(); int CheckTestCase(void); short VoteLogic(unsigned short value); void cfg_real_mcbsp(MCBSP_Handle mhMcbsp) { double START_BITS, DATA_BITS,PARITY_BITS,STOP_BITS,BAUD_RATE,DSPCLK,SAMPLES_BITS,PKTBITS,RxPKTBITS,DIV_MAX,DIV_MIN; Uint16 DIV; MCBSP_Config mcbsp_cfg = { MCBSP_SPCR1_DEFAULT, MCBSP_SPCR2_DEFAULT, MCBSP_RCR1_DEFAULT, MCBSP_RCR2_DEFAULT, MCBSP_XCR1_DEFAULT, MCBSP_XCR2_DEFAULT, MCBSP_SRGR1_DEFAULT, MCBSP_SRGR2_DEFAULT, MCBSP_MCR1_DEFAULT, MCBSP_MCR2_DEFAULT, MCBSP_PCR_DEFAULT, MCBSP_RCERA_DEFAULT, MCBSP_RCERB_DEFAULT, MCBSP_RCERC_DEFAULT, MCBSP_RCERD_DEFAULT, MCBSP_RCERE_DEFAULT, MCBSP_RCERF_DEFAULT, MCBSP_RCERG_DEFAULT, MCBSP_RCERH_DEFAULT, MCBSP_XCERA_DEFAULT, MCBSP_XCERB_DEFAULT, MCBSP_XCERC_DEFAULT, MCBSP_XCERD_DEFAULT, MCBSP_XCERE_DEFAULT, MCBSP_XCERF_DEFAULT, MCBSP_XCERG_DEFAULT, MCBSP_XCERH_DEFAULT }; START_BITS=1; DATA_BITS=8; PARITY_BITS=0; STOP_BITS=1; BAUD_RATE=9600; DSPCLK=1000000*12; SAMPLES_BITS=16; PKTBITS=START_BITS+DATA_BITS+PARITY_BITS+STOP_BITS; RxPKTBITS=START_BITS+DATA_BITS+PARITY_BITS+0.5; DIV_MAX=(PKTBITS*DSPCLK)/(BAUD_RATE*(SAMPLES_BITS*RxPKTBITS+3)); DIV_MIN=(PKTBITS-STOP_BITS)*DSPCLK/(BAUD_RATE*(SAMPLES_BITS*RxPKTBITS-3)); DIV=(DIV_MAX+DIV_MIN)/2; printf("DIV=%d/n",DIV); if(DIV <1 || DIV > 254) { printf("DIV is out of boundary/n"); } mcbsp_cfg.spcr1 = MCBSP_SPCR1_RMK(//clear MCBSP_SPCR1_DLB_OFF, /* DLB = 0 */ MCBSP_SPCR1_RJUST_RZF, /* RJUST = 0 */ MCBSP_SPCR1_CLKSTP_DISABLE, /* CLKSTP = 0 clock stop mode bit*/ MCBSP_SPCR1_DXENA_NA, /* DXENA = 0 Dx delay enabler*/ MCBSP_SPCR1_ABIS_DISABLE, /* ABIS = 0 */ MCBSP_SPCR1_RINTM_RRDY, /* RINTM = 0 Rx interrupt mode bit*/ 0, /* RSYNCER = 0 Rx frame sync error*/ MCBSP_SPCR1_RRST_DISABLE /* RRST = 0 receiver reset bit*/ ); mcbsp_cfg.spcr2 = MCBSP_SPCR2_RMK(//clear MCBSP_SPCR2_FREE_NO, /* FREE = 0 仿真调试时的行为*/ MCBSP_SPCR2_SOFT_YES, /* SOFT = 0 同上*/ MCBSP_SPCR2_FRST_FSG, /* FRST = 0 可以reset帧同步*/ MCBSP_SPCR2_GRST_CLKG, /* GRST = 0 可以reset采样速率产生器*/ MCBSP_SPCR2_XINTM_XRDY, /* XINTM = 0 传输中断信号的模式*/ 0, /* XSYNCER = N/A Tx frame sync error*/ MCBSP_SPCR2_XRST_DISABLE /* XRST = 0 可以reset传输*/ ); mcbsp_cfg.rcr1 = MCBSP_RCR1_RMK( //??? MCBSP_RCR1_RFRLEN1_OF(8), /* RFRLEN1 = 0 第一相多少字*/ MCBSP_RCR1_RWDLEN1_16BIT /* RWDLEN1 = 0 第一相每字多少bit*/ ); mcbsp_cfg.rcr2 = MCBSP_RCR2_RMK( MCBSP_RCR2_RPHASE_DUAL, /* RPHASE = 0 一帧几个相*/ MCBSP_RCR2_RFRLEN2_OF(0), /* RFRLEN2 = 0 第2相多少字*/ MCBSP_RCR2_RWDLEN2_8BIT, /* RWDLEN2 = 0 第2相每字几个bit*/ MCBSP_RCR2_RCOMPAND_MSB, /* RCOMPAND = 0 先收高位还是低位*/ MCBSP_RCR2_RFIG_NO, /* RFIG = 1 收到帧同步之后收帧时忽略其他帧同步*/ MCBSP_RCR2_RDATDLY_1BIT /* RDATDLY = 0 收信号的延迟*/ ); mcbsp_cfg.xcr1 = MCBSP_XCR1_RMK(//clear MCBSP_XCR1_XFRLEN1_OF(8), /* XFRLEN1 = 0 */ MCBSP_XCR1_XWDLEN1_16BIT /* XWDLEN1 = 0 */ ); mcbsp_cfg.xcr2 = MCBSP_XCR2_RMK( MCBSP_XCR2_XPHASE_DUAL, /* XPHASE = 1 */ MCBSP_XCR2_XFRLEN2_OF(1), /* XFRLEN2 = 0 */ MCBSP_XCR2_XWDLEN2_8BIT, /* XWDLEN2 = 0 */ MCBSP_XCR2_XCOMPAND_MSB, /* XCOMPAND = 0 */ MCBSP_XCR2_XFIG_NO, /* XFIG = 1 */ MCBSP_XCR2_XDATDLY_0BIT /* XDATDLY = 0 ???*/ ); mcbsp_cfg.srgr1 = MCBSP_SRGR1_RMK( //??? MCBSP_SRGR1_FWID_OF(0), /* FWID = 0 和FPER配合定义帧同步脉冲的宽度*/ MCBSP_SRGR1_CLKGDV_OF(DIV) /* CLKGDV = 1 时钟降频因子*/ ); mcbsp_cfg.srgr2 = MCBSP_SRGR2_RMK( MCBSP_SRGR2_GSYNC_FREE, /* FREE = 0 有无时钟同步*/ MCBSP_SRGR2_CLKSP_RISING, /* CLKSP = 0 时钟上沿还是下沿同步*/ MCBSP_SRGR2_CLKSM_INTERNAL, /* CLKSM = 1 选时钟源的*/ MCBSP_SRGR2_FSGM_DXR2XSR, /* FSGM = 0 帧同步模式*/ MCBSP_SRGR2_FPER_OF(0) /* FPER = 0 和FWID配合定义帧同步宽度*/ ); mcbsp_cfg.pcr = MCBSP_PCR_RMK(//clear MCBSP_PCR_IDLEEN_RESET, /*IDLEN =0 省电用*/ MCBSP_PCR_XIOEN_SP, /* XIOEN = 0 GPIO模式用*/ MCBSP_PCR_RIOEN_SP, /* RIOEN = 0 GPIO模式用*/ MCBSP_PCR_FSXM_INTERNAL, /* FSXM = 1 发送帧同步信号模式*/ MCBSP_PCR_FSRM_EXTERNAL, /* FSRM = 0 接收帧同步信号模式*/ MCBSP_PCR_CLKXM_OUTPUT, /* CLKXM = 1 发送数据的时钟模式*/ MCBSP_PCR_CLKRM_OUTPUT, /* CLKRM = 1 接收数据的时钟模式*/ MCBSP_PCR_SCLKME_NO, /* SCLKME = 0 配合CLKSM设定采样速率生成器的时钟源*/ 0, /* DXSTAT = N/A */ MCBSP_PCR_FSXP_ACTIVELOW, /* FSXP = 1 发送帧同步是高还是低电位*/ MCBSP_PCR_FSRP_ACTIVELOW, /* FSRP = 1 接收帧同步是高还是低电位*/ MCBSP_PCR_CLKXP_RISING, /* CLKXP = 0 发送时钟同步是上沿还是下沿*/ MCBSP_PCR_CLKRP_FALLING /* CLKRP = 0 接收时钟同步是上沿还是下沿*/ ); MCBSP_config(mhMcbsp, &mcbsp_cfg); } /*******************************************************************/ /* void main(void) */ /*******************************************************************/ void main(void) { // int waittime = 0; // int works = FALSE; unsigned short * xmitbufptr; unsigned short * recvbufptr; unsigned short val; unsigned short * ptr; int i; /* initialize the CSL library */ CSL_init(); /* Set IPTR to start of interrupt vector table */ IRQ_setVecs((Uint16)(&VECSTART)); /* process transmit data */ printf("Processing Transmit string.../n"); ProcessTransmitData(); printf("String transmitted: %s /n", xmit_msg); /* Open the McBSP channel 1 */ hMcbsp1 = MCBSP_open(MCBSP_PORT1, MCBSP_OPEN_RESET); /* Setup for McBSP */ ConfigMcBSP(); //cfg_real_mcbsp(); /* Start the MCBSP and Sample Rate Generator */ MCBSP_start(hMcbsp1, MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC | MCBSP_RCV_START | MCBSP_XMIT_START, 0x200 ); // send data for test /* point to Transmit Buffer */ xmitbufptr = (unsigned short *)xmitbuf; for( i = 0; i< BUFFER_SIZE * 11; i++ ) { while (!MCBSP_xrdy(hMcbsp1)); MCBSP_write16(hMcbsp1,xmitbufptr[i]); //printf("====write 16bit : %d/n",xmitbufptr[i]); } // receive test data recvbufptr = (unsigned short *) recvbuf; for( i = 0; i< (BUFFER_SIZE * 10); i++ ) { /* Wait for RRDY signal to read data from DRR */ while (!MCBSP_rrdy(hMcbsp1)); /* Read 16 bit value from DRR */ recvbufptr[i] = MCBSP_read16(hMcbsp1); } /* process received data */ printf("Processing Receive string.../n"); ProcessReceiveData(); printf("String received: %s /n", recv_msg); MCBSP_close(hMcbsp1); /* close McBSP 1 */ printf("============ completed =============/n"); } /* End of main() */ /*******************************************************************/ /* void ConfigMcBSP(void): Setup for McBSP Configuration */ /*******************************************************************/ void ConfigMcBSP(void) { cfg_real_mcbsp(hMcbsp1); } /* end of Config_McBSP(void) */ /*******************************************************************/ /* void ProcessTransmitData(void) */ /* */ /* This function expands each of the 8-bit ASCII characters in the */ /* transmit string "xmit_msg" into UART transmission 16-bit word */ /* and place them in the transmit buffer "xmitbuf". In addition, */ /* 16-bit Start and 8-bit Stop framing words, respectively, are */ /* inserted before and after each of the ASCII characters in the */ /* buffer. */ /*******************************************************************/ void ProcessTransmitData(void) { int i; short cnt = 1; unsigned char xmit_char; unsigned short *xmitbufptr; /* point to Transmit Buffer */ xmitbufptr = (unsigned short *)xmitbuf; for (i=0; i<(sizeof(xmitbuf)/sizeof(unsigned int)); i++) { xmitbufptr[i] = 0x0000; /* zero fill buffer */ } xmitbufptr = (unsigned short *)xmitbuf; /* Process data BYTES in xmit_msg[] and put in xmit buffer */ for (i = 0; i < BUFFER_SIZE; i++) { /*Get transmit character (one byte) from xmit_msg[] and put in xmit buffer*/ xmit_char = xmit_msg[i]; /* Process each BYTE of transmit character */ for (cnt = -1; cnt < 10; cnt++) { if (cnt == -1) *xmitbufptr++ = 0x0000; else if (cnt == 8 || cnt ==9) *xmitbufptr++ = 0x00FF; //2份8bit的停止位,等于1个停止位 else if (xmit_char & (1 << cnt)) *xmitbufptr++ = 0xFFFF; else *xmitbufptr++ = 0x0000; } /* end for cnt */ } /* end for i */ } /* end ProcessTransmitData */ /*******************************************************************/ /* void ProcessReceiveData(void) */ /* */ /* This function decodes the data in the receive buffer, "recvbuf" */ /* and strips the framing start (0x0000) and Stop (0xFFFF) words. */ /* It calls the subroutine VoteLogic() to determine each bit of */ /* the ASCII character. It then puts the result in recv_msg. */ /*******************************************************************/ void ProcessReceiveData(void) { int i; unsigned char recv_char = 0; short cnt = -1; short recv_val; unsigned short raw_data; unsigned short *recvbufptr; /*receive buffer pointer*/ /* Point to the receive buffer */ recvbufptr = (unsigned short *)recvbuf; /* Process all data in the Receive buffer */ for (i = 0; i < BUFFER_SIZE; i++) { recv_char = 0; /* Process each UART frame */ for (cnt = -1; cnt < 9; cnt++) { if(cnt == -1 || cnt == 8) //发的时候2个停止位,为保险起见。收的时候一个停止位,为配置方便起见 { /* Ignore Start and Stop bits */ *recvbufptr++; } else { /* Get 16-bit data from receive buffer */ raw_data = *recvbufptr; recvbufptr++; /* get the value of the majority of the bits */ recv_val = VoteLogic(raw_data); /* put received bit into proper place */ recv_char += recv_val << cnt; } } /* end for cnt */ /* A full BYTE is decoded. Put in result: recv_msg[i] */ recv_msg[i] = recv_char; } /* end for i */ } /* end ProcessReceiveData() function */ /*******************************************************************/ /* void CheckTestCase(void) */ /*******************************************************************/ int CheckTestCase(void) { unsigned short *source; unsigned short *result; unsigned int i = 0; short cnt = -1; int error = 0; source = (unsigned short *) xmitbuf; result = (unsigned short *) recvbuf; for (i = 0; i < BUFFER_SIZE ; i++) { for (cnt = -1; cnt < 10; cnt++) { /* Ignore the start and stop bits */ if(cnt == -1 || cnt == 8 || cnt ==9) { source++; result++; } else { if (*source != *result) { error = i + 1; break; } source++; result++; } } } return(error); } /* end CheckTestCase() function */ /*******************************************************************/ /* short VoteLogic(unsigned short) */ /* */ /* This function decoded the received character by testing the */ /* center 4 bits of the baud. A majority rule is used for the */ /* decoding. */ /*******************************************************************/ short VoteLogic(unsigned short value) { short returnvalue; switch ((value >> 6) & 0x0F) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 8: case 9: case 10: returnvalue = 0; break; case 7: case 11: case 12: case 13: case 14: case 15: returnvalue = 1 ; break; } /* end switch */ return (returnvalue); } /* end VoteLogic() funciton */

     

     

     

    当时做这块花了不少的时间,走了一些弯路,当时在网上也找不到一个详细到稍微改改就能用的例子。

    希望在这方面别人不要也走没必要的弯路,所以把它贴出来,希望能有帮助。

     


    最新回复(0)