1. 硬件上,底板有2个串口,UART1和UART2(使用了MAX3232电平转换芯片),其中UART2也可以转RS485的。
2. 看下数据手册部分,不过一直不理解过采样的意思,16字节的FIFO
Three Configurable 16550-Type UART Modules:–with Modem Control Signals–16-Byte FIFO–16xor13x Oversampling Option
3. 本次的例程是中断机制,DSP6748的中断系统是什么样的?在DSP是通过中断向量表作为相应的中断服务程序的入口,中断优先级自高至低。在TMS320C6748中共有16个,前4个中断,编程一般用不到,TI公司总共留给用户12个可自定义的中断,如下图
中断优先级 | 中断名称 | 描述 |
0 | Reset | 复位中断 |
1 | NMI | 不可屏蔽中断 |
2 | Reserved | 预留(不可操作) |
3 | Reserved | 预留(不可操作) |
4 | INT4 | 用户自定义中断 |
5 | INT5 | 用户自定义中断 |
6 | INT6 | 用户自定义中断 |
7~13 | INT7~13 | 用户自定义中断 |
14 | INT14 | 用户自定义中断 |
15 | INT15 | 用户自定义中断 |
外部的中断事件有128个,如下图(省略了一部分)
需要把用到的中断事件分配到12个可用的中断。
但是外部有128个中断事件,而CPU只留了12个用户中断,完全不够分啊,所以当使用到的中断特别多的情况下,复用中断事件有非常重要的意义。这个时候有一个中断组合器,中断组合器就是把几个中断事件合并成一个,从下图可以看出,只能中断事件4-127合并到0-3里面。当然这是在中断事件特别多的情况下,假如你只有2-3个中断事件,可以不使用中断组合器。中断组合器在上图的Interrupt selector里面。
4. 看下代码部分,使能模块
void PSCInit(void){ // 对相应外设模块的使能也可以在 BootLoader 中完成 // 使能 UART2 模块 PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_UART2, PSC_POWERDOMAIN_ALWAYS_ON,PSC_MDCTL_NEXT_ENABLE);}
串口配置
void UARTInit(void){ // 配置 UART20 参数 // 波特率 115200 数据位 8 停止位 1 无校验位 UARTConfigSetExpClk(SOC_UART_2_REGS, UART_2_FREQ, BAUD_115200,UART_WORDL_8BITS, UART_OVER_SAMP_RATE_16); // 使能 UART2 UARTEnable(SOC_UART_2_REGS); // 使能接收 / 发送 FIFO UARTFIFOEnable(SOC_UART_2_REGS); // 设置 FIFO 级别 UARTFIFOLevelSet(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_1);}
串口中断配置
void UARTInterruptInit(void){ IntRegister(C674X_MASK_INT4, UARTIsr); IntEventMap(C674X_MASK_INT4, SYS_INT_UART2_INT); IntEnable(C674X_MASK_INT4); // 使能中断 unsigned int intFlags = 0; intFlags |= (UART_INT_LINE_STAT | \ UART_INT_TX_EMPTY | \ UART_INT_RXDATA_CTI); UARTIntEnable(SOC_UART_2_REGS, intFlags);}
中断的C674X_MASK_INT4是什么意思?这个中断4就是上面说的CPU留了12个用户中断的其中之一。
#define C674X_MASK_INT4 4#define C674X_MASK_INT5 5#define C674X_MASK_INT6 6#define C674X_MASK_INT7 7#define C674X_MASK_INT8 8#define C674X_MASK_INT9 9#define C674X_MASK_INT10 10#define C674X_MASK_INT11 11#define C674X_MASK_INT12 12#define C674X_MASK_INT13 13#define C674X_MASK_INT14 14#define C674X_MASK_INT15 15
中断服务函数ISR
void UARTIsr(){ static unsigned int length = sizeof(txArray); static unsigned int count = 0; unsigned char rxData = 0; unsigned int int_id = 0; // 确定中断源 int_id = UARTIntStatus(SOC_UART_2_REGS); // 清除 UART2 系统中断 IntEventClear(SYS_INT_UART2_INT); // 发送中断 if(UART_INTID_TX_EMPTY == int_id) { if(0 < length) { // 写一个字节到 THR UARTCharPutNonBlocking(SOC_UART_2_REGS, txArray[count]); length--; count++; } if(0 == length) { // 禁用发送中断 UARTIntDisable(SOC_UART_2_REGS, UART_INT_TX_EMPTY); } } // 接收中断 if(UART_INTID_RX_DATA == int_id) { rxData = UARTCharGetNonBlocking(SOC_UART_2_REGS); UARTCharPutNonBlocking(SOC_UART_2_REGS, rxData); } // 接收错误 if(UART_INTID_RX_LINE_STAT == int_id) { while(UARTRxErrorGet(SOC_UART_2_REGS)) { // 从 RBR 读一个字节 UARTCharGetNonBlocking(SOC_UART_2_REGS); } } return; }
代码主要是这4部分组成的。
5. 程序运行测试一下,编译的时候点下工程才能编译,连接目标开发板,下载UART2_INT.out文件,点击运行,打开串口终端,发现串口不通,开始查找原因
6. 实际测试发现,TMS320C6748有2个PSC的时钟域(power and sleep control电源和时钟控制),UART0是在PSC0,UART1和UART2是在PSC1,刚开始用错了PSC,修改之后搞定。