если в ШИМ нужен максимальный уровень, используется digitalWrite(), чтобы не было просадок еле заметных
This commit is contained in:
parent
1ab5125fc8
commit
cd3e2268c6
@ -104,55 +104,64 @@ It is recommended to enable the timer in the following order:
|
|||||||
*/
|
*/
|
||||||
void analogWrite(uint32_t PinNumber, uint32_t writeVal)
|
void analogWrite(uint32_t PinNumber, uint32_t writeVal)
|
||||||
{
|
{
|
||||||
if (writeVal > WriteValMax) writeVal = WriteValMax;
|
if (writeVal >= WriteValMax)
|
||||||
|
|
||||||
if (digitalPinPwmIsOn(PinNumber) > 0) // pin has pwm and pwm is already on
|
|
||||||
{
|
{
|
||||||
// we can only change writeVal if it is differ from current value
|
// if we need max value, use digitalWrite to supply constant level
|
||||||
TIMER32_TypeDef* timer = pwmPinToTimer(PinNumber);
|
digitalWrite(PinNumber, HIGH);
|
||||||
uint32_t newOCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
}
|
||||||
if (timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR != newOCR)
|
else
|
||||||
|
{
|
||||||
|
// if we need less then max, use pwm
|
||||||
|
int8_t pwmState = digitalPinPwmIsOn(PinNumber);
|
||||||
|
|
||||||
|
if (pwmState > 0) // pin has pwm and pwm is already on
|
||||||
{
|
{
|
||||||
// if new ocr differs from current, set new ocr
|
// we can only change writeVal if it is differ from current value
|
||||||
timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR = newOCR;
|
TIMER32_TypeDef* timer = pwmPinToTimer(PinNumber);
|
||||||
|
uint32_t newOCR = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
||||||
|
if (timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR != newOCR)
|
||||||
|
{
|
||||||
|
// if new ocr differs from current, set new ocr
|
||||||
|
timer->CHANNELS[pwmPinToTimerChannel(PinNumber)].OCR = newOCR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else if (pwmState == 0) // pin has pwm and pwm is off
|
||||||
|
{
|
||||||
|
// init pin as pwm
|
||||||
|
uint32_t OCRval = (pwmTopVal * writeVal) / WriteValMax;
|
||||||
|
|
||||||
|
// initialization of the required timer
|
||||||
|
htimer32.Instance = pwmPinToTimer(PinNumber);
|
||||||
|
htimer32.Top = pwmTopVal;
|
||||||
|
htimer32.State = TIMER32_STATE_DISABLE;
|
||||||
|
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
|
||||||
|
htimer32.Clock.Prescaler = 0; // Prescaler = 1
|
||||||
|
htimer32.InterruptMask = 0;
|
||||||
|
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
|
||||||
|
HAL_Timer32_Init(&htimer32);
|
||||||
|
|
||||||
|
// gpio init as timer channel pin
|
||||||
|
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
|
||||||
|
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||||
|
|
||||||
|
htimer32_channel.TimerInstance = htimer32.Instance;
|
||||||
|
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
||||||
|
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
||||||
|
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
||||||
|
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
||||||
|
htimer32_channel.OCR = OCRval;
|
||||||
|
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
||||||
|
HAL_Timer32_Channel_Init(&htimer32_channel);
|
||||||
|
|
||||||
|
// start timer with initialized channel
|
||||||
|
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
||||||
|
HAL_Timer32_Value_Clear(&htimer32);
|
||||||
|
HAL_Timer32_Start(&htimer32);
|
||||||
|
pwmIsInited++; // increase inited channels qty
|
||||||
|
}
|
||||||
|
else // pin doesn't have pwm
|
||||||
|
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
|
||||||
}
|
}
|
||||||
else if (digitalPinPwmIsOn(PinNumber) == 0) // pin has pwm and pwm is off
|
|
||||||
{
|
|
||||||
// init pin as pwm
|
|
||||||
uint32_t OCRval = (uint32_t) (((uint64_t)pwmTopVal * writeVal) / WriteValMax);
|
|
||||||
|
|
||||||
// initialization of the required timer
|
|
||||||
htimer32.Instance = pwmPinToTimer(PinNumber);
|
|
||||||
htimer32.Top = pwmTopVal;
|
|
||||||
htimer32.State = TIMER32_STATE_DISABLE;
|
|
||||||
htimer32.Clock.Source = TIMER32_SOURCE_PRESCALER;
|
|
||||||
htimer32.Clock.Prescaler = 0; // Prescaler = 1
|
|
||||||
htimer32.InterruptMask = 0;
|
|
||||||
htimer32.CountMode = TIMER32_COUNTMODE_FORWARD;
|
|
||||||
HAL_Timer32_Init(&htimer32);
|
|
||||||
|
|
||||||
// gpio init as timer channel pin
|
|
||||||
HAL_GPIO_PinConfig(digitalPinToPort(PinNumber), digitalPinToBitMask(PinNumber),
|
|
||||||
HAL_GPIO_MODE_TIMER_SERIAL, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
|
||||||
|
|
||||||
htimer32_channel.TimerInstance = htimer32.Instance;
|
|
||||||
htimer32_channel.ChannelIndex = pwmPinToTimerChannel(PinNumber);
|
|
||||||
htimer32_channel.PWM_Invert = TIMER32_CHANNEL_NON_INVERTED_PWM;
|
|
||||||
htimer32_channel.Mode = TIMER32_CHANNEL_MODE_PWM;
|
|
||||||
htimer32_channel.CaptureEdge = TIMER32_CHANNEL_CAPTUREEDGE_RISING;
|
|
||||||
htimer32_channel.OCR = OCRval;
|
|
||||||
htimer32_channel.Noise = TIMER32_CHANNEL_FILTER_OFF;
|
|
||||||
HAL_Timer32_Channel_Init(&htimer32_channel);
|
|
||||||
|
|
||||||
// start timer with initialized channel
|
|
||||||
HAL_Timer32_Channel_Enable(&htimer32_channel);
|
|
||||||
HAL_Timer32_Value_Clear(&htimer32);
|
|
||||||
HAL_Timer32_Start(&htimer32);
|
|
||||||
pwmIsInited++; // increase inited channels qty
|
|
||||||
}
|
|
||||||
else // pin doesn't have pwm
|
|
||||||
ErrorMsgHandler("analogWrite(): invalid pwm pin number");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the resolution of analogWrite parameters
|
// Set the resolution of analogWrite parameters
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user