Beispiel #1
0
/**
 * Automatically called by @ref gprot_register_changed()
 *
 * Implements the logic associated with the application specific flag register.
 */
void gprot_update_flags(void)
{
	if ((gprot_flag_reg & GPROT_FLAG_PWM_COMM) != 0) {
		pwm_comm();
		return;
	}

        if ((gprot_flag_reg & GPROT_FLAG_COMM_TIM) != 0) {
		if ((gprot_flag_reg_old & GPROT_FLAG_COMM_TIM) == 0) {
			control_process_ignite();
		}
	} else {
		if ((gprot_flag_reg_old & GPROT_FLAG_COMM_TIM) != 0) {
			control_process_kill();
		}
	}

	if ((gprot_flag_reg & GPROT_FLAG_ADC_COMM) != 0) {
		demo = true;
	} else {
		if ((gprot_flag_reg_old & GPROT_FLAG_ADC_COMM) != 0) {
			demo = false;
		}
	}

	if ((gprot_flag_reg & GPROT_FLAG_ALL_LO) != 0) {
		pwm_all_lo();
	} else {
		if ((gprot_flag_reg_old & GPROT_FLAG_ALL_LO) != 0) {
			pwm_off();
		}
	}

	if ((gprot_flag_reg & GPROT_FLAG_ALL_HI) != 0) {
		pwm_all_hi();
	} else {
		if ((gprot_flag_reg_old & GPROT_FLAG_ALL_HI) != 0) {
			pwm_off();
		}
	}

	/* add other flags here (up to 16) */

	gprot_flag_reg_old = gprot_flag_reg;
}
Beispiel #2
0
/**
 * Initialize the three phase (6outputs) PWM peripheral and internal state.
 */
void pwm_init(void)
{
	NVIC_InitTypeDef nvic;
	GPIO_InitTypeDef gpio;
	TIM_TimeBaseInitTypeDef tim_base;
	TIM_OCInitTypeDef tim_oc;
	TIM_BDTRInitTypeDef tim_bdtr;

	(void)gpc_setup_reg(GPROT_PWM_OFFSET_REG_ADDR, &pwm_offset);

	/* Enable clock for TIM1 subsystem */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 |
			       RCC_APB2Periph_GPIOA |
			       RCC_APB2Periph_GPIOB, ENABLE);

	/* Enable TIM1 interrupt */
	nvic.NVIC_IRQChannel = TIM1_TRG_COM_IRQn;
	nvic.NVIC_IRQChannelPreemptionPriority = 0;
	nvic.NVIC_IRQChannelSubPriority = 1;
	nvic.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic);

	/* Enable TIM1 interrupt */
	nvic.NVIC_IRQChannel = TIM1_CC_IRQn;
	nvic.NVIC_IRQChannelPreemptionPriority = 0;
	nvic.NVIC_IRQChannelSubPriority = 1;
	nvic.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&nvic);

	/* GPIOA: TIM1 channel 1, 2 and 3 as alternate function
	   push-pull */
	gpio.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
	gpio.GPIO_Mode = GPIO_Mode_AF_PP;
	gpio.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &gpio);

	/* GPIOB: TIM1 channel 1N, 2N and 3N as alternate function
	 * push-pull
	 */
	gpio.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_Init(GPIOB, &gpio);

	/* Time base configuration */
	tim_base.TIM_Period = PWM__BASE_CLOCK / PWM__FREQUENCY;
	tim_base.TIM_Prescaler = 0;
	tim_base.TIM_ClockDivision = 0;
	tim_base.TIM_CounterMode = TIM_CounterMode_Up;
	tim_base.TIM_RepetitionCounter = 0;

	TIM_TimeBaseInit(TIM1, &tim_base);

	/* TIM1 channel 1, 2 and 3 settings */
	tim_oc.TIM_OCMode = TIM_OCMode_Timing;
	tim_oc.TIM_OutputState = TIM_OutputState_Enable;
	tim_oc.TIM_OutputNState = TIM_OutputNState_Enable;
	tim_oc.TIM_Pulse = pwm_val;
	tim_oc.TIM_OCPolarity = TIM_OCPolarity_High;
	tim_oc.TIM_OCNPolarity = TIM_OCNPolarity_High;
	tim_oc.TIM_OCIdleState = TIM_OCIdleState_Set;
	tim_oc.TIM_OCNIdleState = TIM_OCNIdleState_Set;

	TIM_OC1Init(TIM1, &tim_oc);
	TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_OC2Init(TIM1, &tim_oc);
	TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_OC3Init(TIM1, &tim_oc);
	TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);

	/* TIM1 configure channel 4 as adc trigger source */
	tim_oc.TIM_OCMode = TIM_OCMode_PWM2;
	tim_oc.TIM_Pulse = pwm_offset;
	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
	TIM_OC4Init(TIM1, &tim_oc);

	/* Automatic Output enable, break, dead time and lock configuration */
	tim_bdtr.TIM_OSSRState = TIM_OSSRState_Enable;
	tim_bdtr.TIM_OSSIState = TIM_OSSIState_Enable;
	tim_bdtr.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
	tim_bdtr.TIM_DeadTime = 10;
	tim_bdtr.TIM_Break = TIM_Break_Disable;
	tim_bdtr.TIM_BreakPolarity = TIM_BreakPolarity_High;
	tim_bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;

	TIM_BDTRConfig(TIM1, &tim_bdtr);

	TIM_CCPreloadControl(TIM1, ENABLE);

	/* Enable COM and CC interrupt */
	TIM_ITConfig(TIM1, TIM_IT_COM, ENABLE);
	//TIM_ITConfig(TIM1, TIM_IT_COM | TIM_IT_CC4, ENABLE);

	/* TIM1 enable counter */
	TIM_Cmd(TIM1, ENABLE);

	/* Main output enable */
	TIM_CtrlPWMOutputs(TIM1, ENABLE);

	/* Setting default state of pwm to pwm_off */
	pwm_off();
}
int main(void)
{ char key;

   // Map the I/O sections
   setup_io();

   // Set ALL GPIO pins to the required mode
   setup_gpio();

   // Set up PWM module
   setup_pwm();

   // Setup the SPI
   setup_spi();

   // We don't touch the UART for now

   //
   // Here your main program can start
   //
   do {
     printf(" l/L : Walk the LEDS\n");
     printf(" b/B : Show buttons\n");
     printf(" m/M : Control the motor\n");
     printf(" a/A : Read the ADC values\n");
     printf(" c/C : ADC => Motor\n");
     printf("( D : Set  the DAC values\n");
     printf(" q/Q : Quit program\n");
     key = getchar();
     switch (key)
     {
     case 'l':
     case 'L':
         quick_led_demo();
         break;

     case 'b':
     case 'B':
         quick_buttons_demo();
         break;

     case 'm':
     case 'M':
         quick_pwm_demo();
         break;

     case 'a':
     case 'A':
         quick_adc_demo();
         break;

     case 'c':
     case 'C':
         adc_pwm_demo();
         break;

     case 0x0A:
     case 0x0D:
         // ignore CR/LF
         break;

     default:
       printf("???\n");
     }

   } while (key!='q' && key!='Q');

   // make sure everything is off!
   leds_off();
   pwm_off();

   restore_io();

   return 0;
} // main
Beispiel #4
0
/********************************** 函数实现区 *********************************/
void pwm_init(void)
{
    uint32_T pre_scale_val = 0;

    /* 
     *
     * 将计数器时钟设置为:15MHz, 计算预分频值
     * PWM_TIMCLK使用 APB1 的时钟 即 HCLK/2
     *
     * 预分频值:
     *    pre_scale_val = (APB1_CLK / PWM_TIM_CLK ) - 1
     * => pre_scale_val = ((SystemCoreClock / 2 ) /15 MHz) - 1
     *
     */
    pre_scale_val = (uint32_t)((SystemCoreClock/2) / 15000000) - 1; 

    /*
     * 设置周期为:1000 便于编程
     * ARR = (PWM_TIM源时钟/PWM_TIM输出频率) - 1
     * => PWM_TIM输出频率 = PWM_TIM源时钟 / (ARR + 1)
     * ARR = 1000
     * PWM_TIM源时钟:15MHz
     * => PWM_TIM输出频率 = 15000000 / (1000 + 1)
     *   = 14.985 kHz
     *
     * 设置PWM_TIM输出频率为20 KHz, 周期(ARR)为:
     * ARR = (PWM_TIM源时钟/PWM_TIM输出频率) - 1
     * = 749
     * */
     s_period = 1000;

    /* 配置PWM_TIM计数器:
     * Initialize PWM_TIM peripheral as follows:
     * Prescaler = (SystemCoreClock / 2 / 15000000) - 1
     * Period = (750 - 1)
     * ClockDivision = 0
     * Counter direction = Up
     * */
    s_tim_handle.Instance               = PWM_TIM;
    s_tim_handle.Init.Prescaler         = pre_scale_val;
    s_tim_handle.Init.Period            = s_period;
    s_tim_handle.Init.ClockDivision     = 0;
    s_tim_handle.Init.CounterMode       = TIM_COUNTERMODE_UP;
    s_tim_handle.Init.RepetitionCounter = 0;
    if (HAL_TIM_PWM_Init(&s_tim_handle) != HAL_OK)
    { 
        ERR_STR("执行失败.");
    }

    /* 各通道的占空比计算如下:
     * PWM_TIM_Channel1 占空比 = (PWM_TIM_CCR1/ PWM_TIM_ARR + 1)* 100
     * PWM_TIM Channel2 占空比 = (PWM_TIM_CCR2/ PWM_TIM_ARR + 1)* 100
     * PWM_TIM Channel3 占空比 = (PWM_TIM_CCR3/ PWM_TIM_ARR + 1)* 100
     * PWM_TIM Channel4 占空比 = (PWM_TIM_CCR4/ PWM_TIM_ARR + 1)* 100 
     *
     * 初始化的时候占空比全0
     */
    /* 所有通道都需要 */
    s_sConfig.OCMode       = TIM_OCMODE_PWM1;
    s_sConfig.OCPolarity   = TIM_OCPOLARITY_HIGH;
    s_sConfig.OCFastMode   = TIM_OCFAST_DISABLE;
    s_sConfig.OCNPolarity  = TIM_OCNPOLARITY_HIGH;
    s_sConfig.OCNIdleState = TIM_OCNIDLESTATE_RESET;
    s_sConfig.OCIdleState  = TIM_OCIDLESTATE_RESET; 

    /* 测试电机 */
    pwm_test();
    /* 关闭电机 */
    pwm_off();

    return;
}
Beispiel #5
0
/**
 * @brief Handles the given user command
 *
 * This handles the given user command (user_command_t) either by processing
 * it directly, or by passing it over to the actual handler using
 * UserState_HandleUserCommand().
 *
 * g_eepromSaveDelay and g_checkIfAutoOffDelay get reset every time this
 * function is called to make sure the appropriate functionality works as
 * intended.
 *
 * @param user_command The user command that should be handled
 *
 * @see UserState_HandleUserCommand()
 * @see g_eepromSaveDelay
 * @see g_checkIfAutoOffDelay
 */
void handle_user_command(user_command_t user_command)
{

    if (UC_ONOFF == user_command) {

        log_state("OF\n");

        if (user_power_state < UPS_AUTO_OFF) {

            user_power_state = UPS_MANUAL_OFF;
            pwm_off();

        } else {

            if (user_power_state == UPS_MANUAL_OFF) {

                user_power_state = UPS_NORMAL_ON;

            } else {

                user_power_state = UPS_OVERRIDE_ON;

            }

            pwm_on();
            user_setNewTime(NULL);

        }

        preferences_save();

    } else {

        int8_t i;
        bool handled = false;

        for (i = g_topOfStack - 1; i >= 0 && !handled; --i) {

            handled |= UserState_HandleUserCommand(g_stateStack[i], user_command);

        }

        if (!handled) {

            if (UC_BRIGHTNESS_UP == user_command) {

                log_state("B+\n");
                pwm_increase_brightness();

            } else if (UC_BRIGHTNESS_DOWN == user_command) {

                log_state("B-\n");
                pwm_decrease_brightness();

            } else if (UC_NORMAL_MODE == user_command) {

                addSubState(-1, MS_normalMode, (void*)1);

            } else if (UC_SET_TIME == user_command) {

                addState(MS_setSystemTime, NULL);

            } else if (UC_SET_ONOFF_TIMES == user_command) {

                addState(MS_setOnOffTime, NULL);

            } else if (UC_DEMO_MODE == user_command) {

                menu_state_t curTop = user_get_current_menu_state();

                log_state("BS\n");

                if (MS_demoMode == curTop) {

                    quitMyself(MS_demoMode, NULL);

                } else {

                    addState(MS_demoMode, NULL);

                }

            } else if (UC_CALIB_BRIGHTNESS == user_command) {

                pwm_modifyLdrBrightness2pwmStep();

                // Indicate the change to user
                if (pwm_is_enabled()) {

                    pwm_off();
                    _delay_ms(USER_VISUAL_INDICATION_TOGGLE_MS);
                    pwm_on();

                }

            } else if (UC_PULSE_MODE == user_command) {

                menu_state_t curTop = user_get_current_menu_state();

                log_state("PLS\n");

                if (MS_pulse == curTop) {

                    leaveSubState(g_topOfStack - 1);

                } else {

                    if ((MS_normalMode == curTop)
                    #if (ENABLE_RGB_SUPPORT == 1)
                        || (MS_hueMode == curTop)
                    #endif
                    ) {

                        addState(MS_pulse, NULL);

                    }

                }

                DISPLAY_SPECIAL_USER_COMMANDS_HANDLER

                #if (ENABLE_RGB_SUPPORT == 1)

                    } else if (UC_HUE_MODE == user_command) {

                        log_state("HM");

                        addSubState(-1, MS_hueMode, NULL);

                #endif

                #if (ENABLE_DCF_SUPPORT == 1)

                    } else if (UC_DCF_GET_TIME == user_command) {

                        log_state("DCF\n");

                        dcf77_enable();

                #endif

                #if (ENABLE_AMBILIGHT_SUPPORT == 1)

                    } else if (UC_AMBILIGHT == user_command) {

                        log_state("AL\n");

                        PIN(USER_AMBILIGHT) |= _BV(BIT(USER_AMBILIGHT));

                #endif

                #if (ENABLE_BLUETOOTH_SUPPORT == 1)

                    } else if (UC_BLUETOOTH == user_command) {

                        log_state("BT\n");

                        PIN(USER_BLUETOOTH) |= _BV(BIT(USER_BLUETOOTH));

                #endif

                #if (ENABLE_AUXPOWER_SUPPORT == 1)

                    } else if (UC_AUXPOWER == user_command) {

                        log_state("AUX\n");

                        PIN(USER_AUXPOWER) |= _BV(BIT(USER_AUXPOWER));

                #endif

                    } else {

                        return;

                    }

        }