近日需要编写一个C6416板的串口程序,一开始打算参考TI EXAMPLES,但是TI 的 McBSP例子
都是DLB(数据回路)模式的,不能用,后来google 一下找到spra633c.pdf,看了下,从
http://www-s.ti.com/sc/techlit/spra633.zip 下载了份示例代码,代码基本可以用,
但要根据硬件的情况修改,配置McBSP 寄存器最关键下面几个地方:
1. 波特率 CLKGDV= (CLK) / (16 * baud rate) -1, 比如我这边用的是 6416 1 GHZ,主频是 960MHz,
采用的是 CPU/4 clock for C64x DSP, 波特率采用115200,所以这里 CLKGDV= ((960 * 1000000) / 4) / (16 * 115200) -1 = 129
注意 CLKGDV 这个寄存器 的范围是 0-FFh(255), 所以采用低于 115200 的 波特率时这个计算值会大于255,所以
不能使用小的波特率; 另外如果发现调试时乱码 CLKGDV的值可能还需要一些微调。
2. 寄存器RCR和XCR 的 XFIG和 RFIG 应该设为1,收发数据需要忽略桢同步,不然后出现乱码。
下面给出本人的一个配置:
/* SPCR Setup */
MCBSP_SPCR_RMK(
MCBSP_SPCR_FREE_NO,
MCBSP_SPCR_SOFT_YES,
MCBSP_SPCR_FRST_DEFAULT,
MCBSP_SPCR_GRST_DEFAULT,
MCBSP_SPCR_XINTM_XRDY,
MCBSP_SPCR_XSYNCERR_DEFAULT,
MCBSP_SPCR_XRST_DEFAULT,
MCBSP_SPCR_DLB_OFF,
MCBSP_SPCR_RJUST_RZF,
MCBSP_SPCR_CLKSTP_DISABLE,
MCBSP_SPCR_DXENA_OFF,
MCBSP_SPCR_RINTM_RRDY,
MCBSP_SPCR_RSYNCERR_DEFAULT,
MCBSP_SPCR_RRST_DEFAULT
),
/* RCR Setup */
MCBSP_RCR_RMK(
MCBSP_RCR_RPHASE_DUAL,
MCBSP_RCR_RFRLEN2_OF(1),
MCBSP_RCR_RWDLEN2_8BIT,
MCBSP_RCR_RCOMPAND_MSB,
MCBSP_RCR_RFIG_YES,
MCBSP_RCR_RDATDLY_1BIT,
MCBSP_RCR_RFRLEN1_OF(8),
MCBSP_RCR_RWDLEN1_16BIT,
MCBSP_RCR_RWDREVRS_DISABLE
),
/* XCR Setup */
MCBSP_XCR_RMK(
MCBSP_XCR_XPHASE_DUAL,
MCBSP_XCR_XFRLEN2_OF(1),
MCBSP_XCR_XWDLEN2_8BIT,
MCBSP_XCR_XCOMPAND_MSB,
MCBSP_XCR_XFIG_YES,
MCBSP_XCR_XDATDLY_0BIT,
MCBSP_XCR_XFRLEN1_OF(8),
MCBSP_XCR_XWDLEN1_16BIT,
MCBSP_XCR_XWDREVRS_DISABLE
),
/* SRGR Setup */
MCBSP_SRGR_RMK(
MCBSP_SRGR_GSYNC_FREE,
MCBSP_SRGR_CLKSP_RISING,
MCBSP_SRGR_CLKSM_INTERNAL,
MCBSP_SRGR_FSGM_DXR2XSR,
MCBSP_SRGR_FPER_DEFAULT,
MCBSP_SRGR_FWID_OF(5),
MCBSP_SRGR_CLKGDV_OF(129)
),
/* MCR Setup */
MCBSP_MCR_DEFAULT,
/* RCER Setup */
MCBSP_RCERE0_DEFAULT,
MCBSP_RCERE1_DEFAULT,
MCBSP_RCERE2_DEFAULT,
MCBSP_RCERE3_DEFAULT,
/* XCER Setup */
MCBSP_XCERE0_DEFAULT,
MCBSP_XCERE1_DEFAULT,
MCBSP_XCERE2_DEFAULT,
MCBSP_XCERE3_DEFAULT,
/* PCR Setup */
MCBSP_PCR_RMK(
MCBSP_PCR_XIOEN_SP,
MCBSP_PCR_RIOEN_SP,
MCBSP_PCR_FSXM_INTERNAL,
MCBSP_PCR_FSRM_EXTERNAL,
MCBSP_PCR_CLKXM_OUTPUT,
MCBSP_PCR_CLKRM_OUTPUT,
MCBSP_PCR_CLKSSTAT_0,
MCBSP_PCR_DXSTAT_0,
MCBSP_PCR_FSXP_ACTIVELOW,
MCBSP_PCR_FSRP_ACTIVELOW,
MCBSP_PCR_CLKXP_RISING,
MCBSP_PCR_CLKRP_FALLING
)
};
MCBSP_config(hMcbsp1, &mcbspCfg1);
3. 传输方式的选择,McBSP 通信可以CPU收发,也可以 通过EDMA 收发,如果CPU仅仅只做串口的事CPU收发没问题,
否则 选择EDMA 收发比较灵活依靠中断来处理数据,在TI 文档中有固定的EDMA通道来专门传串口数据,比如笔者
使用 串口 1 的情况:
hEdma14 = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // 打开通道 14, 发数据用
hEdma15 = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // 打开通道 15,收数据用
ConfigEDMA(); // 具体配置 EDMA , 具体可以参考spra633c.pdf
IRQ_enable(IRQ_EVT_EDMAINT); // EDMA 中断使能,c6x里面是 中断8
EDMA_intDisable(14);
EDMA_intDisable(15);
EDMA_intClear(14);
EDMA_intClear(15);
EDMA_intEnable(14); // 使能通道 14 传输完毕时产生 EDMA 中断
EDMA_intEnable(15); // 使能通道 15 传输完毕时产生 EDMA 中断
EDMA_enableChannel(hEdma14); // 使能通道 14
EDMA_enableChannel(hEdma15); // 使能通道 15
...........
// EDMA 中断 处理函数
interrupt void c_int08(void)
{
if (EDMA_intTest(14))
{
// 处理 14
}
if (EDMA_intTest(15))
{
// 处理 15
}
}
...........
...........
这里一定要搞清楚 中断发生的时机,是在传输完毕时,这是根据你在EDMA配置的一次传输的字节数量。
另外如果不定时的发数据,以下语句可以重新启动一次EDMA传输:
// 重新启动一次EDMA传输
EDMA_setChannel(hEdma14);
............