tag 标签: usci

相关博文
  • 热度 16
    2014-3-22 14:57
    2060 次阅读|
    0 个评论
    大部分单片机的外设时钟,比如UART、SPI、TIMER等等,都是由主时钟SYSCLK产生,它们可以单独关断以节省功耗,但是只要有任何一个外设还在工作,MHz级别的主时钟就不能够停止,这也意味着,单片机要么休眠,要么运转。 MSP430系列超低功耗单片机,外设的时钟可以来自MCLK、SMCLK、ACLK,而ACLK(Auxiliary Clock备用时钟)可以来自外部的32768-Hz watch crystal(或高速crystal),也可以来自内部的12KHz的VLO,这意味着MSP430可以相当于其他类型单片机休眠状态的功耗,维持外设的正常运行。比如这里的UART。 使用UART(RS232协议)来唤醒设备,是非常常见的应用方式,这种方式比外部中断唤醒,更适用于远程场合,而MSP430自带的address检测,使得UART(RS485协议)的唤醒也变得方便;否则,RS485就得响应总线上的每一个字节,即使地址字节后面跟随的一大串和自己完全没有关系。 USCI_Ax工作在UART模式下,时钟源可以是UC0CLK(?)、ACLK、SMCLK,在开发笔记(五)中使用的是SMCLK,即校正为1MHz的DCOCLK,以它为时钟源产生的9600波特率的误差率非常小。实际上,进入低功耗模式时SMCLK会被关断,当USCI需要时它会再次被自动唤醒,完成指令后又进入关断状态。因此,它也具备非常好的低功耗特性,适合需要以9600及以上的波特率传输UART数据的场合。同时需要注意的是,当SMCLK被唤醒时,其他使用SMCLK的外设同时也会进入工作状态,需要进行相应的处理。 如果传输的速率要求并不高,并且希望功耗能够进一步的降低,ACLK时钟源是非常好的选择。这里将波特率设置为2400,因为9600的误差率已经非常大了。 /***************************************************/ 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;     __bis_SR_register(GIE);     HC595_init();     // 首先关断UART     // 选择时钟为ACLK     // UCA0BR0、UCA0BR、UCA0MCTL的值在9600波特率,可查询技术手册提供的表格     UCA0CTL1 |= UCSWRST;     UCA0CTL1 |= UCSSEL_1;     UCA0BR0 = 13;           UCA0BR1 = 0;     UCA0MCTL = (0 4) + (6 1) + 0;     // 设置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; } /***************************************************/ 当往串口中发送数据时,就会发现HC595驱动的8段数码管显示了当前接收数据的个数。 ps:吐槽一句,Linux下的串口调试软件minicom真的很好用,它以36字节/100毫秒的速率接收了整整8个小时的数据,没有崩溃,没有error弹窗,没有自动退出,总之,强烈推荐。
  • 热度 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段数码管也需要不短的时间,因此在中断函数中写标志位、在主函数中显示,还是更加合理的选择。