如果我从 MSP430 Launchpad 发送 AT,为什么 HM-10 不发送 OK?
Why HM-10 doesn't send an OK if i send AT from an MSP430 Launchpad?
我正在尝试与 Texas Instruments MSP430 Launchpad 上的 HM-10 芯片建立 UART 通信,但我 运行 遇到了一个非常初级的问题。
我想要实现的是通过 UART 发送一个 "AT" 到 HM-10,并收到一个答复。顺便说一下,这是我找到的代码 here 并且我为了我的目的稍微修改了一下。
#include "msp430g2553.h"
const char string[] = { "AT" };
unsigned int i;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
//------------------- Configure the Clocks -------------------//
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
//---------------- Configuring the LED's ----------------------//
P1DIR |= BIT0 + BIT6; // P1.0 and P1.6 output
P1OUT &= ~BIT0 + BIT6; // P1.0 and P1.6 = 0
//--------- Setting the UART function for P1.1 & P1.2 --------//
P1SEL |= BIT1 + BIT2; // P1.1 UCA0RXD input
P1SEL2 |= BIT1 + BIT2; // P1.2 UCA0TXD output
//------------ Configuring the UART(USCI_A0) ----------------//
UCA0CTL1 |= UCSSEL_2 + UCSWRST; // USCI Clock = SMCLK,USCI_A0 disabled
UCA0BR0 = 104; // 104 From datasheet table-
UCA0BR1 = 0; // -selects baudrate =9600,clk = SMCLK
UCA0MCTL = UCBRS_1; // Modulation value = 1 from datasheet
//UCA0STAT |= UCLISTEN; // loop back mode enabled
UCA0CTL1 &= ~UCSWRST; // Clear UCSWRST to enable USCI_A0
//---------------- Enabling the interrupts ------------------//
IE2 |= UCA0TXIE; // Enable the Transmit interrupt
IE2 |= UCA0RXIE; // Enable the Receive interrupt
_BIS_SR(GIE); // Enable the global interrupt
i = 0;
UCA0TXBUF = string[i]; // Transmit a byte
_BIS_SR(LPM0_bits + GIE); // Going to LPM0
}
//-----------------------------------------------------------------------//
// Transmit and Receive interrupts //
//-----------------------------------------------------------------------//
#pragma vector = USCIAB0TX_VECTOR
__interrupt void TransmitInterrupt(void)
{
P1OUT ^= BIT0;//light up P1.0 Led on Tx
if (i == sizeof string - 1)
{
UC0IE &= ~UCA0TXIE;
}
UCA0TXBUF = string[i++];
}
#pragma vector = USCIAB0RX_VECTOR
__interrupt void ReceiveInterrupt(void)
{
// light up P1.6 LED on RX
if (UCA0RXBUF == 'O')
{
P1OUT ^= BIT6;
}
IFG2 &= ~UCA0RXIFG; // Clear RX flag
}
根据 datasheet 我应该会收到此命令的 OK 答复。
如果 RX 缓冲区中有一个 'O',我希望我的电路板上的 LED 会亮起,但这并没有发生。
使用 Code Composer,我还通过向 RX 中断添加断点来验证确实没有 RX 应答。
我相信这完全是一个软件问题,所以我把它放在这里。我正在使用正确的跳线旋转(http://xanthium.in/Serial-Communication-MSP430-UART-USCI_A)并且 RX 连接到 TX,反之亦然。
如果您能指出我是否在概念上做错了什么,或者我只是犯了一个错误,我将不胜感激。谢谢!
我在中断例程 TransmitInterrupt() 中看到一个问题:您应该使用 UCA0TXBUF = string[++i];
,因为使用 "i++" 会传输两次字母 "A"。关于sizeof(string)的测试也要修改一下
那么,我不会过于相信数据表。我认为,不管数据表怎么说,发送到调制解调器的每个命令都必须由 CR (\r) 终止,否则调制解调器如何从 "AT+RESET" 中辨别出 "AT"?我不太确定,但数据表似乎不是高质量的。无论如何,这是一个快速测试(将 \r 添加到字符串的末尾)。
最后,CTS 和 RTS 信号也可以发挥作用。一些调制解调器需要 RTS 断言,其他调制解调器不关心,术语有时令人困惑:当数据表说 RTS 时,它是指调制解调器 的 RTS 还是调制解调器的 RTS 主机?我希望这对你有所帮助,你应该做一些科学的尝试。
我想对于将来使用 HM-10 设备的每个人来说,我想回答这个问题,因为我认为它有自己的迷你文学,起初令人沮丧,但后来我有点喜欢它给我带来的挑战。
一些问题与硬件相关,因此此 post 可能需要移至嵌入式工程部分。 (重要的后果 - 在用示波器检查之前你不能 100% 确定)
了解您的硬件 - HM-10 有很多版本,它让我们需要一个 额外的分压器 因为它有 3.3V 逻辑高电平而不是 5V。 This website is a fantastic place to start. Though, ours turned out to be an MLT-BT05 which is a clone of a clone。它的固件上没有 iBeacon 功能,因此如果您不想重启电源,那么您应该避免使用此功能。
关于编码位最重要的是检查\n、\r和\n\r,因为linuxfan在上面简要提到了它的重要性,因为一些设备需要它。最好的起点是 AT,如果有效,则使用 AT+HELP 并找到版本,通常是 AT+VERSION 命令,这样你就可以100% 确定您拥有的芯片。
目前它是在 Arduino 上制作原型,但我会在 MSP430 上完成后立即包含工作代码。
Arduino代码:
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(9, 10); // RX, TX
char commandbuffer[50];
int j = 0;
void setup()
{
memset(commandbuffer, 0, sizeof(commandbuffer));
analogWrite(12, 255);
analogWrite(11, 0);
// Start the hardware serial port
Serial.begin(19200);
bluetooth.begin(9600);
// un REM this to set up a Master and connect to a Slave
Serial.println("BLE CC41A Bluetooth");
Serial.println("----------------------------------");
Serial.println("");
Serial.println("Trying to connect to Slave Bluetooth");
delay(1000);
bluetooth.println("AT"); // just a check
delay(2000);
bluetooth.println("AT+NAMEHIST");
delay(2000);
bluetooth.println("AT+ROLE0");
delay(2000);
bluetooth.println("AT+INQ"); // look for nearby Slave
delay(5000);
bluetooth.println("AT+CONN1"); // connect to it */
}
void loop()
{
bluetooth.listen();
// while there is data coming in, read it
// and send to the hardware serial port:
while (bluetooth.available() > 0) {
char inByte = bluetooth.read();
Serial.write(inByte);
}
// Read user input if available.
if (Serial.available()) {
delay(10); // The DELAY!
char temp = Serial.read();
if (temp == '\n')
{
bluetooth.println(commandbuffer);
Serial.println(commandbuffer);
memset(commandbuffer, 0, sizeof(commandbuffer));
j = 0; // Reset
}
else
{
commandbuffer[j++] = temp;
}
delay(500);
}
我正在尝试与 Texas Instruments MSP430 Launchpad 上的 HM-10 芯片建立 UART 通信,但我 运行 遇到了一个非常初级的问题。
我想要实现的是通过 UART 发送一个 "AT" 到 HM-10,并收到一个答复。顺便说一下,这是我找到的代码 here 并且我为了我的目的稍微修改了一下。
#include "msp430g2553.h"
const char string[] = { "AT" };
unsigned int i;
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop the Watch dog
//------------------- Configure the Clocks -------------------//
if (CALBC1_1MHZ==0xFF) // If calibration constant erased
{
while(1); // do not load, trap CPU!!
}
DCOCTL = 0; // Select lowest DCOx and MODx settings
BCSCTL1 = CALBC1_1MHZ; // Set range
DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation
//---------------- Configuring the LED's ----------------------//
P1DIR |= BIT0 + BIT6; // P1.0 and P1.6 output
P1OUT &= ~BIT0 + BIT6; // P1.0 and P1.6 = 0
//--------- Setting the UART function for P1.1 & P1.2 --------//
P1SEL |= BIT1 + BIT2; // P1.1 UCA0RXD input
P1SEL2 |= BIT1 + BIT2; // P1.2 UCA0TXD output
//------------ Configuring the UART(USCI_A0) ----------------//
UCA0CTL1 |= UCSSEL_2 + UCSWRST; // USCI Clock = SMCLK,USCI_A0 disabled
UCA0BR0 = 104; // 104 From datasheet table-
UCA0BR1 = 0; // -selects baudrate =9600,clk = SMCLK
UCA0MCTL = UCBRS_1; // Modulation value = 1 from datasheet
//UCA0STAT |= UCLISTEN; // loop back mode enabled
UCA0CTL1 &= ~UCSWRST; // Clear UCSWRST to enable USCI_A0
//---------------- Enabling the interrupts ------------------//
IE2 |= UCA0TXIE; // Enable the Transmit interrupt
IE2 |= UCA0RXIE; // Enable the Receive interrupt
_BIS_SR(GIE); // Enable the global interrupt
i = 0;
UCA0TXBUF = string[i]; // Transmit a byte
_BIS_SR(LPM0_bits + GIE); // Going to LPM0
}
//-----------------------------------------------------------------------//
// Transmit and Receive interrupts //
//-----------------------------------------------------------------------//
#pragma vector = USCIAB0TX_VECTOR
__interrupt void TransmitInterrupt(void)
{
P1OUT ^= BIT0;//light up P1.0 Led on Tx
if (i == sizeof string - 1)
{
UC0IE &= ~UCA0TXIE;
}
UCA0TXBUF = string[i++];
}
#pragma vector = USCIAB0RX_VECTOR
__interrupt void ReceiveInterrupt(void)
{
// light up P1.6 LED on RX
if (UCA0RXBUF == 'O')
{
P1OUT ^= BIT6;
}
IFG2 &= ~UCA0RXIFG; // Clear RX flag
}
根据 datasheet 我应该会收到此命令的 OK 答复。
如果 RX 缓冲区中有一个 'O',我希望我的电路板上的 LED 会亮起,但这并没有发生。
使用 Code Composer,我还通过向 RX 中断添加断点来验证确实没有 RX 应答。
我相信这完全是一个软件问题,所以我把它放在这里。我正在使用正确的跳线旋转(http://xanthium.in/Serial-Communication-MSP430-UART-USCI_A)并且 RX 连接到 TX,反之亦然。
如果您能指出我是否在概念上做错了什么,或者我只是犯了一个错误,我将不胜感激。谢谢!
我在中断例程 TransmitInterrupt() 中看到一个问题:您应该使用 UCA0TXBUF = string[++i];
,因为使用 "i++" 会传输两次字母 "A"。关于sizeof(string)的测试也要修改一下
那么,我不会过于相信数据表。我认为,不管数据表怎么说,发送到调制解调器的每个命令都必须由 CR (\r) 终止,否则调制解调器如何从 "AT+RESET" 中辨别出 "AT"?我不太确定,但数据表似乎不是高质量的。无论如何,这是一个快速测试(将 \r 添加到字符串的末尾)。
最后,CTS 和 RTS 信号也可以发挥作用。一些调制解调器需要 RTS 断言,其他调制解调器不关心,术语有时令人困惑:当数据表说 RTS 时,它是指调制解调器 的 RTS 还是调制解调器的 RTS 主机?我希望这对你有所帮助,你应该做一些科学的尝试。
我想对于将来使用 HM-10 设备的每个人来说,我想回答这个问题,因为我认为它有自己的迷你文学,起初令人沮丧,但后来我有点喜欢它给我带来的挑战。
一些问题与硬件相关,因此此 post 可能需要移至嵌入式工程部分。 (重要的后果 - 在用示波器检查之前你不能 100% 确定)
了解您的硬件 - HM-10 有很多版本,它让我们需要一个 额外的分压器 因为它有 3.3V 逻辑高电平而不是 5V。 This website is a fantastic place to start. Though, ours turned out to be an MLT-BT05 which is a clone of a clone。它的固件上没有 iBeacon 功能,因此如果您不想重启电源,那么您应该避免使用此功能。
关于编码位最重要的是检查\n、\r和\n\r,因为linuxfan在上面简要提到了它的重要性,因为一些设备需要它。最好的起点是 AT,如果有效,则使用 AT+HELP 并找到版本,通常是 AT+VERSION 命令,这样你就可以100% 确定您拥有的芯片。
目前它是在 Arduino 上制作原型,但我会在 MSP430 上完成后立即包含工作代码。
Arduino代码:
#include <SoftwareSerial.h>
SoftwareSerial bluetooth(9, 10); // RX, TX
char commandbuffer[50];
int j = 0;
void setup()
{
memset(commandbuffer, 0, sizeof(commandbuffer));
analogWrite(12, 255);
analogWrite(11, 0);
// Start the hardware serial port
Serial.begin(19200);
bluetooth.begin(9600);
// un REM this to set up a Master and connect to a Slave
Serial.println("BLE CC41A Bluetooth");
Serial.println("----------------------------------");
Serial.println("");
Serial.println("Trying to connect to Slave Bluetooth");
delay(1000);
bluetooth.println("AT"); // just a check
delay(2000);
bluetooth.println("AT+NAMEHIST");
delay(2000);
bluetooth.println("AT+ROLE0");
delay(2000);
bluetooth.println("AT+INQ"); // look for nearby Slave
delay(5000);
bluetooth.println("AT+CONN1"); // connect to it */
}
void loop()
{
bluetooth.listen();
// while there is data coming in, read it
// and send to the hardware serial port:
while (bluetooth.available() > 0) {
char inByte = bluetooth.read();
Serial.write(inByte);
}
// Read user input if available.
if (Serial.available()) {
delay(10); // The DELAY!
char temp = Serial.read();
if (temp == '\n')
{
bluetooth.println(commandbuffer);
Serial.println(commandbuffer);
memset(commandbuffer, 0, sizeof(commandbuffer));
j = 0; // Reset
}
else
{
commandbuffer[j++] = temp;
}
delay(500);
}