打印

MSPM0G3507应用之ADC数据通过I2C接口进行传输

[复制链接]
530|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
xyz549040622|  楼主 | 2023-12-24 23:01 | 只看该作者
/*
* Copyright (c) 2021, Texas Instruments Incorporated
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* *  Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* *  Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* *  Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "ti_msp_dl_config.h"

/* Maximum size of TX packet */
#define I2C_TX_MAX_PACKET_SIZE (16)

/* Maximum size of RX packet */
#define I2C_RX_MAX_PACKET_SIZE (16)

/* Commands for the ADC sampling */
#define SAMPLE_ADC (0x01)
#define SEND_RESULTS (0x02)
#define SAMPLE_SEND_RESULTS (0x03)

/* Data sent to Controller in response to Read transfer, default set to 0xAA */
uint8_t gTxPacket[I2C_TX_MAX_PACKET_SIZE] = {0xAA};

/* Counters for TX length and bytes sent */
uint32_t gTxLen, gTxCount;

/* Data received from Controller during a Write transfer */
uint8_t gRxPacket[I2C_RX_MAX_PACKET_SIZE];

/* Counters for TX length and bytes sent */
uint32_t gRxLen, gRxCount, gCommandCount;

/* Boolean to know when a stop command was issued */
bool gStopReceived = false;

/* ADC variables:
* gADCResult is the adc result taken from the Memory Register
* NumberOfADCSamples is the count of total ADC samples to keep track for the gTxResult buffer
*/

uint16_t gADCResult;
uint8_t gNumberOfADCSamples = 0;
bool gCheckADC = false;

/* Process Command will take the command from the I2C Rx and parse which command is to be issued */
void processCommand(uint8_t cmd);

/* ADC Process will start the ADC and separate the ADC result into 8 bits to place into the Tx Packet buffer. */
void ADCProcess();

int main(void)
{
    SYSCFG_DL_init();

    /* Set LED to indicate start of transfer */
    DL_GPIO_setPins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);

   /* Reset variables for the Tx, these are used in the I2C ISR */
    gTxCount = 0;
    gTxLen   = 0;
    DL_I2C_enableInterrupt(I2C_INST, DL_I2C_INTERRUPT_TARGET_TXFIFO_TRIGGER);

    /* Initialize variables to receive data inside RX ISR */
    gRxCount = 0;
    gRxLen   = I2C_RX_MAX_PACKET_SIZE;

    NVIC_EnableIRQ(I2C_INST_INT_IRQN);
    NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);


    while (1)
    {
        /* Sleep until the stop command is given from the I2C Controller */
        while(gStopReceived == false)
            __WFE();
        gStopReceived = false;

        /* Process given commands */
        for(uint16_t i = 0; i < gCommandCount; i++){
            processCommand(gRxPacket[i]);
        }
        gCommandCount = 0;
    }
}

/* Process the command given */
void processCommand(uint8_t cmd){

    switch(cmd){
        /* Sample the ADC */
        case SAMPLE_ADC:
            ADCProcess();
            break;
        /* Add 2 to the Tx Length, this equates to one more full result added to the TX transmission */
        case SEND_RESULTS:
            gTxLen += 2;
            break;
        /* Sample the ADC and increment the Tx Length. */
        case SAMPLE_SEND_RESULTS:
            ADCProcess();
            gTxLen += 2;
            break;
        default:
            break;
    }
}

/* Start the ADC process of sampling and storing into the TxPacket Buffer */
void ADCProcess(){

    /* Start the ADC Sampling */

    DL_ADC12_startConversion(ADC12_0_INST);

    /* Sleep until the ADC sampling and conversion is finished, then reset the boolean */
    while(gCheckADC == false){
        __WFI();
    }
    gCheckADC = false;

    /* Get the ADC result and place the upper byte and lower byte into the TxPacket, upper byte first */
    gADCResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
    gTxPacket[gNumberOfADCSamples*2] = (uint8_t)((gADCResult >> 8) & 0xFF);
    gTxPacket[gNumberOfADCSamples*2 + 1] = (uint8_t)(gADCResult & 0xFF);

    /* Make sure the number of ADC samples does not go over the TxPacket size, if it does next sample will overwrite */
    gNumberOfADCSamples++;
    if(gNumberOfADCSamples*2 + 1 > I2C_TX_MAX_PACKET_SIZE)
    {
        gNumberOfADCSamples = 0;
    }
    DL_ADC12_enableConversions(ADC12_0_INST);

}


void ADC12_0_INST_IRQHandler(void) {
  switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
  case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
    gCheckADC = true;
    break;
  default:
    break;
  }
}


void I2C_INST_IRQHandler(void)
{
    static bool commandReceived = false;

    switch (DL_I2C_getPendingInterrupt(I2C_INST)) {
        case DL_I2C_IIDX_TARGET_START:
            /* Initialize RX or TX after Start condition is received */
            gTxCount = 0;
            gRxCount = 0;
            commandReceived   = false;
            /* Flush TX FIFO to refill it */
            DL_I2C_flushTargetTXFIFO(I2C_INST);
            break;
        case DL_I2C_IIDX_TARGET_RXFIFO_TRIGGER:
            /* Store received commands in buffer */
            commandReceived = true;
            while (DL_I2C_isTargetRXFIFOEmpty(I2C_INST) != true) {
                if (gRxCount < gRxLen) {
                    gRxPacket[gRxCount++] = DL_I2C_receiveTargetData(I2C_INST);
                } else {
                    /* Prevent overflow and just ignore data */
                    DL_I2C_receiveTargetData(I2C_INST);
                }
            }
            break;
        case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
            /* Fill TX FIFO with ADC Results */
            if (gTxCount < gTxLen) {
                gTxCount += DL_I2C_fillTargetTXFIFO(
                    I2C_INST, &gTxPacket[gTxCount], (gTxLen - gTxCount));
            } else {
                /*
                 * Fill FIFO with 0xAA if more data is requested than
                 * expected gTxLen
                 */
                while (DL_I2C_transmitTargetDataCheck(I2C_INST, 0xAA) != false)
                    ;
            }
            break;
        case DL_I2C_IIDX_TARGET_STOP:
            /* If commands were received, set the command count to RxCount and reset fifo */
            if (commandReceived == true) {
                gCommandCount = gRxCount;
                commandReceived = false;
                DL_I2C_flushTargetTXFIFO(I2C_INST);
            }

            /* Set Stop Received to true to allow the main loop to proceed */
            gStopReceived = true;
            /* Toggle LED to indicate successful RX or TX */
            DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
            break;
        default:
            break;
    }
}


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2782

主题

19267

帖子

104

粉丝