И что дальше? Вы предлагаете писанину обдолбанных индусов возвести в ранг эталона и молиться на нее, как на сокровищницу программистской мысли? Код STM8S_StdPeriph_Lib местами вообще напоминает плоды программы социализации больных с тяжелыми формами аутизма. Типа, пусть они пишут, чего им вздумается, ST Micro выкладывает это в паблик, чтобы у больных создавалось ощущение востребованности плодов их труда. Как либо иначе объяснить всю эту долбанину исключительно сложно.
Любопытства ради, я просмотрел сейчас код в stm8s_tim2 и испытал совершенно непередаваемые ощущения. Позволю себе привести один маленький фрагмент, чтобы не быть голословным:
Код: Выделить всё
FlagStatus TIM2_GetFlagStatus(TIM2_FLAG_TypeDef TIM2_FLAG)
{
FlagStatus bitstatus = RESET;
uint8_t tim2_flag_l = 0, tim2_flag_h = 0;
/* Check the parameters */
assert_param(IS_TIM2_GET_FLAG_OK(TIM2_FLAG));
tim2_flag_l = (uint8_t)(TIM2->SR1 & (uint8_t)TIM2_FLAG);
tim2_flag_h = (uint8_t)((uint16_t)TIM2_FLAG >> 8);
if ((tim2_flag_l | (uint8_t)(TIM2->SR2 & tim2_flag_h)) != (uint8_t)RESET )
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return (FlagStatus)bitstatus;
}
Начинаем разматывать этот бред с конца: функция, возвращающая результат типа
FlagStatus, оператором
Return описывает возврат значения переменной типа
FlagStatus. Вопрос: в какой из самых запущенных стадий находится помутнение рассудка у писавшего сие, если он отдельно описывает приведение переменной типа
FlagStatus к типу
FlagStatus ?
Следующий момент: в секции
else переменной bitstatus присваивается значение
RESET. Смотрим внимательно, могла ли эта переменная иметь другое значение, если известно, что в самой первой строке функции именно это значение ей и присваивалось, а более никаких действий с этой переменной в коде функции не производится? На кой хрен вообще нужна секция
else в таком случае?
Чтобы разобрать загадочные манипуляции с двумя переменными, не хватит ни времени ни страниц форума. Охарактеризую коротко -- это жесточайшая шизофрения, невиданная и непостижимая.
Как говорится, "критикуя, предлагай". Что бы написал я, если бы данный кусок кода поручили придумывать мне. Начну по порядку: тип для отображения статуса таймера я бы объявил так:
Код: Выделить всё
/** TIM2 Flags */
typedef enum
{
TIM2_FLAG_UPDATE = ((uint16_t)(TIM2_SR1_UIF * 256)),
TIM2_FLAG_CC1 = ((uint16_t)(TIM2_SR1_CC1IF * 256)),
TIM2_FLAG_CC2 = ((uint16_t)(TIM2_SR1_CC2IF * 256)),
TIM2_FLAG_CC3 = ((uint16_t)(TIM2_SR1_CC3IF * 256)),
TIM2_FLAG_CC1OF = ((uint16_t)(TIM2_SR2_CC1OF)),
TIM2_FLAG_CC2OF = ((uint16_t)(TIM2_SR2_CC2OF)),
TIM2_FLAG_CC3OF = ((uint16_t)(TIM2_SR2_CC3OF))
}TIM2_FLAG_TypeDef;
Разницу с тем, как это объявлено в STM8S_StdPeriph_Lib у буйнопомешанных индусов, представляет иной порядок размещения флагов. По сути, он обратный: флаги
SR1 лежат в старшем байте, флаги
SR2 в младшем. Вместо волшебных цифр, дифайны из
stm8s.h
Что дает такая "перемена мест слагаемых": если переменную данного типа мысленно наложить на
TIM2_SR1, то члены перечисления точно лягут по флагам того же назначения, как в регистрах
TIM2->SR1 и
TIM2->SR2. Это в свою очередь позволит упростить такие функции, как
TIM2_ClearFlag и
TIM2_GetFlagStatus. Они легко могут быть переписаны в каком-то таком виде:
Код: Выделить всё
void TIM2_ClearFlag(TIM2_FLAG_TypeDef TIM2_FLAG) {
*(uint16_t*)&TIM2->SR1 &= ~(TIM2_FLAG);
}
FlagStatus TIM2_GetFlagStatus(TIM2_FLAG_TypeDef TIM2_FLAG) {
return (*(uint16_t*)&TIM2->SR1 & TIM2_FLAG) ? SET : RESET;
}
Сравните с оригиналом и почувствуйте, что называется, разницу.