ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
22 ноября
331676 Топик полностью
MegaJohn (29.05.2012 18:15, просмотров: 136) ответил Bill на А по-моему это Си и без вставок может делать.
все очень хитро: есть два дефайна #define WATCHDOG_DISABLE { __watchdog_reset(); MCU_REG &= ~(1 << WDRF); WDT_REG |= (1 << WDCE) | (1 << WDE); WDT_REG = 0; } #define WATCHDOG_EN_250MS { __watchdog_reset(); MCU_REG &= ~(1 << WDRF); WDT_REG |= (1 << WDCE) | (1 << WDE); WDT_REG = (1 << WDP2) | (1 << WDE); } если в проекте юзается только один из них, то все нормально, но когда два, то получается, что оптимизатор "начала" сделал общие, а "конец" разными и после записи WDCE появляются лишние JMP, что в итоге анулирует весь смысл. Тогда на телесисах, обсуждения привели к виду: typedef enum { wd_disable = 255, wd_16ms = 0, wd_32ms = (1 << WDP0), wd_64ms = (1 << WDP1) , wd_125ms = (1 << WDP1) | (1 << WDP0), wd_250ms = (1 << WDP2) , wd_500ms = (1 << WDP2) | (1 << WDP0), wd_1sec = (1 << WDP2) | (1 << WDP1) , wd_2sec = (1 << WDP2) | (1 << WDP1) | (1 << WDP0), #ifdef WDP3 wd_4sec = (1 << WDP3) , wd_8sec = (1 << WDP3) | (1 << WDP0), #endif }Ewd_modes; void watchdog_cmd( Ewd_modes in_mode ) { INTERRUPT_PUSH_AND_CLR; WATCHDOG_RESET; u8 temp = WDT_REG | (1 << WDCE) | (1 << WDE); switch( in_mode ) { case wd_disable: MCU_REG &= ~(1 << WDRF); WDT_REG = temp; WDT_REG = 0; break; default: // временные переменные не дают оптимизатору вольностей, а при конфигурировании ватчдога это нужно успеть в четрые такта после записи бита WDCE #ifdef WDP3 u8 t2 = ( WDT_REG & ~( (1 << WDP3) | (1 << WDP2) | (1 << WDP1) | (1 << WDP0) ) ) | (1 << WDE) | (u8)in_mode; #else u8 t2 = ( WDT_REG & ~( (1 << WDP2) | (1 << WDP1) | (1 << WDP0) ) ) | (1 << WDE) | (u8)in_mode; #endif WDT_REG = temp; WDT_REG = t2; break; } INTERRUPT_POP; } Но смотрю в дизасме, и вычисления t2 происходят как раз между WDT_REG = temp; и WDT_REG = t2; !!! Заколебался подстаиватся под оптимизатор, напишу на асме, он в этом случае более надежен !