嵌入式系统实践 10—— 模数转换器 基于ARM汇编 Keil5 MSP432 P401R开发板

LAB10

绘图串口助手

/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdio.h>
#include <string.h>

volatile uint16_t adcResult;
char strtmp[20] = {
    
    '\0'}; 

/* 设置波特率为115200,参数设置链接:
http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
*/
const eUSCI_UART_Config uartConfig =
{
    
    
	EUSCI_A_UART_CLOCKSOURCE_SMCLK,          //选用SMCLK(4M)时钟源
	2,                                      // BRDIV = 2 ,clockPrescalar时钟分频系数 
	2,                                       // UCxBRF = 2  firstModReg (BRDIV、UCxBRF、 UCxBRS和SMCLK,用于设置串口波特率)
	187,                                       // UCxBRS = 187 secondModReg
	EUSCI_A_UART_NO_PARITY,                  // 校验位None
	EUSCI_A_UART_LSB_FIRST,                  // 低位优先,小端模式
	EUSCI_A_UART_ONE_STOP_BIT,               // 停止位1位
	EUSCI_A_UART_MODE,                       // UART mode
	EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION  // 设置为过采样,该数值为1
};

int main(void)
{
    
    
    int i=0; 
    /* 停用开门狗 */
    MAP_WDT_A_holdTimer();
    
    /* Simple FPU Config */   
    MAP_FPU_enableModule();/*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/    
    MAP_CS_setDCOFrequency(4000000);/* 设置DCO频率为指定频率,此处DCO=4M*/
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置MCLK(主时钟,可用于CPU主频、ADC频率等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=4M*/
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO/1=4M*/
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置SMCLK(低速子系统主时钟,可用TimerA、USART频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/1=4M*/

    /* P1.2和P1.3选用UART模式并分别作为UCA0_RXD(接收)和UCA0_TXD(发送) */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
    
    /* P5.4配置为模拟输入模式*/
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION);
    
    /* 使用uartConfig配置UART_A0 */
    MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);

    /* 使能UART_A0 */
    MAP_UART_enableModule(EUSCI_A0_BASE);

    /* Initializing ADC (MCLK/1/1) */
    ADC14_enableModule();/*使能14位ADC模块*/
    ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_4,0);
		/*初始化14位ADC模块,选用MCLK时钟源,ADC预分频系数为1,ADC分频系数为4,ADC时钟=MCLK/1/4=1M*/

    ADC14_configureSingleSampleMode(ADC_MEM0, true);
		/*将ADC模块配置为使用单个ADC内存采样转换,内存位置为ADC_MEM0*/
    ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,ADC_INPUT_A1, 0);
		/*ADC模块内存位置选用ADC_MEM0,参考电压选择ADC_VREFPOS_AVCC_VREFNEG_VSS,通道选择A1,不选择差分模式*/   
    ADC14_enableSampleTimer(ADC_MANUAL_ITERATION); /*ADC模块采用手动采样模式*/
    ADC14_enableInterrupt(ADC_INT0); /*使能ADC_INT0中断*/
    
    Interrupt_enableInterrupt(INT_ADC14);/*使能INT_ADC14模块中断*/
    Interrupt_enableMaster(); /*使能主中断*/
    
    ADC14_enableConversion(); /*使能ADC模块转换*/   
    ADC14_toggleConversionTrigger(); /*触发ADC模块开始采样*/

    while (1)
    {
    
    
		/* 将ADC采集数据以浮点数形式保存至strtmp中 */
        sprintf(strtmp,"$%.3lfv;\n",adcResult*3.3/16384);

        for (i=0;i<strlen(strtmp);i++)
		{
    
    
            MAP_UART_transmitData(EUSCI_A0_BASE, strtmp[i]);	//将strtmp字符串通过UART_A0逐个字符发出
        }
		for(i=200000;i>0;i--);
    }
}

/* 当转换完成并放置到ADC_MEM0时,此中断发生。 */
void ADC14_IRQHandler(void)
{
    
    
    uint64_t status;    
    status = ADC14_getEnabledInterruptStatus();
    ADC14_clearInterruptFlag(status);

    if(status & ADC_INT0)
    {
    
    
        adcResult = ADC14_getResult(ADC_MEM0);  /*将ADC_MEM0中的值赋值给adcResult*/         
        ADC14_toggleConversionTrigger();/*触发ADC模块开始采样*/
    }     
}

光控灯

使用LED2的红灯、绿灯和蓝灯组合实现白灯;
当用手上下接触LIGHT光敏电阻时,白灯的亮度发生改变,光敏电阻无遮挡时白灯亮度最暗,光敏电阻被完全遮挡时白灯亮度最亮;
观察串口工具中的回显数值;
提示:请复习PWM实验中LED亮度调节的方法

/* DriverLib Includes */
#include <ti/devices/msp432p4xx/driverlib/driverlib.h>

/* Standard Includes */
#include <stdint.h>
#include <stdio.h>
#include <string.h>

volatile uint16_t adcResult;
char strtmp[20] = {
    
    '\0'}; 

/* 设置波特率为115200,参数设置链接:
http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP430BaudRateConverter/index.html
*/
const eUSCI_UART_Config uartConfig =
{
    
    
	EUSCI_A_UART_CLOCKSOURCE_SMCLK,          //选用SMCLK(4M)时钟源
	2,                                      // BRDIV = 2 ,clockPrescalar时钟分频系数 
	2,                                       // UCxBRF = 2  firstModReg (BRDIV、UCxBRF、 UCxBRS和SMCLK,用于设置串口波特率)
	187,                                       // UCxBRS = 187 secondModReg
	EUSCI_A_UART_NO_PARITY,                  // 校验位None
	EUSCI_A_UART_LSB_FIRST,                  // 低位优先,小端模式
	EUSCI_A_UART_ONE_STOP_BIT,               // 停止位1位
	EUSCI_A_UART_MODE,                       // UART mode
	EUSCI_A_UART_OVERSAMPLING_BAUDRATE_GENERATION  // 设置为过采样,该数值为1
};


#define TA1_PERIODS (62500)
#define PWM_PERIODS (62500/50)

const Timer_A_UpModeConfig TA0 =     
{
    
    
        TIMER_A_CLOCKSOURCE_SMCLK,              // 选用SMCLK作为时钟源
        TIMER_A_CLOCKSOURCE_DIVIDER_1,          // 分频系数为1,Timer_A0=SMCLK/1=62.5k
        PWM_PERIODS-1,                          // 周期时长=PWM_PERIODS/Timer_A0=20ms(注:视觉暂留时间约为100ms至400ms),因从零开始计数,建议做减一操作;
        TIMER_A_TAIE_INTERRUPT_DISABLE,         // 禁用定时器中断
        TIMER_A_CCIE_CCR0_INTERRUPT_DISABLE,    // 禁用定时器CCR0中断
        TIMER_A_DO_CLEAR                        // 清空数值
};

Timer_A_CompareModeConfig TA0_CCR1_PWM =
{
    
    
        TIMER_A_CAPTURECOMPARE_REGISTER_1,          // CCR1通道
        TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,   // 禁用CCR中断
        TIMER_A_OUTPUTMODE_RESET_SET,               // 采用复位/置位
        PWM_PERIODS                                 // 占空比,此处不用减一,当定时器数值val<PWM_PERIODS时,输出高电平(即0到PWM_PERIODS-1,共PWM_PERIODS);当val>=PWM_PERIODS时输出低电平
};

Timer_A_CompareModeConfig TA0_CCR2_PWM =
{
    
    
        TIMER_A_CAPTURECOMPARE_REGISTER_2,         // CCR2通道
        TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE,  // 禁用CCR中断
        TIMER_A_OUTPUTMODE_RESET_SET,              // 采用复位/置位
        PWM_PERIODS    
};

Timer_A_CompareModeConfig TA0_CCR3_PWM =
{
    
    
        TIMER_A_CAPTURECOMPARE_REGISTER_3,        // CCR3通道
        TIMER_A_CAPTURECOMPARE_INTERRUPT_DISABLE, // 禁用CCR中断
        TIMER_A_OUTPUTMODE_RESET_SET,             // 采用复位/置位
        PWM_PERIODS    
};

const Timer_A_UpModeConfig TA1 =
{
    
    
        TIMER_A_CLOCKSOURCE_SMCLK,              // 选用SMCLK作为时钟源
        TIMER_A_CLOCKSOURCE_DIVIDER_1,          // 分频系数为1,Timer_A1=SMCLK/1=62.5k
        TA1_PERIODS-1,                          // 周期时长=TA1_PERIODS/Timer_A1=1s,因从零开始计数,建议做减一操作;
        TIMER_A_TAIE_INTERRUPT_DISABLE,         // 禁用定时器中断
        TIMER_A_CCIE_CCR0_INTERRUPT_ENABLE ,    // 使能定时器CCR0中断
        TIMER_A_DO_CLEAR                        // 清空数值
};

int main(void)
{
    
    
    int i=0; 
    /* 停用开门狗 */
    MAP_WDT_A_holdTimer();
    
    /* Simple FPU Config */   
    MAP_FPU_enableModule();/*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/    
    MAP_CS_setDCOFrequency(4000000);/* 设置DCO频率为指定频率,此处DCO=4M*/
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置MCLK(主时钟,可用于CPU主频、ADC频率等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=4M*/
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO/1=4M*/
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置SMCLK(低速子系统主时钟,可用TimerA、USART频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/1=4M*/

    /* P1.2和P1.3选用UART模式并分别作为UCA0_RXD(接收)和UCA0_TXD(发送) */
    MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P1,GPIO_PIN2 | GPIO_PIN3, GPIO_PRIMARY_MODULE_FUNCTION);
    
    /* P5.4配置为模拟输入模式*/
    GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5,GPIO_PIN5, GPIO_TERTIARY_MODULE_FUNCTION);
    
    /* 使用uartConfig配置UART_A0 */
    MAP_UART_initModule(EUSCI_A0_BASE, &uartConfig);

    /* 使能UART_A0 */
    MAP_UART_enableModule(EUSCI_A0_BASE);

    /* Initializing ADC (MCLK/1/1) */
    ADC14_enableModule();/*使能14位ADC模块*/
    ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_1, ADC_DIVIDER_4,0);
		/*初始化14位ADC模块,选用MCLK时钟源,ADC预分频系数为1,ADC分频系数为4,ADC时钟=MCLK/1/4=1M*/

    ADC14_configureSingleSampleMode(ADC_MEM0, true);
		/*将ADC模块配置为使用单个ADC内存采样转换,内存位置为ADC_MEM0*/
    ADC14_configureConversionMemory(ADC_MEM0, ADC_VREFPOS_AVCC_VREFNEG_VSS,ADC_INPUT_A1, 0);
		/*ADC模块内存位置选用ADC_MEM0,参考电压选择ADC_VREFPOS_AVCC_VREFNEG_VSS,通道选择A1,不选择差分模式*/   
    ADC14_enableSampleTimer(ADC_MANUAL_ITERATION); /*ADC模块采用手动采样模式*/
    ADC14_enableInterrupt(ADC_INT0); /*使能ADC_INT0中断*/
    
    Interrupt_enableInterrupt(INT_ADC14);/*使能INT_ADC14模块中断*/
    Interrupt_enableMaster(); /*使能主中断*/
    
    ADC14_enableConversion(); /*使能ADC模块转换*/   
    ADC14_toggleConversionTrigger(); /*触发ADC模块开始采样*/




  //下面内容为 新增部分
  //*将TimerA0的CCR1、CCR2及CCR3,和P2.0、P2.1及P2.2一一映射,并使能*/
    uint8_t port_mapping[]=
    {
    
    
        PM_TA0CCR1A,  //映射至Timer_A0_CCR1,与Pin0对应
        PM_TA0CCR2A, //映射至Timer_A0_CCR2,与Pin1对应
        PM_TA0CCR3A, //映射至Timer_A0_CCR3,与Pin2对应
        PM_NONE,     //不映射,映射为空
        PM_NONE,
        PM_NONE,
        PM_NONE,
        PM_NONE
    };    
    MAP_PMAP_configurePorts((const uint8_t *)port_mapping,PMAP_P2MAP/*端口2*/,1/*8个引脚*/,PMAP_DISABLE_RECONFIGURATION);
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P2,GPIO_PIN0|GPIO_PIN1|GPIO_PIN2,GPIO_PRIMARY_MODULE_FUNCTION); 
    
    //*TimerA0使用SMCLK作为时钟源,禁用CCR0中断,增计数模式*/
		//TimerA0只用三个通道计数,不中断
    MAP_Timer_A_configureUpMode(TIMER_A0_BASE,&TA0);
    
    //*TimerA1使用SMCLK作为时钟源,启用CCR0中断,定时周期为1s,增计数模式*/
    MAP_Timer_A_configureUpMode(TIMER_A1_BASE,&TA1); 
    
    MAP_Interrupt_enableInterrupt(INT_TA1_0); //*使能TimerA1 CCR0中断*/
    MAP_Interrupt_enableMaster(); //*使能中断总开关*/
     
    MAP_Timer_A_startCounter(TIMER_A0_BASE, TIMER_A_UP_MODE);//*以增计数模式启动TimerA0*/
    MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);//*以增计数模式启动TimerA1*/
    

    while (1)
    {
    
    
		/* 将ADC采集数据以浮点数形式保存至strtmp中 */
        sprintf(strtmp,"$%.3lfv;\n",adcResult*3.3/16384);

        for (i=0;i<strlen(strtmp);i++)
		{
    
    
            MAP_UART_transmitData(EUSCI_A0_BASE, strtmp[i]);	//将strtmp字符串通过UART_A0逐个字符发出
        }
		for(i=200000;i>0;i--);
    }
}

/* 当转换完成并放置到ADC_MEM0时,此中断发生。 */
void ADC14_IRQHandler(void)
{
    
    
    uint64_t status;    
    status = ADC14_getEnabledInterruptStatus();
    ADC14_clearInterruptFlag(status);

    if(status & ADC_INT0)
    {
    
    
        adcResult = ADC14_getResult(ADC_MEM0);  /*将ADC_MEM0中的值赋值给adcResult*/         
        ADC14_toggleConversionTrigger();/*触发ADC模块开始采样*/
    }     
}
void TA1_0_IRQHandler(void)
{
    
    
   
    TA0_CCR1_PWM.compareValue =PWM_PERIODS* adcResult*3.3/16384 / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR1_PWM);  /*使用随机数设置TimerA0 CCR1(连接LED2的红灯)的PWM占空比*/
    TA0_CCR2_PWM.compareValue =PWM_PERIODS* adcResult*3.3/16384 / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR2_PWM);  /*使用随机数设置TimerA0 CCR2(连接LED2的绿灯)的PWM占空比*/
    TA0_CCR3_PWM.compareValue =PWM_PERIODS* adcResult*3.3/16384 / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR3_PWM);  /*使用随机数设置TimerA0 CCR3(连接LED2的蓝灯)的PWM占空比*/

    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);/*清空TimerA1 CCR0中断标志*/
    
  
}

猜你喜欢

转载自blog.csdn.net/JamSlade/article/details/129416480