This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] MSP430F5529:无法在 launchpad 上写入命令

Guru**** 2582875 points
Other Parts Discussed in Thread: MSP430F5529

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/609798/msp430f5529-not-able-to-write-the-commands-on-launchpad

器件型号:MSP430F5529

团队、

您能帮助回答 我的客户的以下问题吗:

我将 MSP430F5529 Launchpad 配置为 CDC 器件 、并尝试 通过 Ubuntu 终端进行通信。

我已在 微控制器上加载 TI 堆栈、并已通过 Ubuntu 终端使用 PuTTY 成功进行通信。

接下来,我想使用 libusb 与微型设备通信 ,而不是使用 PuTTY。

 

我能够使用 libusb 打开串行端口、但无法写入命令。

谢谢

Viktorija

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Viktorija、

    您指的是什么命令? 您是否在特定 CDC 示例中引用了命令? 如果是、哪一个?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我是这个问题的发起者,命令 可能不 是一个合适的字。我想通过 USB 将一个随机字符串"LED ON"从主机 PC 发送到 MSP430。 下面 是一些背景信息:MSP430正在运行 TI 的 CDC 堆栈和一个示例代码,通过 输入文本字符串'LED ON'来打开 LED (GPIO 1.0)。 我正在使用 PuTTY 打开端口、启动通信并通过字符串(命令)切换 GPIO 。

    现在、我想使用 libusb  而不是 PuTTY。使用 libusb、我想发送一个文本字符串来打开/切换 GPIO 1.0。下面是我正在尝试的代码。

    #include 
    #include 
    #include 
    #include 
    #include 
    
    #define vender_ID 0x2047 //表示德州仪器
    #define PRODUCT_ID 0x0013 //德州仪器
    
    #define ACM_CTRL_DTR 0x01
    #define ACM_CTRL_RTS 0x02
    
    //*使用全局变量保留器件句柄
    */
    静态结构 libusb_device_handle *devh = NULL;
    
    //为 TI 器件硬编码端点地址
    */
    静态 int EP_in_addr = 0x81; //EP 1 in
    static int ep_out_addr = 0x02;//EP 2 out
    
    void write_char (unsigned char c)
    {
    /*要向器件发送 char、只需向启动 BULK_TRANSFD 即可
    *地址为 EP_OUT_addr 的端点。
    *
    int actual_length;
    if (libusb_bulk_transfer (devh、ep_out_addr、&c、1、
    &actual_length、0)< 0){
    fprintf (stderr、"发送字符时出错\n");
    }
    }
    
    int read_chars (unsigned char * data、int size)
    {
    /*要接收设备中的字符,请启动 BULK_TRANSFRA传输 至
    *地址为 ep_in_addr 的端点。
    *
    int actual_length;
    int RC = libusb_bulk_transfer (devh、ep_in_addr、data、size、&actual_length、
    1000);
    if (RC = libusb_error_timeout){
    printf ("超时(%d)\n"、actual_length);
    返回-1;
    } 如果(RC < 0){
    fprintf (stderr、"等待 char 时出错\n");
    返回-1;
    }
    
    返回 actual_length;
    }
    
    
    int main (int argc、char ** argv)
    {
    内部 RC;
    
    /*初始化 libusb
    *
    RC = libusb_init (NULL);
    如果(RC < 0){
    fprintf (stderr、"初始化 libusb 时出错:%s\n"、libusb_error_name (RC));
    退出(1);
    }
    
    /*将调试输出设置为最大电平。
    *
    libusb_set_debug (NULL、3);
    
    /*查找特定设备并将其打开。
    *
    devh = libusb_open_device_with _vid_pid (NULL、vender_ID、product_ID);
    如果(!devh){
    fprintf (stderr、"查找 USB 设备时出错\n");
    转至输出;
    }
    
    /*当我们使用
    -ACM 设备时,很可能会发生这种情况
    * Linux 已将 CDC-ACM 驱动程序连接到此设备。
    *我们需要从所有 USB 接口上分离驱动程序。 CDC - ACM
    *类定义了两个接口:控制接口和
    *数据接口。
    *
    for (int if_num = 0;if_num < 2;if_num++){
    if (libusb_kernel_driver_active (devh、if_num)){
    libusb_detach_kernel_driver (devh、if_num);
    }
    RC = libusb_clary_interface (devh、if_num);
    
    如果(RC < 0){
    fprintf (stderr、"声明接口时出错:%s\n"、
    libusb_error_name (RC));
    转至输出;
    }
    }
    
    /*开始配置设备:
    *-设置线路状态
    *
    RC = libusb_control_transfer (devh、0x21、0x22、ACM_CTRL_DTR | ACM_CTRL_RTS、
    0、NULL、0、0);
    如果(RC < 0){
    fprintf (stderr、"控制传输过程中出错:%s\n "、
    libusb_error_name (RC));
    }
    
    /*-设置行编码:此处为9600 8N1
    * 9600 = 0x2580 μ~> 0x80、在小端字节序中为0x25
    *
    unsigned char 编码[]={0x80、0x25、0x00、0x00、0x00、 0x00、0x08 };
    RC = libusb_control_transfer (devh、0x21、0x20、0、0、 编码、
    sizeof (编码)、0);
    如果(RC < 0){
    fprintf (stderr、"控制传输过程中出错:%s\n "、
    libusb_error_name (RC));
    }
    
    /*我们现在可以开始向设备发送或接收数据
    *
    unsigned char buf[65];
    int len;
    
    
    write_char ('LED 打开');
    len = read_chars (buf、64);
    buf[len]=0;
    fprintf (stdout、"已接收:\"%s\"\n"、buf);
    睡眠(1);
    
    libusb_release_interface (devh、0);
    
    输出:
    如果(devh)
    libusb_close (devh);
    libusb_exit (空);
    返回 RC;
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jagbir、您好!

    将来在论坛上发布代码时、请使用"使用 RTF 格式"按钮进行发布。 在中粘贴代码时、单击 按钮、以便正确格式化代码以方便阅读。 我已经编辑过您的帖子以执行此操作。

    从上面的文本来看、我假设您正在使用 MSP430器件上的第二个 CDC 示例(LED 开/关/闪存)。 此示例是否对您无效?

    就 libusb 而言、这是一个 Linux 库、我对它不了解、因此无法为您提供帮助。 如果您对 MSP430F5529的 USB 库有任何疑问、我可以为您提供帮助、但您似乎可以通过 Putty 接口使其正常工作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当我使用 PuTTY 时、程序正在工作、但它不能与 libusb 一起工作。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jagbir、您好!

    再说一次、我无法帮助您解决其中的 libusb 部分。 MSP430 USB 设备正确连接后、它不关心连接了什么、只要通过 USB 线路发送的数据与应用所需的类型匹配、它就应该像您通过 PuTTY 连接时看到的那样做出适当响应。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好! 
    以下代码是从 TI CDC LED On Off 示例中修改的。此代码在 PuTTY 中的 Windows 中工作。当我在 Linux 中使用 PuTTY 运行此代码时,我单击第一个键盘键的那一刻。 我不断收到垃圾数据
    在 PuTTY 屏幕上。有时,当我插入 MS430并启动 PuTTy 时,屏幕上会填满垃圾值。
    我正在使用'USBCDC_REProjectData (CDC0_INTFNUM)'清除代码中的缓冲区、但它没有帮助。




    #include "driverlib.h" #include //由 J.Singh 添加 #include "USB_config/descriptors.h" #include "USB_API/USB_Common/device.h" #include "USB_API/USB_Common/usb.h" //特定于 USB 的函 数#include "USB_API/USB_CDC_API/Usbcdc.h" #include "USB_app/usbConstructs.h" #include "hal.h"//注:修改 hal.h 以选择特定的评估板并自定义您自己的板。 uint8_t retInString (char* string);//函数声明 void initTimer(void); void setTimer_a_Parameters (void); //由事件 volatile uint8_t bCDCDataReceived Received = false 设置的全局标志;//指示数据已被接收 //没有打开的 Rx 操作 #define MAX_STR_LENGTH 64 char 整体字符串[MAX_STR_LENGTH]=""; //从最后一个'return' char 的整个输入 str pueOfString[MAX_STR_LENGTH]=""; //保留字符串 outString[MAX_STR_LENGTH]=""的新加法; //保留传出字符串 int bytesSent、bytesReceived; Timer_A_initUpModeParam Timer_A_params ={0}; /*=== main ==== // void main (void) { int i、myDelay、myDuration; char command[MAX_STR_LENGTH]; WDT_A_HOLD (WDT_A_base);//停止看门狗计时器 // USB API 所需的最小 Vcore 设置为 PMM_CORE_LEVEL_2。 PMM_setVCore (PMM_CORE_LEVEL_2); USBHAL_initPorts(); //配置用于低功耗(输出低电平)的 GPIO USBHAL_initClocks (8000000);//配置时钟。 MCLK=SMCLK=FLL=8MHz;ACLK=REFO =32kHz initTimer(); //准备计时器以进行 LED 切换 USB_setup (true、true);// Init USB & events;如果存在主机,则连接 __ENABLE_INTERRUPT ();//全局启用中断 USBCDC_REjectData (CDC0_INTFNUM); GPIO_setOutputHighOnPin (LED_PORT、LED_PIN);//LED 1.0打开 while (1) { uint8_t i; //检查 USB 状态并相应地直接检查主循环 开关(USB_getConnectionState()) { //在 USB 主机上枚举设备时执行此例 实例 ST_ENUM_ACTIVE: //输入 LPM0 (激活时不能执行 LPM3) _bis_SR_register (LPM0_bits + GIE); _NOP(); //在 USB 接收时退出 LPM 并执行接收操作 //如果为 true,则缓冲区中有一些数据;开始接收 cmd if (bCDCDataReceived){ //将 USB 缓冲区中的字节添加到字符串中 USBCDC_receiveDataInBuffer ((uint8_t*) puteOfString、MAX_STR_LENGTH、CDC0_INTFNUM);//获取字符串的下一部分 //将新的部分附加到整个部分 strcat (整体字符串、分段 OfString); //回显接收到的字符 USBCDC_sendDataInBackground ((uint8_t*) puteOfString、 strlen (nueOfString)、CDC0_INTFNUM、0); //用户是否还按了 Enter/Return 键? if (retInString (整体字符串)){ sscanf (整体字符串、"%s"%d %d %d、命令、&myDelay、&myDuration); //比较字符串并响应 如果(!(strcmp (command、"kill"))){ //关闭 timerA Timer_A_stop (timer_A0_BASE); //准备传出字符串 strcpy (outString、"\r\n"LED 关闭进程已启动。\r\n\r\n); //通过 USB 发送响应 USBCDC_sendDataInBackground ((uint8_t*) outString、 strlen (outString)、CDC0_INTFNUM、0); for (i=0;i<=myDelay;i++){ _delay_cycles (8000000); } //准备传出字符串 strcpy (outString、"\r\n 是!!!\r\n\r\n); //通过 USB 发送响应 USBCDC_sendDataInBackground ((uint8_t*) outString、 strlen (outString)、CDC0_INTFNUM、0); //关闭 LED P1.0 GPIO_setOutputLowOnPin (LED_PORT、LED_PIN); _delay_cycles (6000000);// 0.6秒延迟 GPIO_setOutputHighOnPin (LED_PORTDELAY、LED_PINDELAY);//JS 仅用于演示 //JS:唤醒时间。 for (i=0;i<=myDuration;i++){ _delay_cycles (8000000); } //准备传出字符串 strcpy (outString、"\r\n 还没有。\r\n LED 再次亮起\r\n); //通过 USB 发送响应 USBCDC_sendDataInBackground ((uint8_t*) outString、 strlen (outString)、CDC0_INTFNUM、0); //打开 LED P1.0 GPIO_setOutputHighOnPin (LED_PORT、LED_PIN); _delay_cycles (16000000); GPIO_setOutputLowOnPin (LED_PORTDELAY、LED_PINDELAY);//JS 仅用于演示 } 否则{ //准备传出字符串 //strcpy (outString、"\r\n 错误命令!\r\n\r\n); sprintf (outString、"\r\n 命令错误! '%s'\r\n\r\n"、命令); //通过 USB 发送响应 USBCDC_sendDataInBackground ((uint8_t*) outString、 strlen (outString)、CDC0_INTFNUM、0); } //清除字符串以准备下一个字符串 对于(i = 0;i < MAX_STR_LENGTH;i++){ 整体字符串[i]= 0x00; } } bCDCDataReceived 事件= false; } 中断; //这些情况在设备断开连接时执行 //主机(意思是,未枚举);已枚举但已暂停 //由主机连接,或连接到没有 USB 主机的有源集线器 //存在。 案例 ST_PHYS_DISCONNECTED: 实例 ST_ENUM_Suspended: 案例 ST_PHYS_Connected: //关闭 LED P1.0 // GPIO_setOutputLowOnPin (LED_PORT、LED_PIN); _bis_SR_register (LPM3_bits + GIE); _NOP(); 中断; //默认为瞬时状态执行 // ST_enum_in_progress。 通常、该状态仅持续少数几个状态 //秒。 确保在此状态下不进入 LPM3;USB //此处正在进行通信,因此必须使用模式 //为 LPM0或有源 CPU。 实例 ST_ENUM_IN_PROGRESS: 默认值:; } }// while (1) }// main() /* ====== UNMI_ISR ==== // #if defined (__TI_Compiler_version__)||(__IAR_systems_ICC__) #pragma vector = UNMI_Vector __interrupt void UNMI_ISR (void) #Elif defined (__GNUC__)&&(__MSP430__) void Compiler_attribute__((interrupt (UNMI_ISR)#vector (void)#UNMI_error! #endif { 开关(__evo_in_range (SYSUNIV、SYSUNIV_BUSIFG)) { 案例 SYSUNIV_NONE: __no_operation(); 中断; SYSUNIV_NMIIFG 案例: __no_operation(); 中断; SYSUNIV_OFIFG 案例: UCS_clearFaultFlag (UCS_XT2OFFG); UCS_clearFaultFlag (UCS_DCOFFG); SFR_clearInterrupt (SFR_oscillator_FAULT_INTERRUPT); 中断; 案例 SYSUNIV_ACCVIFG: __no_operation(); 中断; 案例 SYSUNIV_BUSIFG: //如果 CPU 在 USB 模块的同时访问 USB 内存 //挂起,可能会出现“总线错误”。 这会生成 NMI。 如果 // USB 在您的软件中自动断开连接,请设置 a //在这里断点并查看执行是否成功。 请参阅 //编程人员指南以了解更多信息。 SYSBERRIV = 0;//清除总线错误标志 USB_disable();//Disable } } /* === retInString ==== // //如果字符串中有0x0D 字符,则该函数返回 true;如果 //如此,它将剪裁0x0D 及其后面的任何内容。 uint8_t retInString (char* string) { uint8_t retPos = 0、i、len; char tempStr[MAX_STR_LENGTH]=""; strncpy (tempStr、string、strlen (string));//复制字符串 Len = strlen (tempStr); //找到0x0D;如果未找到,retPos 将在 len 结束 while ((tempStr[retPos]!= 0x0A)&&(tempStr[retPos]!= 0x0D)&& (retPos++< len); //如果实际找到0x0D ... if ((retPos < len)&&(tempStr[retPoS]= 0x0D)){ 对于(i = 0;i < MAX_STR_LENGTH;i++){//清空缓冲区 字符串[i]= 0x00; } //...将输入字符串修整为恰好在0x0D 之前 strncpy (string、tempStr、retPos); //...并告知调用函数我们这样做了 return (true); //如果实际找到0x0D… …} 否则、如果((retPos < len)&&(tempStr[retPos]= 0x0A){ //清空缓冲区 对于(i = 0;i < MAX_STR_LENGTH;i++){ 字符串[i]= 0x00; } //...将输入字符串修整为恰好在0x0D 之前 strncpy (string、tempStr、retPos); //...并告知调用函数我们这样做了 返回(真); } 否则、如果(tempStr[retPos]= 0x0D){ 对于(i = 0;i < MAX_STR_LENGTH;i++){//清空缓冲区 字符串[i]= 0x00; } //...将输入字符串修整为恰好在0x0D 之前 strncpy (string、tempStr、retPos); //...并告诉调用函数我们这样做了 返回(真); } 如果(RetPos < len){ 对于(i = 0;i < MAX_STR_LENGTH;i++){//清空缓冲区 字符串[i]= 0x00; } //...将输入字符串修整为恰好在0x0D 之前 strncpy (string、tempStr、retPos); //...并告知调用函数我们这样做了 返回(真); } 返回( false );//否则,找不到它 } /* ==== setTimer_a_Parameters === // //此函数设置计时器 A 参数 void setTimer_A_Parameters () { Timer_A_params.clockSource = Timer_A_CLOCKSOURCE_ACLK; Timer_A_params.clockSourceDivider = TIMER_A_CLOCKSOURCE_divider; Timer_A_params.timerIE_Interrupt = Timer_A_params.captureCompareInterruptEnable_CCR0_CCIE;TIE_DIE_DIT_DIAG_DIAG_DIAG_DIAG_DIAG_DISABLE_INTERRUPT = TIMER_DIAG_DIAG_DIAG_DIAG_DISABLE_ Timer_A_CAPTURECOMPARE INTERRUPT_ENABLE; Timer_A_params.timerClear = TIMER_A_DO _CLEAR; Timer_A_params.startTimer = false; } // *=== initTimer ====== */ void initTimer (void) { //配置计时器参数 setTimer_A_Parameters (); //启动计时器 Timer_A_clearTimerInterrupt (timer_A0_BASE); //将定时器周期设置为零 Timer_A_params.timerPeriod = 0; Timer_A_initUpMode (timer_A0_BASE、&Timer_A_params); } /* === Timer1_A0_ISR === // #if defined (__TI_Compiler_version__)||(__IAR_systems_icc_) #pragma vector=TIMER0_A0_Vector __interrupt void TIMER0_A0_ISR (void) #Elif defined (__GNU__)&&(__MSP430__)__INTERRUPT __TIMER0_A0_ISR (void TIMER0_ISR)(void TIMER0_A0)(void TIMER0_A0)(void TIMER0_ISR (void)#interrupt )(void TIMER0_A0)(void TIMER0_A0 #endif { GPIO_toggleOutputOnPin (LED_PORT、LED_PIN); } //released_Version_5_20_06_02

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jagbir、您好!

    此问题听起来像是"Babbling Bug "、也称为 USB10勘误表。 请参阅勘误文档以了解有关此解决方法的解决方法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Jagbir、您好!

    您是否能够解决您的问题? 由于没有响应、此主题将很快关闭。