历史上的今天
返回首页

历史上的今天

今天是:2025年03月10日(星期一)

正在发生

2020年03月10日 | [MSP430] 3.UART

2020-03-10 来源:eefocus

这一节我们将会看到如何在 MSP430 Launchpad 上使 用 UART 进行通信。我们的程序将会实现通过 UART 从 PC 读入一个字节的数据,然后发送相应的反馈字节给 PC。通信 模式为 115200 波特率,全双工,8 位数据,无奇偶校验,1 位停止位。


MSP430 G2553(Launchpad 使用的芯片)是 MSP430 家 族中比较给力的芯片,它集成了硬件 UART 模块。

UART 通信在处理/调试传感器的时候尤为有用,举一个简单的 例子,我们可以用温度传感器采集数据,经过 AD 转换之后通过 UART 发送给 PC,传送的方式可以是有线,也可以使用无线例如蓝牙。

让我们直接进入正题吧。


首先,你应该已经熟悉了这样的开头:


#include "msp430g2553.h"

#define TXLED BIT0 

#define RXLED BIT6 

#define TXD BIT2 

#define RXD BIT1

const char string[] = { "Hello Worldn" }; 

unsigned int i; //Counter


像前两节中所做的那样,程序开头包含 MSP430G2553 的头文 件,然后宏定义一些常数使得程序更具可读性。


接着我们定义了一个 char 类型数组(即一个 C String),存了 我们将要反馈给 PC 的信息(经典的 Hello World)。最后定义一个 计数变量,辅助反馈字符串的发送。


int main(void) {

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  DCOCTL = 0; // Select lowest DCOx and MODx settings

  BCSCTL1 = CALBC1_1MHZ; // Set DCO

  DCOCTL = CALDCO_1MHZ;


这依然是大家熟悉的 main 函数的开始方法,首先关闭看门狗定 时器,之后的三行将单片机的内部时钟设置为 1MHz。接下来 UART 和板上所有其他外设都将使用 SMCLK 时钟(sub-main clock)。


  P2DIR |= 0xFF; // All P2.x outputs

  P2OUT &= 0x00; // All P2.x reset

  P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD

  P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD

  P1DIR |= RXLED + TXLED;

  P1OUT &= 0x00;


这里是配置输入输出引脚:

前两行我们把 PORT2 的所有引脚关闭。对于用不到的引脚,关 闭引脚是一个比较好的习惯,这样能有效地减少噪声和电流的消耗。


第3行和第4行将引脚P1.1和P1.2设置为UART模式。事 实上,P1SEL 和 P1SEL2 两个寄存器是一个多路选择器,它们将 P1 的引脚连接至不同的板载的外设上。但是注意,TXD 和 RXD 是固定引脚的,我们可以通过查 G2553 的数据手册找到对应的引脚。

最后两行是初始化板载 LED。


  UCA0CTL1 |= UCSSEL_2; // SMCLK

  UCA0BR0 = 0x08; // 1MHz 115200

  UCA0BR1 = 0x00; // 1MHz 115200

  UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5

  UCA0CTL1 &= ~UCSWRST;  // **Initialize USCI state machine**

  UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt 

  _EINT();

  while(1)

  {}

}

这是 UART 的配置。第 1 行,如同前面所说的,我们选择 SMCLK 作为 UART 模块的时钟源,用来产生需要的波特率(当然, 你也可以选择其他的时钟源)。


UCA0BR0 和 UCA0BR1 用来选择波特率:你可以将这两个 寄存器存储的整数看做对时钟 SMCLK(1MHz)的分频。在我们 的配置下,产生的频率是 1MHz/8=125000Hz,而实际上我们需 要 115200 的波特率,所以在长时间的工作中会累积一定的误差。 如果配置为 9 的话波特率又会低于 115200。这时候就需要用到 UCA0MCTL 寄存器。


这个寄存器是起调节作用的,它会选择 8 和 9 之间的分频因子, 在通信中可以控制累积误差。如果分频因子为 8,有 125000- 115200=9600(+8.5%)的误差,如果分频因子为 9,有 115200-111111=4089(-3.6%)的误差。

调节器差不多会这样工作:


位数 分频因子 误差(%) 累积误差(%)

1 8 +8.5 +8.5

2 9 -3.6 +4.9

3 9 -3.6 +1.3

4 9 -3.6 -2.3

5 8 +8.5 +6.2

…… …… …… ……

在 MSP430 的编程手册(User Guide)上可以找到一张表, 列出了 SMCLK 典型频率和常用波特率下,UART 收发数据时期望 的最小和最大的误差率。根据表格我们选择 5 作为调节值。


然后我们使能所有中断,进入循环。

#pragma vector=USCIAB0RX_VECTOR

__interrupt void USCI0RX_ISR(void)

{

  P1OUT |= RXLED;

  if (UCA0RXBUF == 'a') // 'a' received?

  {

    i = 0;

    UC0IE |= UCA0TXIE;  // Enable USCI_A0 TX interrupt

    UCA0TXBUF = string[i++];

  }

  P1OUT &= ~RXLED;

}

这是当 UART 接收到数据时的中断处理程序。如果你看过了 指导书的第二部分,你应该对中断的概率比较熟悉了。


在中断处理程序中,我们先点亮一个 LED,表示单片机已经 接收到一个字节。然后我们读 UCA0RXBUF 寄存器,这个寄存器 存储了收到的数据。


如果收到的数据为’a’,那么就重置计数变量 i,打开发送中 断向 PC 发送反馈字符串。

当我们把字符串的第一个字符放入 UCA0TXBUF 时,这个寄 存器就会做好准备将数据发送出去。


在这个中断处理程序的最后,记得关闭 LED,表示接收中断 处理完毕。


#pragma vector=USCIAB0TX_VECTOR 

__interrupt void USCI0TX_ISR(void)

{

  P1OUT |= TXLED;

  UCA0TXBUF = string[i++]; // TX next character

  if (i == sizeof(string) - 1) // TX over?

  {

    UC0IE &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt

  }

  P1OUT &= ~TXLED;

}

这是UART的发送中断处理程序。和刚才一样,我们点亮一个 LED表示进入发送中断。


我们将要发送的下一个字符放入缓存区中。如果字符串没有结束, 关闭LED,中断处理程序结束。待当前字节发送结束后,发送中断会被再一次触发(因为buffer中还有待发送的数据)。如果反馈字 符串已经全部载入buffer中,我们就可以关闭发送中断,回到主程序中。

烧代码看效果吧!


提示:通信时PC与单片机的互动可以在PC端下载一个串口助手, 比较经典是sscom。串口助手是调试单片机程序的利器!


以下是这一节的完整代码:


#include "msp430g2553.h"

#define TXLED BIT0 

#define RXLED BIT6 

#define TXD BIT2 

#define RXD BIT1

const char string[] = { "Hello Worldn" }; 

unsigned int i; //Counter

int main(void)

{

  WDTCTL = WDTPW + WDTHOLD; // Stop WDT

  DCOCTL = 0; // Select lowest DCOx and MODx settings

  BCSCTL1 = CALBC1_1MHZ; // Set DCO

  DCOCTL = CALDCO_1MHZ;

  P2DIR |= 0xFF; // All P2.x outputs

  P2OUT &= 0x00; // All P2.x reset

  P1SEL |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD

  P1SEL2 |= RXD + TXD ; // P1.1 = RXD, P1.2=TXD

  P1DIR |= RXLED + TXLED;

  P1OUT &= 0x00;

  UCA0CTL1 |= UCSSEL_2; // SMCLK

  UCA0BR0 = 0x08; // 1MHz 115200

  UCA0BR1 = 0x00; // 1MHz 115200

  UCA0MCTL = UCBRS2 + UCBRS0; // Modulation UCBRSx = 5

  UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**

  UC0IE |= UCA0RXIE; // Enable USCI_A0 RX interrupt 

  _EINT();

  while (1)

  {}

}

 

#pragma vector=USCIAB0RX_VECTOR

__interrupt void USCI0RX_ISR(void)

{

  P1OUT |= RXLED;

  if (UCA0RXBUF == 'a') // 'a' received?

  {

    i = 0;

    UC0IE |= UCA0TXIE;  // Enable USCI_A0 TX interrupt

    UCA0TXBUF = string[i++];

  }

  P1OUT &= ~RXLED;

}

 

#pragma vector=USCIAB0TX_VECTOR 

__interrupt void USCI0TX_ISR(void)

{

  P1OUT |= TXLED;

  UCA0TXBUF = string[i++]; // TX next character

  if (i == sizeof(string) - 1) // TX over?

  {

    UC0IE &= ~UCA0TXIE; // Disable USCI_A0 TX interrupt

  }

  P1OUT &= ~TXLED;

}

推荐阅读

史海拾趣

昆泰芯微电子(CONNTEK)公司的发展小趣事

随着物联网技术的快速发展,昆泰芯微电子紧跟时代步伐,深度布局物联网应用领域。公司专注于面向物联网应用的传感器芯片研发、生产和销售,致力于成为传感器信号链及物联网芯片的行业领导者。在消费电子、智能制造、智能交通、智能家居以及新能源汽车等多个领域,昆泰芯微电子的产品得到了广泛应用,为这些领域的发展提供了强有力的技术支持。

Endicott Research Group Inc (ERG)公司的发展小趣事

进入21世纪,随着LED技术的快速发展,ERG看到了固态照明市场的巨大潜力。2008年,公司决定成立一个新的部门——ERG Lighting,专注于为固态照明市场设计、制造和分销LED驱动器和其他照明配件。这一举措极大地拓展了公司的业务范围,并使其在市场上占据了有利地位。ERG Lighting的成立,不仅为公司带来了新的增长点,还进一步巩固了其在电源转换产品领域的领先地位。

Antenna Factor公司的发展小趣事

随着公司实力的不断增强,Antenna Factor公司开始将目光投向国际市场。他们积极参加国际电子展会和技术交流活动,与全球各地的客户和合作伙伴建立了广泛的联系。同时,公司还加大了对海外市场的研发投入和市场推广力度,逐步实现了产品的全球化销售。这一战略不仅为公司带来了更广阔的发展空间,也提升了其在全球电子行业中的竞争力。

通过以上五个故事,我们可以看到Antenna Factor公司在电子行业中的发展历程和取得的成就。他们以技术创新为驱动,不断突破自我,积极拓展市场,加强质量管理和品牌建设,逐步实现了公司的快速发展和壮大。未来,随着无线通信技术的不断进步和应用领域的不断拓展,相信Antenna Factor公司将继续保持领先地位,为电子行业的发展做出更大的贡献。

Globaltech Semiconductor Co Ltd公司的发展小趣事

随着公司业务的不断发展壮大,Globaltech开始着手进行全球化布局。公司在全球多个地区设立了研发中心和销售中心,以便更好地服务全球客户。同时,公司还注重可持续发展和社会责任,积极参与公益事业和环保活动。这些举措不仅提升了公司的社会形象和品牌价值,也为公司的长期发展奠定了坚实的基础。

以上五个故事展示了Globaltech Semiconductor Co., Ltd.在电子行业中的发展历程和关键里程碑。通过技术创新、市场拓展、研发实力提升、战略调整和全球化布局等措施,公司不断壮大自身实力,并在全球半导体行业中占据了一席之地。

绿宝石(BERYL)公司的发展小趣事

随着国内市场的饱和,绿宝石公司开始积极拓展国际市场。公司加强了与国际知名企业的合作,共同开发新产品、新技术。同时,绿宝石公司还在海外设立了研发中心和生产基地,以便更好地服务全球客户。通过一系列的市场拓展和国际化战略,绿宝石公司的国际影响力不断提升。

川晶科技公司的发展小趣事

随着环保意识的不断提高,绿色制造成为电子行业的重要发展趋势。川晶科技积极响应国家绿色发展的号召,通过引进先进的环保设备和技术,实现了生产过程的绿色化、低碳化。公司不断优化生产工艺,减少能源消耗和废弃物排放,推动产品向绿色、环保方向发展。川晶科技的绿色制造实践得到了业界的广泛赞誉,成为行业内的绿色标杆。

问答坊 | AI 解惑

IT项目管理成功秘笈

你听过能预言祸吉的咒语吗?虽然这是回到在古希腊时代才能听得到,它似乎在当今的整个美国,包括IT领域内的众多企业在内仍然存在并且十分盛行。   卡珊德拉,这位古希腊美女,被深爱她的阿波罗赋予了预知未来的禀赋。但当卡珊德拉拒绝他的时 ...…

查看全部问答>

中国做模拟IC还有前途吗?

工作难找啊 研究生毕业才刚入门,都没人要!一般都去做数字了。…

查看全部问答>

使用Quartus做VHDL时,遇见一个问题,求助!

运行程序的时候提示不支持我选择的芯片,怎么办? 错误原文:Current licence file does not support the EP2C35F672C6 device 谢谢各位大哥了!…

查看全部问答>

请教:EVC下怎样将CEDIT中输入的内容转换为float类型数据?

请教:EVC下怎样将CEDIT中输入的内容转换为float类型数据,谢谢…

查看全部问答>

为什么基于cepc和geode定制的系统,一个可以跳转,一个停在jumping..上

Debug Serial Init SysInit: GDTBase=80ad70e8 IDTBase=80b28ec0 KData=80b49800 Windows CE Kernel for i486 Built on Jun 24 2004 at 18:23:42 g_pPageDir = 80b4a000               Init ...…

查看全部问答>

关于c51单片机串口通信问题

我用c51单片机进行串口通信,发送数据时如果用轮询的方式就成功,如果用发送中断的方式另一个单片机接收到得数据老是错误,望高手解答。。。 串口初始化 TMOD=0x20;//工作方式2 自动重装 TH0=0xF4; //波特率2400bps TL0=0xF4; TR1=1;//启动定 ...…

查看全部问答>

求助—关于wince键盘开发问题。急!!!

各位前辈:我现在有个问题想请教,我在开发键盘的时候(sumsang2413),用的是eint,在intr.c里需要一个变量保存g_pPortRegs->EINTMASK。但是在S3c2413kbd.cpp定义,在intr.c中加extern但不能访问此变量,或者在S3c2413kbd.cpp中定义,intr.c中也不 ...…

查看全部问答>

江湖救急!!!!!!

急!俺公司的示波器返厂维修了,现在着急调试一开发板的串行总线,那位仁兄能开开后门让我混进你们实验室借示波器用用?(限上海的啊)…

查看全部问答>

请教关于430看门狗的问题

程序中起用了看门狗。有时候会出现程序死机,看门狗却不复位了。按道理说看门狗应该 复位的,程序应该重起。 是什么原因造成的?多谢了!…

查看全部问答>

msp430f2132 2线下载老是说找不到设备

开发msp430f2132 用LSD-FET430UIF 2线下载老是说找不到设备,接法与利尔达仿真机提供的接法相近。就是8脚未接。是这原因吗? 谢谢帮助…

查看全部问答>