/**@brief Thread for handling the Application's BLE Stack events. * * @details This thread is responsible for handling BLE Stack events sent from on_ble_evt(). * * @param[in] arg Pointer used for passing some arbitrary information (context) from the * osThreadCreate() call to the thread. */ void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } }
static void ecg_2_lead_gui_tick(state_ptr state) { uint32_t i = 0; osEvent event; uint32_t bpm = 0; char str_bpm[4] = "-?-"; int32_t lead_I = 0, lead_II = 0; /* Do transition actions */ /* Get bpm data */ event = osMessageGet(queue_ecg_bpm_screenHandle, 0); if (event.status == osEventMessage) { /* Retrieve value */ bpm = (((uint32_t) event.value.v) >> 10); sprintf(str_bpm, "%u", bpm); item_area_set_text(&menu_ecg.items[1].item.area, str_bpm); while (osMailPut(queue_lcdHandle, (void *) &menu_ecg.items[1]) != osOK) { osDelay(1); } }
/** * @brief Storage Thread * @param argument: pointer that is passed to the thread function as start argument. * @retval None */ static void StorageThread(void const * argument) { osEvent event; for( ;; ) { event = osMessageGet( StorageEvent, osWaitForever ); if( event.status == osEventMessage ) { switch(event.value.v) { case USBDISK_CONNECTION_EVENT: f_mount(&USBDISK_FatFs,USBDISK_Drive, 0); StorageStatus[USB_DISK_UNIT] = 1; break; case USBDISK_DISCONNECTION_EVENT: f_mount(0, USBDISK_Drive, 0); StorageStatus[USB_DISK_UNIT] = 0; break; } } } }
// Handle command event processing. void commandProcessingThread(void const *argument) { UINT8 currentIndex; for (;;) { // Wait for a command message. osEvent commandEvent = osMessageGet(commandQueue, osWaitForever); // Is this a command event? if (commandEvent.status == osEventMessage) { // Point to the message. commandMessage *message = (commandMessage *) commandEvent.value.p; // Execute all the commands currentIndex = 0; while (currentIndex < message->length) { currentIndex += handleCommand(message, currentIndex); } // Free the message. osPoolFree(commandMemPool, message); } } }
/** * @brief Message Queue Consumer Thread. * @param argument: Not used * @retval None */ static void MessageQueueConsumer (const void *argument) { osEvent event; for(;;) { /* Get the message from the queue */ event = osMessageGet(osQueue, 100); if(event.status == osEventMessage) { if(event.value.v != ConsumerValue) { /* Catch-up. */ ConsumerValue = event.value.v; /* Toggle LED3 to indicate error */ BSP_LED_Toggle(LED3); } else { /* Increment the value we expect to remove from the queue next time round. */ ++ConsumerValue; } } } }
/*---------------------------------------------------------------------------* * Routine: sys_arch_mbox_tryfetch *---------------------------------------------------------------------------* * Description: * Similar to sys_arch_mbox_fetch, but if message is not ready * immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is * returned. * Inputs: * sys_mbox_t mbox -- Handle of mailbox * void **msg -- Pointer to pointer to msg received * Outputs: * u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise, * return ERR_OK. *---------------------------------------------------------------------------*/ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { osEvent event = osMessageGet(mbox->id, 0); if (event.status != osEventMessage) return SYS_MBOX_EMPTY; *msg = (void *)event.value.v; return ERR_OK; }
void MainTask() { for(;;) { // Wait for adc result and write it to the UART connected to the PC. osEvent result = osMessageGet(mainTaskMessageQId, osWaitForever); HAL_UART_Transmit(&huart2, (uint8_t*)&result.value.v, 4, 100); } }
/** * @brief Audio task * @param argument: pointer that is passed to the thread function as start argument. * @retval None */ static void Audio_Thread(void const * argument) { uint32_t numOfReadBytes; osEvent event; for(;;) { event = osMessageGet(AudioEvent, 100 ); if( event.status == osEventMessage ) { if(haudio.state == AUDIOPLAYER_PLAY) { switch(event.value.v) { case BUFFER_OFFSET_HALF: if(f_read(&wav_file, &haudio.buffer[0], AUDIO_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { haudio.state = AUDIOPLAYER_EOF; } } else { haudio.state = AUDIOPLAYER_ERROR; } break; case BUFFER_OFFSET_FULL: if(f_read(&wav_file, &haudio.buffer[AUDIO_BUFFER_SIZE/2], AUDIO_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { haudio.state = AUDIOPLAYER_EOF; } } else { haudio.state = AUDIOPLAYER_ERROR; } break; default: break; } } } } }
/**@brief Thread for handling the Application's BLE Stack events. * * @details This thread is responsible for handling BLE Stack events sended from on_ble_evt(). * * @param[in] arg Pointer used for passing some arbitrary information (context) from the * osThreadCreate() call to the thread. */ void ble_stack_thread(void const * arg) { uint32_t err_code; osEvent evt; ble_evt_t * p_ble_evt; UNUSED_PARAMETER(arg); while (1) { evt = osMessageGet(ble_stack_msg_box, osWaitForever); // wait for message if (evt.status == osEventMessage) { p_ble_evt = evt.value.p; switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); APP_ERROR_CHECK(err_code); m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; break; case BLE_GAP_EVT_DISCONNECTED: err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); advertising_start(); break; case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { err_code = bsp_indication_set(BSP_INDICATE_IDLE); APP_ERROR_CHECK(err_code); // enable buttons to wake-up from power off bsp_buttons_enable( (1 << WAKEUP_BUTTON_ID) | (1 << BOND_DELETE_ALL_BUTTON_ID) ); // Go to system-off mode (this function will not return; wakeup will cause a reset). err_code = sd_power_system_off(); APP_ERROR_CHECK(err_code); } break; default: // No implementation needed. break; } (void)osPoolFree(ble_evt_pool, p_ble_evt); } } }
/*---------------------------------------------------------------------------* * Routine: sys_arch_mbox_fetch *---------------------------------------------------------------------------* * Description: * Blocks the thread until a message arrives in the mailbox, but does * not block the thread longer than "timeout" milliseconds (similar to * the sys_arch_sem_wait() function). The "msg" argument is a result * parameter that is set by the function (i.e., by doing "*msg = * ptr"). The "msg" parameter maybe NULL to indicate that the message * should be dropped. * * The return values are the same as for the sys_arch_sem_wait() function: * Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a * timeout. * * Note that a function with a similar name, sys_mbox_fetch(), is * implemented by lwIP. * Inputs: * sys_mbox_t mbox -- Handle of mailbox * void **msg -- Pointer to pointer to msg received * u32_t timeout -- Number of milliseconds until timeout * Outputs: * u32_t -- SYS_ARCH_TIMEOUT if timeout, else number * of milliseconds until received. *---------------------------------------------------------------------------*/ u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { u32_t start = us_ticker_read(); osEvent event = osMessageGet(mbox->id, (timeout != 0)?(timeout):(osWaitForever)); if (event.status != osEventMessage) return SYS_ARCH_TIMEOUT; *msg = (void *)event.value.v; return (us_ticker_read() - start) / 1000; }
// Receive the 'data' in the Message 'queue'. Returns 1 if a message was received, 0 otherwise. int receive_message(float * data, osMessageQId queue){ osEvent evt = osMessageGet(queue, 0); if (evt.status == osEventMessage) { Message* msg = ((Message *)evt.value.p); *data = msg->data; osPoolFree(mem_pool, msg); return 1; } return 0; }
void blinkThread(void const *argument) { uint16_t delay = 500; /* Default delay */ osEvent evt; while(1) { evt = osMessageGet(MsgBox, 1); if(evt.status == osEventMessage) delay = evt.value.v; HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin); osDelay(delay); } }
static void demo_task1(void *arg) { osEvent event; while (1) { event = osMessageGet(p_msgqueue, osWaitForever); if (event.status == osEventMessage) { printf("demo_task1 get msg %d\n", event.value.v); } else { printf("demo_task1 get msg failed\n"); } }; }
/** * @brief USB Host Thread task * @param pvParameters not used * @retval None */ static void USBH_Process_OS(void const * argument) { osEvent event; for(;;) { event = osMessageGet(((USBH_HandleTypeDef *)argument)->os_event, osWaitForever ); if( event.status == osEventMessage ) { USBH_Process((USBH_HandleTypeDef *)argument); } } }
/// Get a mail from a queue osEvent osMailGet(osMailQId queue_id, uint32_t millisec) { osEvent ret; if (queue_id == NULL) { ret.status = osErrorParameter; return ret; } ret = osMessageGet(*((void **)queue_id), millisec); if (ret.status == osEventMessage) ret.status = osEventMail; return ret; }
/** * @brief USBH_TEMPLATE_Init * The function Initialize the TEMPLATE function * @param phost: Host handle * @retval USBH Status */ USBH_StatusTypeDef USBH_TEMPLATE_Init (USBH_HandleTypeDef *phost) { USBH_StatusTypeDef Status = USBH_BUSY; #if (USBH_USE_OS == 1) osEvent event; event = osMessageGet( phost->class_ready_event, osWaitForever ); if( event.status == osEventMessage ) { if(event.value.v == USBH_CLASS_EVENT) { #else while ((Status == USBH_BUSY) || (Status == USBH_FAIL)) { /* Host background process */ USBH_Process(phost); if(phost->gState == HOST_CLASS) { #endif Status = USBH_OK; } } return Status; } /** * @brief USBH_TEMPLATE_IOProcess * TEMPLATE TEMPLATE process * @param phost: Host handle * @retval USBH Status */ USBH_StatusTypeDef USBH_TEMPLATE_IOProcess (USBH_HandleTypeDef *phost) { if (phost->device.is_connected == 1) { if(phost->gState == HOST_CLASS) { USBH_TEMPLATE_Process(phost); } } return USBH_OK; }
/*---------------------------------------------------------------------------- * Thread 2: Receive thread *---------------------------------------------------------------------------*/ void recv_thread (void const *argument) { T_MEAS *rptr; osEvent evt; for (;;) { evt = osMessageGet(MsgBox, osWaitForever); /* wait for message */ if (evt.status == osEventMessage) { rptr = evt.value.p; printf ("\nVoltage: %.2f V\n",rptr->voltage); printf ("Current: %.2f A\n",rptr->current); printf ("Number of cycles: %d\n",(int)rptr->counter); #ifdef __USE_FFLUSH fflush (stdout); #endif osPoolFree(mpool,rptr); /* free memory allocated for message */ } } }
/**************************************************************************//** * @brief * Thread 1: Print LCD thread - modified to not use LCD *****************************************************************************/ void PrintLcdThread(void const *argument) { lcdText_t *rptr; osEvent evt; (void) argument; /* Unused parameter. */ while (1) { /* Wait for message */ evt = osMessageGet(msgBox, osWaitForever); if (evt.status == osEventMessage) { rptr = evt.value.p; /* Free memory allocated for message */ osPoolFree(mpool, rptr); } } }
/** * @brief Start task * @param pvParameters not used * @retval None */ static void StartThread(void const * argument) { osEvent event; /* Init MSC Application */ MSC_InitApplication(); /* Init Host Library */ USBH_Init(&hUSBHost, USBH_UserProcess, 0); /* Add Supported Class */ USBH_RegisterClass(&hUSBHost, USBH_MSC_CLASS); /* Start Host Process */ USBH_Start(&hUSBHost); /* Register the file system object to the FatFs module */ if(f_mount(&USBH_fatfs, "", 0) != FR_OK) { LCD_ErrLog("ERROR : Cannot Initialize FatFs! \n"); } for( ;; ) { event = osMessageGet(AppliEvent, osWaitForever); if(event.status == osEventMessage) { switch(event.value.v) { case APPLICATION_DISCONNECT: Appli_state = APPLICATION_DISCONNECT; osSemaphoreRelease(MenuEvent); break; case APPLICATION_READY: Appli_state = APPLICATION_READY; default: break; } } } }
static void LogCollector_Process_OS(void const * argument) { osEvent event; for(;;) { event = osMessageGet(((EventLogger_Handle_TypeDef *)argument)->os_event, osWaitForever ); //if(((EventLogger_Handle_TypeDef *)argument)-> LogStatus == LOG_BUFFER_FULL) if( event.status == osEventMessage ) { ((EventLogger_Handle_TypeDef *)argument)->pLogData = &Log_List[event.value.v]; ((EventLogger_Handle_TypeDef*) argument)->Interface->WriteLog((EventLogger_Handle_TypeDef*) argument); ((EventLogger_Handle_TypeDef *)argument)->pLogData = 0; LogIndex_List[event.value.v] = 0; } //osDelay(0); } }
/** * @brief Message Queue Consumer Thread. * @param argument: Not used * @retval None */ static void QueueReceiveThread (const void *argument) { osEvent event; for(;;) { /* Wait until something arrives in the queue. */ event = osMessageGet(osQueue, osWaitForever); /* To get here something must have arrived, but is it the expected value? If it is, turn the LED on for a short while. */ if(event.status == osEventMessage) { if(event.value.v == QUEUED_VALUE) { BSP_LED_On(LED1); osDelay(LED_TOGGLE_DELAY); BSP_LED_Off(LED1); } } } }
/** * @brief Start task * @param pvParameters not used * @retval None */ static void StartThread(void const *argument) { osEvent event; /* Link the USB Host disk I/O driver */ if(FATFS_LinkDriver(&USBH_Driver, USBDISKPath) == 0) { /* Init Host Library */ USBH_Init(&hUSB_Host, USBH_UserProcess, 0); /* Add Supported Class */ USBH_RegisterClass(&hUSB_Host, USBH_MSC_CLASS); /* Start Host Process */ USBH_Start(&hUSB_Host); for( ;; ) { event = osMessageGet(AppliEvent, osWaitForever); if(event.status == osEventMessage) { switch(event.value.v) { case CONNECTION_EVENT: MSC_Application(); break; case DISCONNECTION_EVENT: f_mount(NULL, (TCHAR const*)"", 0); break; default: break; } } } } }
/** * @brief Wait for a generic message in the queue and copy out the generic message upon arrival * @param msgQ: Message Q to send the message to * @param *messagePtr: Pointer to a generic message struct * @param timeout: How long the operating system must wait until the message is successfully placed in message Q msgQ */ void fetchMessage(osMessageQId msgQ, msg_genericMessage_t *messagePtr, uint32_t timeout) { osEvent messageEvent; msg_genericMessage_t *messageRxPtr; // Wait for a message in the message Q, msgQ messageEvent = osMessageGet(msgQ, timeout); // If the recieved data is a message if (messageEvent.status == osEventMessage) { // Grab the pointer to the generic message and copy it into the externally declared message struct messageRxPtr = messageEvent.value.p; memcpy(messagePtr, messageRxPtr, sizeof(msg_genericMessage_t)); // Then free the message from the global memory pool osPoolFree(genericMPool, messageRxPtr); } else { // If there was no message received after the timeout value, set the type to NULL to indicate this messagePtr->messageType = MSG_TYPE_NO_MESSAGE; } }
/** * @brief Start task * @param pvParameters not used * @retval None */ static void StartThread(void const * argument) { osEvent event; /* Init HID Application */ HID_InitApplication(); /* Start Host Library */ USBH_Init(&hUSBHost, USBH_UserProcess, 0); /* Add Supported Class */ USBH_RegisterClass(&hUSBHost, USBH_HID_CLASS); /* Start Host Process */ USBH_Start(&hUSBHost); for( ;; ) { event = osMessageGet( AppliEvent, osWaitForever ); if( event.status == osEventMessage ) { switch(event.value.v) { case APPLICATION_DISCONNECT: Appli_state = APPLICATION_DISCONNECT; HID_UpdateMenu(); break; case APPLICATION_READY: Appli_state = APPLICATION_READY; default: break; } } } }
/** * @brief Audio task * @param argument: pointer that is passed to the thread function as start argument. * @retval None */ static void Audio_Thread(void const * argument) { uint32_t numOfReadBytes; osEvent event; for(;;) { event = osMessageGet(AudioEvent, 100 ); if( event.status == osEventMessage ) { if(haudio.out.state == AUDIOPLAYER_PLAY) { switch(event.value.v) { case PLAY_BUFFER_OFFSET_HALF: if(f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { haudio.out.state = AUDIOPLAYER_EOF; } #if (!defined ( __GNUC__ )) SpiritEQ_Apply((void *)AUDIO_EqInstance, /* NB_Channel */2, (int16_t *)&haudio.buff[0], numOfReadBytes / 4); /* Apply Loudness settings */ SpiritLdCtrl_Apply((TSpiritLdCtrl *)AUDIO_LdCtrlPersistance, /* NB_Channel */ 2, (int16_t *)&haudio.buff[0], numOfReadBytes / 4, (void *)AUDIO_LdCtrlScratch); #endif } else { haudio.out.state = AUDIOPLAYER_ERROR; } break; case PLAY_BUFFER_OFFSET_FULL: if(f_read(&wav_file, &haudio.buff[AUDIO_OUT_BUFFER_SIZE/2], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { haudio.out.state = AUDIOPLAYER_EOF; } #if (!defined ( __GNUC__ )) SpiritEQ_Apply((void *)AUDIO_EqInstance, /* NB_Channel */2, (int16_t *)&haudio.buff[AUDIO_OUT_BUFFER_SIZE /2], numOfReadBytes / 4); /* Apply Loudness settings */ SpiritLdCtrl_Apply((TSpiritLdCtrl *)AUDIO_LdCtrlPersistance, /* NB_Channel */ 2, (int16_t *)&haudio.buff[AUDIO_OUT_BUFFER_SIZE /2], numOfReadBytes / 4, (void *)AUDIO_LdCtrlScratch); #endif } else { haudio.out.state = AUDIOPLAYER_ERROR; } break; default: break; } } } } }
/** * @brief Concurrent task * @param pvParameters not used * @retval None */ static void ConcurrentThread(void const *argument) { osEvent event; FRESULT res; /* FatFs function common result code */ uint16_t byteswritten; /* File write count */ uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */ for( ;; ) { event = osMessageGet(DiskEvent, osWaitForever); if(event.status == osEventMessage) { switch(event.value.v) { case DISK_READY_EVENT: /* Create and Open a new text file object with write access */ if(f_open(&MyFile2, "STM32_2.TXT", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) { /* 'STM32_2.TXT' file Open for write Error */ Error_Handler(); } else { /* Write data to the text file */ res = f_write(&MyFile2, wtext, sizeof(wtext), (void *)&byteswritten); if((byteswritten == 0) || (res != FR_OK)) { /* 'STM32_2.TXT' file Write or EOF Error */ Error_Handler(); } else { /* Close the open text file */ f_close(&MyFile2); /* If last access to Disk, unlink drive */ if(disk_op == 1) { osMessagePut(DiskEvent, DISK_REMOVE_EVENT, 0); } disk_op = 2; /* Success of the demo: no error occurrence */ BSP_LED_On(LED4); } } break; case DISK_REMOVE_EVENT: /* Unlink the USB disk I/O driver */ FATFS_UnLinkDriver(USBDISKPath); break; default: break; } } } }
/*---------------------------------------------------------------------------* * Routine: sys_mbox_free *---------------------------------------------------------------------------* * Description: * Deallocates a mailbox. If there are messages still present in the * mailbox when the mailbox is deallocated, it is an indication of a * programming error in lwIP and the developer should be notified. * Inputs: * sys_mbox_t *mbox -- Handle of mailbox *---------------------------------------------------------------------------*/ void sys_mbox_free(sys_mbox_t *mbox) { osEvent event = osMessageGet(mbox->id, 0); if (event.status == osEventMessage) error("sys_mbox_free error\n"); }
/** * @brief Audio task * @param argument: pointer that is passed to the thread function as start argument. * @retval None */ static void Audio_Thread(void const * argument) { uint32_t numOfReadBytes, numOfWrittenBytes; osEvent event; for(;;) { event = osMessageGet(AudioEvent, 100 ); if( event.status == osEventMessage ) { if(haudio.in.state == AUDIO_RECORDER_PLAYING) { switch(event.value.v) { case PLAY_BUFFER_OFFSET_HALF: if(f_read(&wav_file, &haudio.buff[0], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { AUDIO_RECORDER_StopPlayer(); } } else { AUDIO_RECORDER_StopPlayer(); } break; case PLAY_BUFFER_OFFSET_FULL: if(f_read(&wav_file, &haudio.buff[AUDIO_OUT_BUFFER_SIZE/2], AUDIO_OUT_BUFFER_SIZE/2, (void *)&numOfReadBytes) == FR_OK) { if(numOfReadBytes == 0) { AUDIO_RECORDER_StopPlayer(); } } else { AUDIO_RECORDER_StopPlayer(); } break; default: break; } } /* Recording .... */ if(haudio.in.state == AUDIO_RECORDER_RECORDING) { switch(event.value.v) { case REC_BUFFER_OFFSET_HALF: if(f_write(&wav_file, (uint8_t*)(haudio.buff), AUDIO_IN_BUFFER_SIZE/2, (void*)&numOfWrittenBytes) == FR_OK) { if(numOfWrittenBytes == 0) { AUDIO_RECORDER_StopRec(); } } else { AUDIO_RECORDER_StopRec(); } haudio.in.fptr += numOfWrittenBytes; break; case REC_BUFFER_OFFSET_FULL: if(f_write(&wav_file, (uint8_t*)(haudio.buff + AUDIO_IN_BUFFER_SIZE/2), AUDIO_IN_BUFFER_SIZE/2, (void*)&numOfWrittenBytes) == FR_OK) { if(numOfWrittenBytes == 0) { AUDIO_RECORDER_StopRec(); } } else { AUDIO_RECORDER_StopRec(); } haudio.in.fptr += numOfWrittenBytes; break; default: break; } } } } }
/* 过零点触发中断 回调函数 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin != ZERO) return; bool wave_is_rise; // 读Pin,判断是上升沿还是下降沿 if (HAL_GPIO_ReadPin(PORT_ZERO, ZERO) == GPIO_PIN_RESET) { wave_is_rise = true; } else { wave_is_rise = false; } // t 顺序: 1 3 4 6 // 上升沿 if (wave_is_rise) { t4 = __HAL_TIM_GET_COUNTER(&htim3); // 上升沿是否valid? // if (!it_is_valid(t4_prev, t4)) { // t4_prev = t4; // r++; // return; // } //r++; } else { // 下降沿 t6 = __HAL_TIM_GET_COUNTER(&htim3); // 下降沿是否valid? // if (!it_is_valid(t6_prev, t6)) { // t6_prev = t6; // f++; // return; // } //f++; } if (wave_is_rise) // 只在波谷计算,否则退出 return; is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; /* 下降沿时计算下一个零点 */ // t2 if (t3 < t1) t2 = (0xffff + t1 + t3) / 2; else t2 = (t1 + t3) / 2; // t5 if (t6 < t4) t5 = (0xffff + t4 + t6) / 2; else t5 = (t4 + t6) / 2; // 交流电源周期 if (t5 < t2) T1 = 0xffff + t5 - t2; else T1 = t5 - t2; // 下一个零点 if (t5 < t4) t7 = t5 + 0xffff - t4 + (T1 / 4); /* 计算不对 ! */ else t7 = t5 - t4 + (T1 / 4); // counter++; // if (counter >=299) { // //printf("t4:%d,t5:%d,t6:%d,t7:%d,T1:%d\r\n", t4,t5,t6,t7,T1); // printf("delay:%d\r\n", t7 + TOTAL_TIME - triac_cur.fan_smoke_delay * 100); // counter = 0; // } // 更新数值 t1 = t4; t2 = t5; t3 = t6; // 计数器复位 __HAL_TIM_SET_COUNTER (&htim1, 0); __HAL_TIM_SET_COUNTER (&htim4, 0); // 检查Q_Triac队列,更新输出的控制状态 if (Q_TriacHandle != NULL) { // 读取值 osEvent evt = osMessageGet(Q_TriacHandle, 0); if (evt.status == osEventMessage) { triac_cur = *((Triac *)evt.value.p); // 更新送料duty on_count = triac_cur.feed_duty * 100; off_count = 1000 - on_count; // 10s = 10000ms 10000 / 10 = 1000 // 返还内存 osStatus status = osPoolFree(pool_TriacHandle, evt.value.p); if (status != osOK) printf("Free Triac memory error:%x\r\n", status); } } // 设置period __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, t7 + TOTAL_TIME - triac_cur.fan_smoke_delay * 100); // 80÷100×10×1000 = 80×100 __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, t7 + TOTAL_TIME - triac_cur.fan_exchange_delay * 100); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, t7); /* 输出: 条件判断 */ HAL_StatusTypeDef status; //排烟通道 if (triac_cur.fan_smoke_is_on) { status = HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_1); if (status != HAL_OK) printf("time4 c1 failed at zero:%x\r\n", status); } //循环通道 if (triac_cur.fan_exchange_is_on) { status = HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_2); if (status != HAL_OK) printf("time4 c2 failed:%x\r\n", status); } //送料通道 ON计数 OFF计数 if (triac_cur.feed_is_on) { // 送料 if (running_feed) { if (on_cnt < on_count) { // 输出 送料: On HAL_TIM_OC_Start_IT(&htim4, TIM_CHANNEL_3); on_cnt++; } else { on_cnt = 0; off_cnt = 0; running_feed = false; waiting_feed = true; } } // 不送料 if (waiting_feed) { off_cnt ++; if (off_cnt >= off_count) { on_cnt = 0; off_cnt = 0; running_feed = true; waiting_feed = false; } } } // }
/* 过零点触发中断 回调函数 */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin != ZERO) return; bool rising_edge; // 读Pin,判断是上升沿还是下降沿 if (HAL_GPIO_ReadPin(PORT_ZERO, ZERO) == GPIO_PIN_SET) { rising_edge = true; } else { rising_edge = false; } // t 顺序: 1 3 4 6 // 上升沿 if (rising_edge) { t6 = __HAL_TIM_GET_COUNTER(&htim3); } else { // 下降沿 t4 = __HAL_TIM_GET_COUNTER(&htim3); } if (!rising_edge) // 只在波谷计算,否则退出 return; /*----------------------------------------------------------------------------*/ is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; /* 下降沿时计算下一个零点 */ // t1 t3 t4 t6 if ((t1<t3) && (t3<t4) && (t4<t6)) { t2 = (t1+t3) / 2; t5 = (t4+t6) / 2; } else if(t3<t1) { t2 = (t1+t3+0xffff) / 2; t5 = (t4+t6)/2 + 0xffff; } else if(t4<t3) { t2 = (t1+t3) / 2; t5 = (t4+t6)/2 + 0xffff; } else if(t6<t4) { t2 = (t1+t3) / 2; t5 = (t4+t6+0xffff) / 2; } T1 = t5 - t2; // 下一个零点 if (t6<t5) { t7 = t5 + T1/4 - t6 -0xffff; } else { t7 = t5 + T1/4 - t6; } // debug // counter++; // if (counter >= 149) { // Zero *z; // z = (Zero*)osPoolAlloc(pool_ZeroHandle); // if (z!=NULL) { // z->t1 = t1; // z->t3 = t3; // z->t4 = t4; // z->t6 = t6; // z->t7 = t7; // z->T1 = T1; // osMessagePut(Q_ErrorHandle, (uint32_t)z, 0); // } // // counter = 0; // } // // 更新数值 t1 = t4; t3 = t6; /*--------------------------------------------------------------------------*/ // 只处理下半波 if (t7 == 0) { t7 = 220; } is_lower_blow = true; // 设置波谷flag is_lower_exchange = true; is_lower_feed = true; //uint32_t compare = 0; // 检查Q_Triac队列,更新输出的控制状态 if (Q_TriacHandle != NULL) { // 读取值 osEvent evt = osMessageGet(Q_TriacHandle, 0); if (evt.status == osEventMessage) { Triac *p = (Triac *)evt.value.p; triac_cur.fan_exchange_delay = p->fan_exchange_delay; triac_cur.fan_exchange_is_on = p->fan_exchange_is_on; triac_cur.fan_smoke_is_on = p->fan_smoke_is_on; triac_cur.fan_smoke_power = p->fan_smoke_power; triac_cur.feed_by_manual = p->feed_by_manual; triac_cur.feed_duty = p->feed_duty; triac_cur.feed_full = p->feed_full; triac_cur.feed_is_on = p->feed_is_on; // 更新送料duty if (triac_cur.feed_duty != 0) { // 500×triac_cur.feed_duty÷100 on_count = 5 * triac_cur.feed_duty; off_count = 500 - on_count; // 10s = 10000ms 10000 / 20 = 500 } // 返还内存 osStatus status = osPoolFree(pool_TriacHandle, evt.value.p); if (status != osOK) printf("Free Triac memory error:%x\r\n", status); } } /*----------------------------------------------------------------------------*/ // 设置period if (triac_cur.fan_smoke_power == 0) { triac_cur.fan_smoke_power = 60; } // 最低延时2.5ms,最高延时6ms uint32_t delay = t7 + triac_cur.fan_smoke_power; if (delay>8999) { delay = last_delay; } else { last_delay = delay; } // 计数器复位 __HAL_TIM_SET_COUNTER (&htim2, 0); __HAL_TIM_SET_COUNTER (&htim4, 0); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_1, delay); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_2, t7+T1/4); __HAL_TIM_SET_COMPARE(&htim4, TIM_CHANNEL_3, t7+T1/4); /* 输出: 条件判断 */ //排烟通道 if (triac_cur.fan_smoke_is_on) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC1); } //循环通道 if (triac_cur.fan_exchange_is_on) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC2); } //送料通道 if ((triac_cur.feed_by_manual || triac_cur.feed_full) && (!triac_cur.feed_is_on)) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC3); } //送料通道 ON计数 OFF计数 if (triac_cur.feed_is_on && (!triac_cur.feed_by_manual)) { // 0 // 送料 if (feed_run) { __HAL_TIM_ENABLE_IT(&htim4, TIM_IT_CC3); count_feed ++; if (count_feed >= on_count) { count_feed = 0; feed_run = false; } } else { // 不送料 count_feed ++; if (count_feed >= off_count) { count_feed = 0; feed_run = true; } } } // if 0 }