コード例 #1
0
ファイル: TB6612FNG_2pin.c プロジェクト: bechu/hexapod
static boolean initPWM(const IOPin* pin, uint32_t deciHertz){
	const TimerCompare* channel = compareFromIOPin(pin);

	if(channel==null){
		setError(PWM_PIN_NOT_AVAILABLE);
		return FALSE;
	}
	if(compareIsInUse(channel)){
		setError(PWM_PIN_IN_USE);
		return FALSE;
	}

	TIMER_MODE mode;
	uint16_t icr;
	uint16_t prescaler;

	const Timer* timer = compareGetTimer(channel);

	// Find the best PWM setting for 10kHz, with 128 steps
	boolean valid = timerCalcPwm(timer, deciHertz, 128, &mode, &icr, &prescaler);

	if(!valid){
		// There is no PWM setting that is valid
		setError( (timerIsInUse(timer)) ? PWM_TIMER_IN_USE : TIMER_HAS_NO_PWM );
	}else{
		// Lets set up the PWM
		if(!timerIsInUse(timer)){
			timerSetMode(timer,mode);
			if(modeIsICR(mode)){
				// Set the ICR
				PORT icrPort = pgm_read_word(&timer->pgm_icr);
				_SFR_MEM16(icrPort)=icr;
			}
		}

		// Make it an output pin and set high for brake
		pin_make_output(pin,TRUE);

		// Use inverting PWM
		compareSetOutputMode(channel,CHANNEL_MODE_INVERTING);

		// Mark the channels as in use
		compareAttach(channel,&nullTimerCompareCallback,0,null);

		// Do this last as it then turns on the timer
		timerSetPrescaler(timer,prescaler);
	}
	return valid;
}
コード例 #2
0
ファイル: pwm.c プロジェクト: kenzanin/webbotavrclib-1x
// Set up PWM on the given pin
boolean pwmInitDeciHertz(const IOPin* pin, uint32_t deciHertz, DUTY_CYCLE duty, uint32_t* actualDeciHertz){
	boolean rtn = FALSE;
	const TimerCompare* channel = compareFromIOPin(pin);

	if(channel==null){
		setError(PWM_PIN_NOT_AVAILABLE);
	}else{
		// The pin is valid
		if(compareIsInUse(channel)){
			setError(PWM_PIN_IN_USE);
		}else{
			// The pin is valid and available
			TIMER_MODE mode;
			uint16_t icr;
			uint16_t prescaler;

			const Timer* timer = compareGetTimer(channel);

			// Find the best PWM setting
			boolean valid = timerCalcPwm(timer, deciHertz, 100, &mode, &icr, &prescaler);

			if(!valid){
				// There is no PWM setting that is valid
				setError( (timerIsInUse(timer)) ? PWM_TIMER_IN_USE : TIMER_HAS_NO_PWM );
			}else{
				// Lets set up the PWM
				if(!timerIsInUse(timer)){
					timerSetMode(timer,mode);
					if(modeIsICR(mode)){
						// Set the ICR
						PORT icrPort = pgm_read_word(&timer->pgm_icr);
						_SFR_MEM16(icrPort)=icr;
					}
				}else{
					// Can't change the prescaler so just use the existing
					prescaler = timerGetPrescaler(timer);
				}

				// Mark the channel as in use
				compareAttach(channel,&nullTimerCompareCallback,0,null);

				// Turn the pin into an output, low
				pin_make_output(pin, FALSE);

				// Turn on the PWM pin output
				compareSetOutputMode(channel, CHANNEL_MODE_NON_INVERTING);

				// Turn on the timer
				timerSetPrescaler(timer,prescaler);

				// Set the initial duty cycle
				pwmSetDutyCycle(pin,duty);

				// Set the return value
				if(actualDeciHertz){
					*actualDeciHertz = TimerGetPwmDeciHertz(timer);
				}

				rtn = TRUE;
			}

		}
	}
	return rtn;
}