热度 13
2014-3-22 14:40
1590 次阅读|
0 个评论
几乎所有的单片机都会集成UART外设,但是调试MSP430的UART功能比想象的要有挑战性也更有乐趣。MSP430的UART外设提供了更丰富的硬件可定制性,允许用户使用更简洁的代码和更少的外围器件,实现非常实用的功能,比如address选择、break信号、baudrate自动检测等等。当然,UART外设有丰富的时钟选项,32.768KHZ的ACLK时钟源也可以被使用,CPU可以最大限度的处于未唤醒状态,这是为低功耗而考虑的设计。 (USI外设:Universal Serial Interface,提供这一功能的MSP430型号并不多,在调试它之前得先确认是否具备它,MSP430F2616不提供USI外设,所以直接从USCI开始。) USCI外设:Universal Serial Communication Interface,大部分单片机会将UART、SPI、I2C外设功能分开,它们通常会使用不一样的IO引脚,不共用寄存器和中断向量;MSP430将这些外设功能集成到USCI中,它支持不同的(UART、SPI、I2C)模式,不同模式之间虽然不共用IO引脚,但是却共用寄存器和中断向量。USCI之间以不同的字母后缀来命名,比如USCI_A和USCI_B;如果有两个USCI_A,则命名为USCI_A0和USCI_A1。 其中,USCI_Ax支持UART、SPI、IrDA模式。如果需要使用UART功能,就需要设置USCI_Ax对应的IO引脚、寄存器和中断服务程序。相应的,USCI包含的SPI功能也就无法再使用。 这里UART使用的时钟是SMCLK(MCLK不能作为UART的时钟,而只能从UCLK(?)、ACLK、SMCLK中选择),默认的SMCLK来自DCOCLK,也就是MSP430自带的Digitally Controlled Oscillator时钟,IO引脚使用的是P3.4/P3.5,从数据手册可以看到它们是UART外设的专用引脚。将波特率设置为9600,分频值在数据手册中有表可查。 由于UART的接受通常使用中断,所以这里还要使能全局中断和UART接收中断。 /**********************************************************************/ uint32_t uart_rx_count = 0; #pragma vector=USCIAB0RX_VECTOR __interrupt void USCI0RX_ISR(void) { dma_temp_A = UCA0RXBUF; uart_rx_count++; HC595_disdata_4bytes(uart_rx_count); } int main (void) { uint16_t i = 0; WDTCTL = WDTPW + WDTHOLD; // 等待DCOCLK稳定,并且将它调整为1MHz,而系统启动时的默认值是1.1MHz if (CALBC1_1MHZ == 0xFF || CALDCO_1MHZ == 0xFF) while(1); BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; // 开启全局中断 __bis_SR_register(GIE); led_init(); HC595_init(); // 首先关断UART // 选择时钟为SMCLK // UCA0BR0、UCA0BR、UCA0MCTL的值在9600波特率,可查询技术手册提供的表格 UCA0CTL1 |= UCSWRST; UCA0CTL1 |= UCSSEL_2; UCA0BR0 = 104; UCA0BR1 = 0; UCA0MCTL = (0 4) + (1 1); // 设置IO口的外设功能 // 启动UART // 使能UART的接收中断 P3SEL = 0x30; UCA0CTL1 = ~UCSWRST; IE2 |= UCA0RXIE; while (1) { for (i = 'A'; i = 'Z'; i++) { while (!(IFG2 UCA0TXIFG)); UCA0TXBUF = i; } while (!(IFG2 UCA0TXIFG)); UCA0TXBUF = '\r'; while (!(IFG2 UCA0TXIFG)); UCA0TXBUF = '\n'; } return 0; } /********************************************************************/ MSP430的技术手册提供了不同波特率对应的寄存器表格,观察这个表格就会发现,以1MHz的SMCLK作为时钟源时,115200波特率实际上会有一个不可忽视的误差值,在实际应用中可能要注意它带来的影响。 当使用串口调试软件发送数据时,中断服务程序就会将当前接收到的个数显示在74HC595驱动的4位数码管上面。串口和液晶由于显示事件比较长,并不适合放进中断服务程序,实际上,显示4位8段数码管也需要不短的时间,因此在中断函数中写标志位、在主函数中显示,还是更加合理的选择。