ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Воскресенье
22 декабря
427326 Топик полностью
mazur (25.07.2013 05:55 - 06:23, просмотров: 528) ответил Ксения на Можно ли жить на Main Loop, если какая-то периферия требует долгих таймаутов при обмене? Например:
Странно это слышать от вас. Да запросто это сделать в программе Main Loop. Стараюсь писать свои программы без долгих зацикливаний. Потихоньку перетаскиваю этот принцип на си. К примеру ваш пример. С дисплеем. https://www.youtube.com/watch?v=F2SZjORyGD8
Main: wdr rcall Service_Timers rcall Drv_Lcd rcall KBD_DRV rcall Proc_Menu rjmp Main Простой цикл подпрограмм. Что такое Service_Timers? Это обработка программных таймеров, где шаг установки таймера 1 мс (можно взять шаг 10, 100 мс), неточность плюс-минус несколько мкс тут уже абсолютно некритична. Макрос установки Set_Timer, макрос проверки Proc_Timer. В прерывании каждые 1 мс устанавливается флаг SYS_TICK_FLG. В Service_Timers проверяется этот флаг. Сброшен флаг, выход. Установлен флаг, пробежка по всем таймерам, инкремент каждого установленного таймера. Если время вышло, установка флага TIME_OUT_FLG. В подпрограммах, где используются программные таймеры, происходит следующим образом: Взято из старого проекта на асме. Drv_Lcd: sbrc FSM_FLAGS, DRV_LCD_RUN_FLG rjmp DRV_LCD_Run Drv_Lcd_Init: setb FSM_FLAGS, DRV_LCD_RUN_FLG Set_Timer Par_Tim_Drv_Lcd // Установка таймера. Ниже параметры таймера в памяти программ. Drv_Lcd_Run: Proc_Timer Par_Tim_Drv_Lcd // Проверка таймера. brtc Drv_Lcd_Run_End // Если время не вышло, переход на Drv_Lcd_Run_End. sbrs FSM_FLAGS, SEND_CHAR_FLG rjmp DRV_LCD_Send_Addr Drv_Lcd_Send_Char: rjmp Drv_Lcd_Run_End Drv_Lcd_Send_Addr: setb FSM_FLAGS, SEND_CHAR_FLG Drv_Lcd_Run_End: ret //------------------------------------------------------------------- //------------------------------------------------------------------- Par_Tim_Drv_Lcd: par_timer ST_DRV_LCD, 1<<ST_UNLOCK_FLG, DRV_LCD_TIME //=================================================================== Пример на автомате: Proc_FSM_Heater: Proc_FSM Table_FSM_Proc_Heat //------------------------------------------------------------------------ Proc_Heat_Init_1: // Инициализация портов ввода-вывода. cbi RED_LED_PORT, RED_LED sbi RED_LED_DDR, RED_LED cbi GREEN_LED_PORT, GREEN_LED sbi GREEN_LED_DDR, GREEN_LED cbi PLUG_PORT, PLUG sbi PLUG_DDR, PLUG Set_Timer Par_Timer_Proc_Heat_Init Set_State _PROC_HEAT_INIT_2 ret Proc_Heat_Init_2: // Ожидание завершения задержки. Proc_Timer Par_Timer_Proc_Heat_Init brtc Proc_Heat_Init_2_End setb FSM_FLAGS, PROC_HEAT_RUN_FLG // Установка флага, признака, что модуль готов к работе. Set_State _PROC_HEAT_WAIT_ON Proc_Heat_Init_2_End: ret Proc_Heat_Init_Blow_1: // Инициализация режима продувки. rcall Switch_Off_Proc_Heat_Err // Отключение модуля индикации ошибок. rcall Set_Fan_Speed_Blow_1 // Установка скорости вентилятора. plug_on // Включение свечи накаливания. set_fan_on // Установка модуля управления вентилятором на разгон. led_mode_blow // Индикация режима продувки. Set_Timer Par_Timer_Blow_1 ret Proc_Heat_Blow_1: Proc_Timer Par_Timer_Blow_1 brtc Proc_Heat_Blow_1_End Set_State _PROC_HEAT_SET_WAIT_FIRE_SENS Proc_Heat_Blow_1_End: ret Proc_Heat_Set_Wait_Fire_Sens: rcall set_pump_on // Включение модуля насоса. Set_Timer Par_Timer_Fire_Sens Set_State _PROC_HEAT_WAIT_FIRE_SENS ret Как видите, в подпрограммах нет долгих зацикливаний. В том проекте шаг 1 мс. Соответственно, время обработки всех подпрограмм, при любых ветвлениях, в цикле не должно превышать 1 мс. Так что спокойно ставьте задержки хоть "таймаут в один год", и делайте спокойно свои дела в других подпрограммах. Видео-пример по ссылке. Рыскание символа это проверка дисплея при быстрых изменениях на экране.