MSP430F5529与HC-SR04超声波测距

该文描述了一个使用MSP430微控制器,配合HC-SR04超声波传感器进行距离测量的系统。通过发送高电平触发信号,测量回波的高电平时间并转换为距离。程序中涉及到定时器初始化、中断处理以及UART串口通信,实现了精度为0.5cm的测量,实际与理论值接近。
摘要由CSDN通过智能技术生成

原理

5529向Trig发送大于10us的高电平,HC-SR04模块开始工作,Echo向5529发送高电平同时向外发射信号,当接收到返回信号时,Echo结束高电平的发送。故所测距离=(高电平时间*声音速度)/2。声速为340m/s。

代码

HC-SR04模块工作频率为4MHZ晶振

#include "driverlib.h"
#include "clk.h"
#include "stdio.h"
#include <string.h>
#include <stdarg.h>
#include "bmp6.h"
#include <msp430.h>
#include "oled6.h"
#include "type6.h"
#define MCLK_IN_HZ      4000000
#define delay_us(x)     __delay_cycles((MCLK_IN_HZ/1000000*(x)))
#define delay_ms(x)     __delay_cycles((MCLK_IN_HZ/1000*(x)))
//1s=1000ms=1000000us
uint16_t x;
static double len;
static int f;
static int a;
static int z;
static int d1;
static int d2;
static int fule;


void start()
{
    GPIO_setAsOutputPin (GPIO_PORT_P3,GPIO_PIN0 );
    GPIO_setOutputLowOnPin (GPIO_PORT_P3, GPIO_PIN0);
    GPIO_setOutputHighOnPin (GPIO_PORT_P3, GPIO_PIN0);
    delay_us(20);
    GPIO_setOutputLowOnPin (GPIO_PORT_P3, GPIO_PIN0);
}

void time()
{
        Timer_A_initUpModeParam initContParam = {0};
        initContParam.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
        initContParam.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
        initContParam.timerPeriod = 50000;
        initContParam.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_ENABLE;
        initContParam.captureCompareInterruptEnable_CCR0_CCIE = TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE;
        initContParam.timerClear = TIMER_A_DO_CLEAR;
        initContParam.startTimer = true;
        Timer_A_initUpMode(TIMER_A1_BASE, &initContParam);

           //__bis_SR_register(GIE);
}
void uartinit1()
{

    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4,GPIO_PIN5);
    GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P4, GPIO_PIN4);
    USCI_A_UART_initParam param1 = {0};
    param1.selectClockSource = USCI_A_UART_CLOCKSOURCE_SMCLK;
    param1.clockPrescalar = 26;
    param1.firstModReg = 1;
    param1.secondModReg = 0;
    param1.parity = USCI_A_UART_NO_PARITY;
    param1.msborLsbFirst = USCI_A_UART_LSB_FIRST;
    param1.numberofStopBits = USCI_A_UART_ONE_STOP_BIT;
    param1.uartMode = USCI_A_UART_MODE;
    param1.overSampling = USCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION;
    if (STATUS_FAIL == USCI_A_UART_init(USCI_A1_BASE, &param1)){
            return;
        }
    //Enable UART module for operation
    USCI_A_UART_enable(USCI_A1_BASE);

}
void UART_printf(uint16_t baseAddress, const char *format,...)
{
    uint32_t length;
    va_list args;
    uint32_t i;
    char TxBuffer[128] = {0};

    va_start(args, format);
    length = vsnprintf((char*)TxBuffer, sizeof(TxBuffer), (char*)format, args);
    va_end(args);

    for(i = 0; i < length; i++)
        USCI_A_UART_transmitData(baseAddress, TxBuffer[i]);
}

void capture()
{
            Timer_A_initContinuousModeParam htim = {0};
            htim.clockSource = TIMER_A_CLOCKSOURCE_SMCLK;
            htim.clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_1;
            htim.timerInterruptEnable_TAIE = TIMER_A_TAIE_INTERRUPT_DISABLE;
            htim.timerClear = TIMER_A_DO_CLEAR;
            htim.startTimer = false;
            Timer_A_initContinuousMode(TIMER_A2_BASE, &htim);


            GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P2, GPIO_PIN4);
            Timer_A_initCaptureModeParam initComParam = {0};
            initComParam.captureRegister = TIMER_A_CAPTURECOMPARE_REGISTER_1;
            initComParam.captureMode = TIMER_A_CAPTUREMODE_FALLING_EDGE;
            initComParam.captureInputSelect = TIMER_A_CAPTURE_INPUTSELECT_CCIxA;
            initComParam.synchronizeCaptureSource = TIMER_A_CAPTURE_SYNCHRONOUS;
            initComParam.captureInterruptEnable = TIMER_A_CAPTURECOMPARE_INTERRUPT_ENABLE;
            initComParam.captureOutputMode = TIMER_A_OUTPUTMODE_OUTBITVALUE;
            Timer_A_initCaptureMode(TIMER_A2_BASE, &initComParam);
            Timer_A_startCounter( TIMER_A2_BASE,TIMER_A_CONTINUOUS_MODE);

}

int main(void) {

    WDT_A_hold(WDT_A_BASE);
    clk_Init ();
    //UCS_Init();
    capture();
    uartinit1();
    time();
    __bis_SR_register(GIE);
    OLED_Init();    //初始化
    OLED_Clear();   //清屏
    GPIO_setAsOutputPin (GPIO_PORT_P1,GPIO_PIN0 );
    GPIO_setAsOutputPin (GPIO_PORT_P4,GPIO_PIN7 );
    GPIO_setOutputLowOnPin (GPIO_PORT_P1, GPIO_PIN0);
    GPIO_setOutputLowOnPin (GPIO_PORT_P4, GPIO_PIN7);
    while(1)
    {

        if(a>20)
        {
            start();
            Timer_A_clear (TIMER_A1_BASE);
            a=0;
        }

    }
    return (0);
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt
void TIMER1_A0_ISR (void)
{

    a++;
    Timer_A_clearTimerInterrupt (TIMER_A1_BASE);

}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=TIMER2_A1_VECTOR
__interrupt void TIMER2_A1_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER2_A1_VECTOR))) TIMER2_A1_ISR (void)
#else
#error Compiler not supported!
#endif
{
    switch(TA2IV)
        {
            case TA2IV_TACCR1:

                x = Timer_A_getCounterValue (TIMER_A1_BASE);

                len = x*0.00425;
                z = (int)len-10;
                fule = (int)100*len;
                d1 = (fule/10)%10;
                d2 = fule%10;
                UART_printf(USCI_A1_BASE, "%d\r\n",z);
                OLED_ShowNum(40,1,z,3,16);
                OLED_ShowChar(70,1,'.',16);
                OLED_ShowNum(80,1,d1,1,16);
                OLED_ShowNum(90,1,d2,1,16);

                break;

        }
}

效果

实际值20.5cm,测量值20.45cm

 aa0ae5c88d1642d5ac4f9fbdd8576e16.jpegb007da86d09e484c9c31a1779ae8c780.jpeg

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值