以下部分内容来自spra633b "TMS320C6000 McBSP UART"颜色为兰色
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /> 使用MCBSP的内部波特率进行同步,MCBSP可以被配置以16b字发送和接收每个UART位。软件必须将每个要发送的位扩展成16b,并将输入的16b数据压成单个 bit。同时要处理必要的同步数据,如起始位,停止位。
McBSP Setup: Serial Port Implementation<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
C6000将每个UART位当作16b数据。内部采样率发生器被配置为产生一个16倍于串口波特率的时钟。由于UART起始位是一个下降沿,因这个下降沿可心作为帧同步的输入,这就是为什么FSR和DR都被连接到UART的输出。为了防止MCBSP被重复触发,在开始接收数据后需要忽略所有的帧同步信号。为了使用8N1(8数据位1停止位,无校验)方式发送UART数据,
将MCBSP配置为UART输要设置几个参数。
• Pin Control Register (PCR) PCR = 0x00000B0C
Receive Control Registers (RCR) RCR = 0x81050840
Transmit Control Registers (XCR) XCR = 0x81040840
Sample Rate Generator Register (SRGR) SRGR = 0x2000006C
CLKGDV= (CPU Clock frequency) / (16 * baud rate) -1.
MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV 57600 */
如果DSP时钟为200Mhz,当波特率为115200时,分频比为0x6C,实际波特率偏差为:0.4%。当分频比为216时,波特率为57600。没有办法使用更低频率的时钟,除非为MCBSP外接一个同步时钟。
Receiving/Transmitting UART Data
发送时,发送转换程序将需要被发送的数据按位转换16b。发送转换程序将扩展好的数据加上起始位0x0000及停止位0xFFFF放入发送缓冲器中。EDMA被设置为将数据从发送缓冲器传送到MCBSP,因为数据在发送缓冲区中已经是正确的UART格式,MCBSP帧同步产生器能连续地传送这些数据。void ProcessTransmitData(void);
接收时,EDMA将数据将被扩展的数据从MCBSP中读出,并写到接收缓冲区中,软件将禁止数据处理,直到EDMA完成一个段数据的传送。一个压缩程序被调用将数据还原成正确的数据。void ProcessReceiveData(void);
/* Open the McBSP channel 1 */
hMcbsp1 = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET);
使用CLS库,如果使用上述函数将打开McBSP1
如果改为MCBSP_DEV0将打开McBSP0
C6x的多通道缓冲串行口(McBSP) 可以运行在不同的模式,由不同的应用要求,为了保证正确工作,串行口必须在特定的顺序进行初始化。
当EDMA或CPU被用于处理McBSP数据,典型情况下,EDMA用于读/写数据从/到McBSP。EDMA传送是读/写同步的,McBSP提供这些同步状态。如可使用CPU从DRR读数据,或向DXR写数据,查询或中断的方式都可以使用。
McBSP Introduction
发送器:发送器将写入DXR寄存器中的数据发送出去。DXR中的内容被拷贝XSR。当发送帧同步信号(FSX)被检测到时,传送立即开始。每一个CLKX时钟下,一个XSR中数据位将被传送。新的数据可以被写入DXR使用CPU或DMA。
接收器:在每个CLKR时钟下,DR引脚上的数据被移位至RSR寄存器。真正的数据移位开始于接收帧同步信号(FSR)。RSR中的数据被拷贝至接收缓冲寄存器(RBR),然后到数据接收寄存器(DRR)。 DRR可以被CPU或EDMA读取。
采样率产生器: As the name implies, 这个模块产生控制发送/接收的时钟信号以及必须的帧同步信号。时钟产生电路允许使用者通过CLKS选择CPU时钟或外部时钟作为源产生CLK(R/X)。帧同步信号的特性,如帧周期,帧宽也可编程。FS(R/X), CLK(R/X) 是双向引脚。
事件/中断产生: McBSP 产生为EDMA产生帧事件告知数据已经在DRR中准备好。或者DXR已经准备好接受新的数据。这些都是读同步事件REVT和写同步事件XEVT。同理CPU也可以通过中断(RINT and XINT)读/写数据到McBSP。
Servicing the McBSP
C6000可以通过CPU或EDMA操作McBSP。所有控制寄存器只能通过CPU编程。但DXR和DRR可以通过CPU或EDMA访问。通常EDMA通过用于读写数据,这样可以减轻CPU处理低速外围的压力。TMS320C6000 DMA Applications(SPRA529) and TMS320C6000 Enhanced DMA: Example Applications (SPRA636).
EDMA方式:EDMA使用写同步事件XEVT写DXR,使用读同步事件REVT读DRR。在每个EDMA在每个串口单元传送时读或写McBSP,当EDMA完成需要的单元数目后,如果需要可以产生一个通道结束中断。
CPU方式: CPU可以用中断或查询方式操作McBSP,查询时,SPCR中的(R/X)RDY位被查询检查McBSP是否可以发送新的数据或有新的数据需要接收。在中断方式,CPU处理McBSP产生的中断。中断模式寄存器(R/X)INTM = 00b 缺省值产生McBSP中断。当CPU中断允许时McBSP在每个数据单元发送/接收时通过(R/X)INT产生中断。其它中断模式用于诊断和跟踪功能。
Initialization Requirements
McBSP中的控制信号如:时钟、帧同步、时钟源都是可以编程。模块被编程激活的顺序对正确操作McBSP是非常重要的。
查询方式UART的实现:
需要实现下列函数
void ConfigMcBSP(void);
short* ProcessTransmitData(char xmitchar);
char ProcessReceiveData(short*);
short VoteLogic(unsigned short);
void McBSP_UART_OutChar(char);
char McBSP_UART_InChar(void);
初始化过程:
CSL_init(); /* initialize the CSL library */
IRQ_nmiEnable();/* enable NMI and GI */
IRQ_globalEnable();
hMcbsp1 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET); /* Open the McBSP channel 0 */
ConfigMcBSP();/* Setup for McBSP */
MCBSP_enableSrgr(hMcbsp1); /* Start Sample Rate Generator: set /GRST = 1 */
/* inserted wait time for McBSP to get ready */
for (waittime=0; waittime<0xF; waittime++);
/* Wake up the McBSP as transmitter and receiver */
MCBSP_enableRcv(hMcbsp1);
MCBSP_enableXmt(hMcbsp1);
/* Enable Frame Sync Generator for McBSP 1: set /FRST = 1 */
MCBSP_enableFsync(hMcbsp1);
发送时不使用帧同步,直接将数据加上起始位和停止位,并将这10b数据按扩充为10个16b的数据。扩充方式为当数据位为1时扩充为0xFFFF 数据位为0时扩充为0x0000。检测xrdy的状态将数据写入MCBSP即可。
接收时需要使用输入数据的起始位作为帧同步信号,启动接收。接收过程中数据的下降沿被忽略。
附:查询方式代码
/*******************************************************************/
/* Sinovee Microsystems */
/* Date Created: 03/31/2007 */
/* Date Last Modified: 03/31/2007 */
/* Source File: uart.c */
/* Original Author: Todd Hiers */
/* Author: 罗昊 */
/* */
/* 被始化C6000 McBSP 与UART通信 */
/* communicate with a . By modifying the CHIP definition, */
/* On 6x0x devices, DMA channels 1 and 2 are used to service */
/* McBSP 1 transmit and receive operations, respectively. On */
/* 6x1x/64x devices, EDMA channels 14 and 15 are used to service */
/* McBSP 1 transmit and receive operations, respectively. */
/* */
/* For this example, a data string is being transmitted from McBSP */
/* transmit (DX) to McBSP receive (DR). Each bit of the 8.bit */
/* ASCII character is expanded into 16.bit UART transmission word. */
/* Once being received, the 16.bit UART transmission words are */
/* compressed back to binary bits and ASCII form. */
/* */
/* For the code to work, DX, DR, and FSR of McBSP1 are shorted */
/* together. */
/* */
/* This code has been verified for functionality on 6711, 6202, */
/* and 6203 devices. */
/* */
/* This program is based on CSL 2.0. Please refer to the */
/* TMS320C6000 Chip Support Library API User’s Guide for further */
/* information. */
/*******************************************************************/
/* Chip definition . Please change this accordingly */
#define CHIP_6205 1
/* Include files */
#include
#include
#include
#define TRUE 1
#define FALSE 0
#define BUFFER_SIZE 30
/* Declare CSL objects */
MCBSP_Handle hMcbsp1; /* handle for McBSP1 */
volatile int receive_done = FALSE;
volatile int transmit_done = TRUE;
short xmitbuf[10];
short recvbuf[30];
char xmit_msg[BUFFER_SIZE] = "McBSP does UART on C6000!\r\n";
char recv_msg[BUFFER_SIZE];
/* Include the vector table to call the IRQ ISRs hookup */
//extern far void vectors();
/* Prototypes */
void ConfigMcBSP(void);
short* ProcessTransmitData(char xmitchar);
char ProcessReceiveData(short*);
short VoteLogic(unsigned short);
void McBSP_UART_OutChar(char);
char McBSP_UART_InChar(void);
/*******************************************************************/
/* void main(void) */
/*******************************************************************/
void main(void)
{
int i;
int waittime = 0;
char temp;
/* initialize the CSL library */
CSL_init();
/* enable NMI and GI */
IRQ_nmiEnable();
IRQ_globalEnable();
/* point to the IRQ vector table */
//IRQ_setVecs(vectors);
/* Open the McBSP channel 1 */
hMcbsp1 = MCBSP_open(MCBSP_DEV0, MCBSP_OPEN_RESET);
/* Setup for McBSP */
ConfigMcBSP();
/* Start Sample Rate Generator: set /GRST = 1 */
MCBSP_enableSrgr(hMcbsp1);
/* inserted wait time for McBSP to get ready */
for (waittime=0; waittime<0xF; waittime++);
/* Wake up the McBSP as transmitter and receiver */
MCBSP_enableRcv(hMcbsp1);
MCBSP_enableXmt(hMcbsp1);
/* Enable Frame Sync Generator for McBSP 1: set /FRST = 1 */
MCBSP_enableFsync(hMcbsp1);
for(i = 0;i {
McBSP_UART_OutChar(xmit_msg);
} /*end of i */
for(i = 0;i<30;i++)
{
temp = McBSP_UART_InChar();
recv_msg = temp;
}/*end of i */
printf("String recieved: %s \r\n", recv_msg);
MCBSP_close(hMcbsp1); /* close McBSP 1 */
} /* End of main() */
/*******************************************************************/
/* void ConfigMcBSP(void): Setup for McBSP Configuration */
/*******************************************************************/
void ConfigMcBSP(void)
{
MCBSP_Config mcbspCfg1 = {
/* SPCR Setup */
MCBSP_SPCR_RMK(
MCBSP_SPCR_FRST_DEFAULT, /* 0 */
MCBSP_SPCR_GRST_DEFAULT, /* 0 */
MCBSP_SPCR_XINTM_XRDY, /* 00 */
MCBSP_SPCR_XSYNCERR_DEFAULT, /* 0 */
MCBSP_SPCR_XRST_DEFAULT, /* 0 */
MCBSP_SPCR_DLB_OFF, /* 0 */
MCBSP_SPCR_RJUST_RZF, /* 00 */
MCBSP_SPCR_CLKSTP_DISABLE, /* 0x */
MCBSP_SPCR_RINTM_RRDY, /* 00 */
MCBSP_SPCR_RSYNCERR_DEFAULT, /* 0 */
MCBSP_SPCR_RRST_DEFAULT /* 0 */
),
/* RCR Setup */
#if 0 //orignal
MCBSP_RCR_RMK(
MCBSP_RCR_RPHASE_DUAL, /* 1 */
MCBSP_RCR_RFRLEN2_OF(1), /* 00010 */
MCBSP_RCR_RWDLEN2_8BIT, /* 000 */
MCBSP_RCR_RCOMPAND_MSB, /* 00 */
MCBSP_RCR_RFIG_YES, /* 1 */
MCBSP_RCR_RDATDLY_1BIT, /* 01 */
MCBSP_RCR_RFRLEN1_OF(8), /* 01000 */
MCBSP_RCR_RWDLEN1_16BIT /* 010 */
),
#else
MCBSP_RCR_RMK(
MCBSP_RCR_RPHASE_DUAL, /* 1 */
MCBSP_RCR_RFRLEN2_OF(1), /* 00010 */
MCBSP_RCR_RWDLEN2_8BIT, /* 000 */
MCBSP_RCR_RCOMPAND_MSB, /* 00 */
MCBSP_RCR_RFIG_YES, /* 1 */
MCBSP_RCR_RDATDLY_1BIT, /* 01 */
MCBSP_RCR_RFRLEN1_OF(7), /* 01000 */
MCBSP_RCR_RWDLEN1_16BIT /* 010 */
),
#endif
/* XCR Setup */
MCBSP_XCR_RMK(
MCBSP_XCR_XPHASE_DUAL, /* 1 */
MCBSP_XCR_XFRLEN2_OF(1), /* 00010 */
MCBSP_XCR_XWDLEN2_8BIT, /* 000 */
MCBSP_XCR_XCOMPAND_MSB, /* 00 */
MCBSP_XCR_XFIG_YES, /* 1 */
MCBSP_XCR_XDATDLY_0BIT, /* 00 */
MCBSP_XCR_XFRLEN1_OF(8), /* 01000 */
MCBSP_XCR_XWDLEN1_16BIT /* 010 */
),
/* SRGR Setup */
MCBSP_SRGR_RMK(
MCBSP_SRGR_GSYNC_FREE, /* 0 */
MCBSP_SRGR_CLKSP_RISING, /* 0 */
MCBSP_SRGR_CLKSM_INTERNAL, /* 1 */
MCBSP_SRGR_FSGM_DXR2XSR, /* 0 */
MCBSP_SRGR_FPER_DEFAULT, /* 0 */
MCBSP_SRGR_FWID_DEFAULT, /* 0 */
// MCBSP_SRGR_CLKGDV_OF(108) /* CLKGDV for 115200 */
MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV for 57600 */
),
/* MCR Setup */
MCBSP_MCR_DEFAULT, /* default values */
/* RCER Setup */
MCBSP_RCER_DEFAULT, /* default values */
/* XCER Setup */
MCBSP_XCER_DEFAULT, /* default values */
/* PCR Setup */
MCBSP_PCR_RMK(
MCBSP_PCR_XIOEN_SP, /* 0 */
MCBSP_PCR_RIOEN_SP, /* 0 */
MCBSP_PCR_FSXM_INTERNAL, /* 1 */
MCBSP_PCR_FSRM_EXTERNAL, /* 0 */
MCBSP_PCR_CLKXM_OUTPUT, /* 1 */
MCBSP_PCR_CLKRM_OUTPUT, /* 1 */
MCBSP_PCR_CLKSSTAT_0, /* 0 */
MCBSP_PCR_DXSTAT_0, /* 0 */
MCBSP_PCR_FSXP_ACTIVELOW, /* 1 */
MCBSP_PCR_FSRP_ACTIVELOW, /* 1 */
MCBSP_PCR_CLKXP_RISING, /* 0 */
MCBSP_PCR_CLKRP_FALLING /* 0 */
// MCBSP_PCR_CLKRP_RISING /* 0 */
)
};
MCBSP_config(hMcbsp1, &mcbspCfg1);
} /* 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. */
/*******************************************************************/
short *ProcessTransmitData(char xmitchar)
{
int i;
short cnt;
short *xmitbufptr;
/* point to Transmit Buffer */
xmitbufptr = xmitbuf;
for (i=0; i<(sizeof(xmitbuf)/sizeof(short)); i++)
{
xmitbufptr = 0x0000; /* zero fill buffer */
}
/* Process BYTE of transmit character */
for (cnt = -1; cnt < 10; cnt++)
{
if (cnt == -1)
*xmitbufptr++ = 0x0000;
else if (cnt == 8 || cnt ==9)
*xmitbufptr++ = 0xFFFF;
else if (xmitchar & (1 << cnt))
*xmitbufptr++ = 0xFFFF;
else
*xmitbufptr++ = 0x0000;
} /* end for cnt */
return xmitbuf;
} /* 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. */
/*******************************************************************/
char ProcessReceiveData(short *recvbuf)
{
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;
recv_char = 0;
/* Process each UART frame */
for (cnt = -1; cnt < 10; cnt++)
{
if(cnt == -1 || cnt == 8 || cnt == 9)
{
/* 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 */
return recv_char;
} /* end ProcessReceiveData() 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 */
void McBSP_UART_OutChar(char xmitchar)
{
int cnt;
short *xmitbufptr;
xmitbufptr = ProcessTransmitData(xmitchar);
for(cnt = 0;cnt < 10;cnt++)
{
while(!(MCBSP_xrdy(hMcbsp1))); //wait for transmitter ready
MCBSP_write(hMcbsp1,xmitbufptr[cnt]);
}/* end cnt */
}/* end McBSP_UART_OutChar() funciton */
char McBSP_UART_InChar(void)
{
char charget;
int cnt;
short *recvbufptr;
recvbufptr = recvbuf;
for(cnt = 0;cnt < 10;cnt++)
{
while(!(MCBSP_rrdy(hMcbsp1))); //wait for reciev ready
recvbufptr[cnt] = MCBSP_read(hMcbsp1);
}/* end cnt */
charget = ProcessReceiveData(recvbufptr);
return charget;
}
用户377235 2012-5-8 12:59
用户1381176 2009-9-29 16:04
用户191304 2009-6-2 10:43
southcreek 2007-5-30 21:06
southcreek 2007-5-30 21:04
用户389537 2007-5-29 08:57
请问southcreek,我还有一事不明。你这边说
CLKGDV= (CPU Clock frequency) / (16 * baud rate) -1.
MCBSP_SRGR_CLKGDV_OF(216) /* CLKGDV 57600 */
而我有在其它资料上看到
CLKGDV=(McBSP的时钟频率)/(16倍的波特率)-1。
时钟频率必须进行适当的配置,以便产生 16倍波特率的频率。对于 6711,CPU的时钟频率为150MHZ,McBSP的时钟频率为75MHZ,波特率为115200bps,此时通过上式计算得CLKGDV=41.
请问如果是6713的话该如何算呢?6713的主频是225MHZ。
QQ:357448476
或者这边回答也可,谢谢!
用户389537 2007-5-29 08:44
你好:
请问一下,你这测试代码对应的硬件电路是UART模式还是GPIO模式呢?我想是UART的吧?
QQ:3574489476
邮箱:huaeast@163.com
This diagram shows that DX, DR, FSX, and FSR
of McBSP1 are all connected together.
___________________
|2 1|
| |
| |
| |
| |
| |
|CLK0 FSX0|
|DX0 |
|DR0 FSR0|
| |
+----|DX1 36 35 FSX1|
| | |
+----|DR1 42 41 FSR1|----+
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| |____________ ______| |
| |
+---------------------------------+
southcreek 2007-5-28 16:47
我做完了原理图,样例程序,烧写程序。
调通了串口。现在交给做软件的了。
wang1jin 2006-11-10 00:59
用户1318081 2006-10-12 08:29
不好意思啊