大部分单片机的外设时钟,比如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[0] = 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弹窗,没有自动退出,总之,强烈推荐。
文章评论(0条评论)
登录后参与讨论