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.

[参考译文] MSP430FR2676:用于8x8共电容阵列的后通道 UART

Guru**** 2387830 points
Other Parts Discussed in Thread: MSP430FR2676, MSP430G2553, ENERGIA
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1067078/msp430fr2676-backchannel-uart-for-8x8-mutual-capacitance-array

部件号:MSP430FR2676
《线程》中讨论的其他部件: MSP430G2553ENERGIA

我一直在使用编程器和调试模块与 MSP430FR2676合作,并采用典型的金刚石阵列8x8共电容阵列设计。 我想知道如何获得该阵列中每个传感器的过滤计数,并不断通过 UART 传输这些信息。 我一直关注 MSP430FR2676后向频道 UART 演示,该演示在迷人的设计工作室中找到。 我打开了这个项目并将它加载到我的主板上,我在 CCS 中打开了终端,希望看到这些信息被发送出去,但无法完成这项工作。 根据我收集的数据,这个特定示例仅假定在按下按钮时输出信息,并且只输出一个特定的过滤按钮对终端的计数(尽管尚未看到这种情况有效)。 我一直在使用 此 http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430Ware/3_70_00_05/exports/MSP430Ware_3_70_00_05/captivate/docs/api_guide/FR2633/html/group__CAPT__Buttons.html 作为参考,我看到 Capt_Buttons 下列出的三个函数似乎仅支持查找正在按下的主按钮,不允许我访问所有过滤的按钮计数? 是否有任何示例代码可用于此类事物的进一步示例,或任何可能有帮助的资源? 根据我目前的理解,我在 Captivate Design Studio 中创建了我的项目,调整我的传感器,然后为 CCS 生成源代码,然后将有关 UART 通信的代码添加到此代码中,并将其上传到主板。 我在这个迷人的设计工作室里附上了我当前项目的一些图像(我成功地调谐了我的传感器)。  我在使用“嵌入式系统”方面的唯一经验是使用 Energia 对 MSP430G2553进行编程,我认为这种编程不支持被迷住的设备,CCS 对我来说相当抽象。 这些是我迄今为止一直在使用的现有资源:

https://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/CapTIvate_Design_Center/latest/exports/docs/users_guide/html/CapTIvate_Technology_Guide_html/markdown/ch_workshop.html

http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430Ware/3_70_00_05/exports/MSP430Ware_3_70_00_05/captivate/docs/api_guide/FR2633/html/group__CAPT__Buttons.html#gaa50fcc71045648e6eaf5e31549d044b5

https://www.ti.com/lit/ug/slau445i/slau445i.pdf

以下是德州仪器(TI)在演示中提供的代码示例(我重点关注的部分):  

//#############################################################################
//
//! \file Backchannel_UART_demo.c
//
// Group: MSP
// Target Devices: MSP430FR2633
//
// (C) Copyright 2018, Texas Instruments, Inc.
//#############################################################################
// TI Release: 1.83.00.05
// Release Date: May 15, 2020
//#############################################################################

//*****************************************************************************
// Includes
//*****************************************************************************

#include "demo.h"

//*****************************************************************************
// Definitions
//*****************************************************************************

//*****************************************************************************
// Global Variables
//*****************************************************************************

//*****************************************************************************
// Function Prototypes
//*****************************************************************************

//*****************************************************************************
// Function Implementations
//*****************************************************************************

//callback function for keypad buttons
void keypad_callback(tSensor* pSensor){

//trigger once when the button is touched
if(((pSensor->bSensorTouch)) && (!(pSensor->bSensorPrevTouch))){

//decode the dominant button number
uint8_t myButtonNumber = CAPT_getDominantButton(pSensor);
uint8_t loopCounter = 0;
uint8_t cycleCounter = 0;
uint8_t elementCounter = 0;
uint8_t myCycle;
uint8_t myElement;

//go through each cycle pointer, and within it each element pointer to find element that corresponds to the dominant button
for(cycleCounter = 0; cycleCounter < pSensor->ui8NrOfCycles; ++cycleCounter){
for(elementCounter = 0; elementCounter < pSensor->pCycle[cycleCounter]->ui8NrOfElements; ++elementCounter){
//get the cycle and element numbers from the dominant button
if(loopCounter == myButtonNumber){
myCycle = cycleCounter;
myElement = elementCounter;
}
loopCounter++;
}

}

//placeholder for output data, must be static to ensure that it is available & unchanged across function calls
static uint8_t str[100];

//access the element's raw count
//CAPT_getDominantButton() returns 0x00 for button #1, 0x01 for button #2... etc
uint16_t rawCount = pSensor->pCycle[myCycle]->pElements[myElement]->pRawCount[0];

//extract the filtered count, NOTE this truncates to the nearest natural number
uint16_t filteredCount = pSensor->pCycle[myCycle]->pElements[myElement]->filterCount.ui16Natural ;

//get the length of the output string, insert int data into output string
uint8_t str_length = sprintf((char*)str, "Button Pressed: %d\tRaw Count: %d\tFiltered Count: %d\n\r", myButtonNumber + 1, rawCount, filteredCount);

//transmit data
UART_transmitBuffer(str, str_length);
}
}


//Sets all the parameters for UART transmission
const tUARTPort UARTPort =
{
//does not receive messages, so no callback needed
.pbReceiveCallback = NULL,

//does not receive messages, so no callback needed
.pbErrorCallback = 0,

//choose clock source
.peripheralParameters.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,

//clockPrescalar is UCBRx = int(N / 16), where N = clock_frequency / baud_rate
//int(N / 16) = int(2000000 / 9600 / 16) = int(13.02) = 13;
.peripheralParameters.clockPrescalar = SMCLK_FREQ_MHZ * 1000000 / 9600 / 16,

//controls UCBRF bits for oversampling mode
//UCBRF = int(((N/16) - int(N/16)) * 16) = int(((208.3333/16) - int(208.3333/16)) * 16) = int(0.3333) = 0
.peripheralParameters.firstModReg = 0,

//consult table 22-4 in the user's guide to find the register value corresponding to UCBRF number
//fraction portion of N = 0.3333
//in the table, 0.3333 <---> 0x49
.peripheralParameters.secondModReg = 0x49,

//controls parity bit - NOTE the eZ-FET does not support a parity bit
.peripheralParameters.parity = EUSCI_A_UART_NO_PARITY,

//least or most significant bit first
.peripheralParameters.msborLsbFirst = EUSCI_A_UART_LSB_FIRST,

//select either one or two stop bits
.peripheralParameters.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT,

//select whether to use multiprocessor/autobaud modes
.peripheralParameters.uartMode = EUSCI_A_UART_MODE,

//selects oversampling vs low-freq baud rate modes
.peripheralParameters.overSampling = EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION

};

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

    亚历克斯:

    我对您的帖子做了一些编辑,以便让其他人关注这一主题。

    听起来你在正确的轨道上。

    步骤1 -首先要确保在 Capt_userconfig.h 中设置正确,是将 Capt_interface 设置为(__Capt_no_interface__),这应该是从 MSP430FR2676_backchannel_UART_DEMO 开始的。

    这实际上会禁用目标和 GUI 之间的通信接口,方法是告诉编译器不要在内部版本中包含任何通信驱动程序,以及在代码中任何其他位置,而该代码库要将数据发送到 GUI。

    步骤2 -下一步,您希望能够重新使用 UART 驱动程序函数调用,因此在本演示的项目设置中,在编译器->预定义符号下,默认情况下您将看到 UART_ENABLE =TRUE。

    注:如果您想返回并与 GUI 进行通信(重新调整传感器或其他内容),则需要从项目设置中删除此符号,并将#define Capt_interface (__Capt_no_interface__)更改为#define Capt_interface (__Capt_UART_interface__)或#define Capt_interface (_使用 KUL接口_)。

    步骤3 -您显然不想运行@250K 波特率,这是与 GUI 通信的默认速率,因此,您可以轻松创建自己的 UART 配置并选择适用于 PC 终端应用程序的波特率。  看起来你也做过这件事。

    步骤4 - 在回叫中,您希望执行以下操作。 代码循环显示每个周期内的所有周期和所有元素,捕捉过滤的测量计数,转换为 ASCII 并发送到 PC。  您可以根据需要进行优化或执行此操作。  请记住,您有64个元素,并且回叫中发送的所有数据可能需要比测量扫描周期长(默认为33ms)。  因此,您可能选择了非常高的波特率或增加测量周期。

    void trackpad_callback(tSensor* pSensor)
    {
        uint8_t ui16BufferLength;
        uint8_t ui8Index = 0;
        uint8_t element;
        uint8_t cycle;
    
        for(cycle = 0; cycle < pSensor->ui8NrOfCycles; ++cycle)
        {
            for(element = 0; element < pSensor->pCycle[cycle]->ui8NrOfElements; ++element)
            {
                filteredCount[ui8Index] = pSensor->pCycle[cycle]->pElements[element]->filterCount.ui16Natural;
                ui16BufferLength = sprintf((char*) asciiBuffer, "%d\t%d\r\n\0", ui8Index, filteredCount[ui8Index] );
                UART_transmitBuffer(asciiBuffer,ui16BufferLength);
                ui8Index++;
            }
        }
    
    }

    这是否有帮助?

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

    亚历克斯:

    我想再补充一条关于加速转换的评论,因为您有64个测量点。

    传感器结构中有一个位,.bLpmControl = false,在每个测量周期后,基本上会将 Captivate 外围设备1.5v LDO 置于待机模式以节省电量。  在下一个测量周期中,LDO 被设置回活动模式,但会延迟约350US 以使 LDO 稳定。  如果您有几个按钮需要两个测量周期,则影响不大,而且您不是在跟踪手指运动,因此这确实是一个不在乎的问题。  但是,由于您有16个测量值,因此您希望快速通过这些测量,因此没有必要延迟这些测量值。

    因此,我建议将传感器结构中的位更改为.bLpmControl = true。

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

    我还无法使其正常工作,我进行了更改,但现在它说它无法在我的主目录中打开源文件“DEMO.h”,尽管在我一直用于大纲的演示中,它在执行此操作时没有问题。 我在项目中有文件夹演示,基于 TI 提供的演示,它们不包括任何额外路径,因此我认为这不是必需的。

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

    亚历克斯:

    检查编译器中是否有演示路径,包括项目设置中设置的路径选项。

    否则,主要尝试使用#include "./demo/sdemo.h"

    丹尼斯

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

    解决了该错误,我还需要在预定义符号中使用“UART_ENABLE =true”吗? 有许多其他错误现在都与未定义的变量有关:tUART 端口,asciBuffer 和 filteredCount。tUART 端口是用“UART_openPort (&UARTPort)”定义的;“main.c 对吗? 其他人应该来自迷人的 API 吗?  

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

    亚历克斯:

    是的,正确。

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

    亚历克斯:


    我们已经听过您的发言了一段时间,所以我要假设您能够推进您的项目。
    我会将此帖子标记为已解决,但如果不是这种情况,请单击“这未能解决我的问题”按钮,并使用更多信息回复此主题。
    如果此线程已锁定,请单击“询问相关问题”按钮,在新线程中描述您的问题的当前状态以及您可能需要帮助我们解决您的问题的任何其他详细信息。

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

    很抱歉,我自己一直在尝试解决问题,但我仍然无法解决我遇到的一些错误,我不明白原因。  

    以下是错误的图像:

    我一直在使用搜索功能来调查为什么它说这些内容没有定义(奇怪的是,演示使用的是相同的,并且没有出现此问题)。 我看到 tUART 端口在 Capt_interface 中定义,并在 UART.c 和 UART.h 中使用,没有问题,但在 DEMO.c 和 demo.h 中引用时,它会成为一个问题(简单使用相同的文件名,但项目不同)。asciBuffer 似乎没有被定义为迷住 API 的区别? 使用 filteredCount[ui8Index]= pSensor->pCycle [cycle]->pElements[element]->filterCount.ui16Natural 修复了 unfilteredCount。

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

    亚历克斯:

    这部分是我的坏事。  您需要定义这些变量。

    UINT8_t    asciBuffer[32];
    UINT16_t   文件计数[64];

    我只提供了一部分演示代码来说明如何迭代周期和元素以检索过滤的计数。

    下面是整个代码。

    #include "captivate.h"
    #include "CAPT_UserConfig.h"
    #include "CAPT_BSP.h"
    #include "UART.h"
    #include <stdio.h>
    
    //======================== DEFINES ========================================
    #define FIRST_SENSOR_TOUCH      (pSensor->bSensorTouch == true) && (pSensor->bSensorPrevTouch == false)
    #define SENSOR_TOUCH            (pSensor->bSensorTouch == true) && (pSensor->bSensorPrevTouch == true)
    #define EXIT_TOUCH              (pSensor->bSensorTouch == false) && (pSensor->bSensorPrevTouch == true)
    #define NO_TOUCH TOUCH          (pSensor->bSensorTouch == false) && (pSensor->bSensorPrevTouch == false)
    
    //======================= VARIABLES ========================================
    uint8_t     asciiBuffer[32];
    uint16_t    filteredCount[64];
    
    // Added this so when switching back to GUI interface, this code doesn't cause compiler warnings
    #if CAPT_INTERFACE ==  (__CAPT_NO_INTERFACE__)
    
    /*
     * CREATE A LOCAL INSTANCE OF UART PARAMETERS
     */
    static const tUARTPort UARTPort =
    {
        .pbReceiveCallback = NULL,
        .pbErrorCallback = 0,
        .peripheralParameters.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK,
        .peripheralParameters.clockPrescalar = UART__PRESCALER,
        .peripheralParameters.firstModReg = UART__FIRST_STAGE_MOD,
        .peripheralParameters.secondModReg = UART__SECOND_STAGE_MOD,
        .peripheralParameters.parity = EUSCI_A_UART_NO_PARITY,
        .peripheralParameters.msborLsbFirst = EUSCI_A_UART_LSB_FIRST,
        .peripheralParameters.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT,
        .peripheralParameters.uartMode = EUSCI_A_UART_MODE,
        .peripheralParameters.overSampling = UART__SAMPLING_MODE
    };
    #endif
    
    //=========================== CALLBACKS =======================================
    /*
     * TRACKPAD CALLBACK
     * AUTOMATICALLY CALLED AFTER SENSOR IS PROCESSED
     * ADD APPLICATION SPECIFIC CODE HERE
     */
    void trackpad_callback(tSensor* pSensor)
    {
        uint8_t ui16BufferLength;
        uint8_t ui8Index = 0;
        uint8_t element;
        uint8_t cycle;
    
        for(cycle = 0; cycle < pSensor->ui8NrOfCycles; ++cycle)
        {
            for(element = 0; element < pSensor->pCycle[cycle]->ui8NrOfElements; ++element)
            {
                filteredCount[ui8Index] = pSensor->pCycle[cycle]->pElements[element]->filterCount.ui16Natural;
                ui16BufferLength = sprintf((char*) asciiBuffer, "%d: %d\r\n", ui8Index, filteredCount[ui8Index] );
                UART_transmitBuffer(asciiBuffer,ui16BufferLength);
                ui8Index++;
            }
        }
    
    }

    关于找不到“tUART 端口”的错误,该错误是在 UART.h.中的“迷人的库通信”部分中定义的  在编译器预定义符号中,是否确实有'UART_ENABLE = true'?

    如果仍然卡住,请将 CCS 项目导出到 zip 文件,然后上传到此处。  我要看一下。  要在 CCS 中正确导出项目,请从顶部菜单中选择“文件”>“导出”>“存档文件”。