嵌入式系统实践 08 ——基于ARM汇编 Keil5 MSP432 P401R开发板

lab 8

亮度变化

练习要求

新建交通信号灯keil工程,

设置三个不同的亮度级(0最暗,9最亮),控制LED2亮白色并以这三种亮度循环闪烁,每种亮度保持时间为1秒(比如013,那么分别使用0,1,3三个数字来设置3个不同大小的占空比)。

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

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

#define random(x) (rand()%x)+10

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

static int state = 0;
//TimerA0采用了CCR1,CCR2,CCR3通道,就禁用CCR0和定时器中断
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)
{
    
    
    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_WDT_A_holdTimer();

    //![Simple FPU Config]   
    MAP_FPU_enableModule();//*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/
    MAP_CS_setDCOFrequency(1000000);//* 设置DCO频率为指定频率,此处DCO=1M*/
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);//*设置MCLK(主时钟,可用于CPU主频等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=1M*/
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1); //设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO=1M*/
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_16);//*设置SMCLK(低速子系统主时钟,可用TimerA频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/16=62.5K*/
    //![Simple FPU Config]    
    
    //*将TimerA0的CCR1、CCR2及CCR3,和P2.0、P2.1及P2.2一一映射,并使能*/
    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); //打结
}


unsigned int order = 0;
double light[] = {
    
    1,4,9};

void TA1_0_IRQHandler(void)
{
    
    
   
    order = (order + 1) % 3;
    TA0_CCR1_PWM.compareValue =PWM_PERIODS* light[order] / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR1_PWM);  /*使用随机数设置TimerA0 CCR1(连接LED2的红灯)的PWM占空比*/
    TA0_CCR2_PWM.compareValue =PWM_PERIODS*light[order] / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR2_PWM);  /*使用随机数设置TimerA0 CCR2(连接LED2的绿灯)的PWM占空比*/
    TA0_CCR3_PWM.compareValue =PWM_PERIODS*light[order] / 9;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR3_PWM);  /*使用随机数设置TimerA0 CCR3(连接LED2的蓝灯)的PWM占空比*/
    //pwmConfig(light[order]);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);/*清空TimerA1 CCR0中断标志*/
    

}

呼吸灯

使用定时器选择自己喜欢的颜色实现一个氛围呼吸灯的效果(渐亮渐灭)。

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

/* Standard Includes */
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>

#define random(x) (rand()%x)+10

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

static int state = 0;
//TimerA0采用了CCR1,CCR2,CCR3通道,就禁用CCR0和定时器中断
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)
{
    
    
    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_WDT_A_holdTimer();

    //![Simple FPU Config]   
    MAP_FPU_enableModule();/*启用FPU加快DCO频率计算,注:DCO是内部数字控制振荡器,默认是3M频率*/
    MAP_CS_setDCOFrequency(100000);/* 设置DCO频率为指定频率,此处DCO=1M*/
    MAP_CS_initClockSignal(CS_MCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置MCLK(主时钟,可用于CPU主频等),MCLK=DCO频率/时钟分频系数,此处MCLK=DCO=1M*/
    MAP_CS_initClockSignal(CS_HSMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置HSMCLK(子系统主时钟),HSMCLK=DCO频率/时钟分频系数,此处HSMCLK=DCO=1M*/
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);/*设置SMCLK(低速子系统主时钟,可用TimerA频率),SMCLK=DCO频率/时钟分频系数,此处SMCLK=DCO/16=62.5K*/
    //![Simple FPU Config]    
    
    /*将TimerA0的CCR1、CCR2及CCR3,和P2.0、P2.1及P2.2一一映射,并使能*/
    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); //打结
}

/*
uint32_t breath[] = { CS_CLOCK_DIVIDER_4, CS_CLOCK_DIVIDER_8, 
				CS_CLOCK_DIVIDER_16, CS_CLOCK_DIVIDER_32, CS_CLOCK_DIVIDER_64, CS_CLOCK_DIVIDER_128, CS_CLOCK_DIVIDER_64, CS_CLOCK_DIVIDER_32, CS_CLOCK_DIVIDER_16,
				CS_CLOCK_DIVIDER_8, CS_CLOCK_DIVIDER_4};*/
double light[] = {
    
    0, 2, 4, 6, 8, 10, 8, 6, 4, 2, 0};
unsigned int order = 0;
void mydelay(int cnt)
{
    
    
	int i = cnt * 8000;
	while(i--);
}
void TA1_0_IRQHandler(void)
{
    
    
    order = (order + 1) % 11;
    MAP_CS_initClockSignal(CS_SMCLK, CS_DCOCLK_SELECT, CS_CLOCK_DIVIDER_1);
    MAP_Timer_A_configureUpMode(TIMER_A1_BASE,&TA1); 
    MAP_Timer_A_startCounter(TIMER_A1_BASE, TIMER_A_UP_MODE);

    TA0_CCR1_PWM.compareValue =PWM_PERIODS* light[order] / 20;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR1_PWM);  

    TA0_CCR2_PWM.compareValue =PWM_PERIODS* light[order] / 20;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR2_PWM);  

    TA0_CCR3_PWM.compareValue =PWM_PERIODS* light[order] / 20;
    MAP_Timer_A_initCompare(TIMER_A0_BASE, &TA0_CCR3_PWM);  
    mydelay(light[order]);
    MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_A1_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_0);/*清空TimerA1 CCR0中断标志*/
}

猜你喜欢

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