bit count in c (2) -- precompute

本文介绍了一种用于预计算16位和8位整数中1的位数的方法,并提供了完整的C语言实现。通过生成预计算表,可以显著提高计算效率。

 pre

  Precompute_16bit.c

  Precompute_8bit.c


-------------------------------

 

Precompute_16bit.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "../lib/ut.h"

//int main(void) {
int Precompute_16bit(void) {
  int max = 0x1u << 16;
  FILE * pFile;
  pFile = fopen ("src/lib/pre16.h","w");

  int i;
  fprintf(pFile, "#ifndef PRE16_H_\n");
  fprintf(pFile, "#define PRE16_H_\n\n");
  fprintf(pFile, "static int bits_in_16bits [%d]={\n", max);
  for (i = 0; i < max; i++) {
    if (i > 0) {
      if(i%32==0){
        fprintf(pFile, "\n");
      }
      fprintf(pFile, ", ");
    }
    int rlt = a2_bitcount(i);
    fprintf(pFile, "%d", rlt);
  }
  fprintf(pFile, "\n};\n\n");
  fprintf(pFile, "#endif /* PRE16_H_ */\n");
  fclose (pFile);
  return EXIT_SUCCESS;
}

 

Precompute_8bit.c

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "../lib/ut.h"

//int main(void) {
int Precompute_8bit(void) {
  int max = 256;
  FILE * pFile;
  pFile = fopen ("src/lib/pre8.h","w");
  int i;
  fprintf(pFile, "#ifndef PRE8_H_\n");
  fprintf(pFile, "#define PRE8_H_\n\n");
  fprintf(pFile, "static int bits_in_char [%d]={\n", max);
  for (i = 0; i < max; i++) {
    if (i > 0) {
      if(i%32==0){
        fprintf(pFile, "\n");
      }
      fprintf(pFile, ", ");
    }
    int rlt = a2_bitcount(i);
    fprintf(pFile, "%d", rlt);
  }
  fprintf(pFile, "\n};\n\n");
  fprintf(pFile, "#endif /* PRE8_H_ */\n");
  fclose (pFile);
  return EXIT_SUCCESS;
}
/***************************************************************/ /* Module Name: LED hysteresis control */ /* File Name: led_hysteresis.c */ /* Description: Implements LED control with hysteresis */ /***************************************************************/ #include "../include/led_hysteresis.h" /*=============================================================*/ /* Function Name: s4_g_led_transformInput */ /*-------------------------------------------------------------*/ /* Description: Transforms input value to scaled integer */ /* Arguments: U1 u1_a_input_value: Input value (0-255) */ /* Return: Transformed value in fixed-point format */ /*=============================================================*/ S4 s4_g_led_transformInput(U1 u1_a_input_value) { S4 s4_t_trans_result; s4_t_trans_result = (S4)u1_a_input_value * (S4)LED_MULTIPLIER - (S4)LED_SUBTRACTOR; return s4_t_trans_result; } /*=============================================================*/ /* Function Name: u1_g_led_determineLedCount */ /*-------------------------------------------------------------*/ /* Description: Determines number of LEDs to light based on */ /* transformed value and direction */ /* Arguments: S4 s4_a_TRANS_value: Transformed input value */ /* bool b_a_direction: Current direction */ /* Return: Number of LEDs to light (0-8) */ /*=============================================================*/ U1 u1_g_led_determineLedCount(S4 s4_a_TRANS_value, bool b_a_direction,U1 u1_a_last_led_count) { U1 u1_t_led_count = u1_a_last_led_count; if (b_a_direction) { if (s4_a_TRANS_value < (S4)UP_THRESHOLD_0) { u1_t_led_count = (U1)DATAZERO; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_1) { u1_t_led_count = (U1)DATAONE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_2) { u1_t_led_count = (U1)DATATWO; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_3) { u1_t_led_count = (U1)DATATHREE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_4) { u1_t_led_count = (U1)DATAFOUR; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_5) { u1_t_led_count = (U1)DATAFIVE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_6) { u1_t_led_count = (U1)DATASIX; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_7) { u1_t_led_count = (U1)DATASEVEN; } else if (s4_a_TRANS_value <= (S4)UP_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } else { printf("Unsigned range, the light status remains in the previous state.\n"); } } else { if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_7) { u1_t_led_count = (U1)DATASEVEN; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_6) { u1_t_led_count = (U1)DATASIX; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_5) { u1_t_led_count = (U1)DATAFIVE; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_4) { u1_t_led_count = (U1)DATAFOUR; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_3) { u1_t_led_count = (U1)DATATHREE; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_2) { u1_t_led_count = (U1)DATATWO; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_1) { u1_t_led_count = (U1)DATAONE; } else { u1_t_led_count = (U1)DATAZERO; } } return u1_t_led_count; } /*=============================================================*/ /* Function Name: u1_g_led_generateLedStates */ /*-------------------------------------------------------------*/ /* Description: Generates LED states bitmask based on count */ /* Arguments: U1 u1_a_led_count: Number of LEDs to light */ /* Return: LED states bitmask (8-bit) */ /*=============================================================*/ U1 u1_g_led_generateLedStates(U1 u1_a_led_count) { U1 u1_t_generate_result; u1_t_generate_result = (U1)DATAZERO; if (u1_a_led_count >= (U1)NUM_LEDS) { u1_t_generate_result = (U1)LED_ALL_ON_MASK; } else if (u1_a_led_count > (U1)DATAZERO) { u1_t_generate_result = ((U1)DATAONE << u1_a_led_count) - (U1)DATAONE; } else { u1_t_generate_result = (U1)DATAZERO; } return u1_t_generate_result; } /*=============================================================*/ /* Function Name: b_g_hyst_determineDirection */ /*-------------------------------------------------------------*/ /* Description: Determines current direction with hysteresis */ /* Arguments: S4 s4_a_TRANS_value: Transformed input value */ /* VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* Return: Current direction (DIRECTION_UP/DIRECTION_DOWN) */ /*=============================================================*/ bool b_g_hyst_determineDirection(S4 s4_a_TRANS_value, VALUESTATEMACHINE* stp_a_STATE) { bool b_t_determine_result; S4 s4_t_value_difference; S4 s4_t_abs_diff; s4_t_value_difference = s4_a_TRANS_value - stp_a_STATE->s4_t_hyst_last_value; s4_t_abs_diff = (s4_t_value_difference > (S4)DATAZERO) ? s4_t_value_difference : -s4_t_value_difference; if (s4_t_abs_diff >= (S4)HYSTERESIS_THRESHOLD) { b_t_determine_result = (s4_t_value_difference >= (S4)DATAZERO) ? (bool)DATAONE : (bool)DATAZERO; } else { b_t_determine_result = stp_a_STATE->b_t_hyst_lsb_direction; } return b_t_determine_result; } /*=============================================================*/ /* Function Name: v_g_led_processInput */ /*-------------------------------------------------------------*/ /* Description: Processes input value and updates LED state */ /* Arguments: VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* U1 u1_a_input_value: Input value (0-255) */ /* Return: void */ /*=============================================================*/ void vd_Output_Led_Light_Ctl(VALUESTATEMACHINE* stp_a_STATE, U1 u1_a_input_value) { S4 s4_t_trans_value; bool b_t_curr_direction; bool b_t_is_led_on; S1P s1p_t_curr_state; U1 u1_t_led_count; U1 u1_t_led_states; S4 s4_t_trans_integer; S4 s4_t_trans_decimal; U1 u1_t_process_index; U1 u1_t_led_maskid; /* Transform raw input value to scaled processing value */ s4_t_trans_value = s4_g_led_transformInput(u1_a_input_value); /* Determine current direction based on transformed value and hysteresis state */ b_t_curr_direction = b_g_hyst_determineDirection(s4_t_trans_value, stp_a_STATE); /* Calculate number of LEDs to illuminate based on transformed value and direction */ u1_t_led_count = u1_g_led_determineLedCount(s4_t_trans_value, b_t_curr_direction, stp_a_STATE->u1_t_last_led_count); /* Generate LED bitmask states according to LED count */ u1_t_led_states = u1_g_led_generateLedStates(u1_t_led_count); /* Update state machine parameters */ stp_a_STATE->s4_t_hyst_last_value = s4_t_trans_value; stp_a_STATE->b_t_hyst_lsb_direction = b_t_curr_direction; stp_a_STATE->u1_t_last_led_count = u1_t_led_count; /* Split transformed value into integer and decimal parts */ s4_t_trans_integer = s4_t_trans_value / (S4)SCALE_FACTOR; s4_t_trans_decimal = (s4_t_trans_value < (S4)DATAZERO ? -s4_t_trans_value : s4_t_trans_value) % (S4)SCALE_FACTOR; /* Set state string pointer based on direction flag */ s1p_t_curr_state = b_t_curr_direction ? "UP" : "DOWN"; /* Output LED illumination states */ printf("LED STATE: "); for (u1_t_process_index = (U1)DATAZERO; u1_t_process_index < (U1)NUM_LEDS; u1_t_process_index++) { /* Generate bitmask for current LED position */ u1_t_led_maskid = (U1)DATAONE << u1_t_process_index; /* Check if current LED should be ON */ b_t_is_led_on = u1_t_led_states & u1_t_led_maskid; /* Output LED symbol (ON/OFF) */ putchar(b_t_is_led_on ? (S1)LED_TURN_ON : (S1)LED_TURN_OFF); } /* Print full LED states in hexadecimal format */ printf(" (0x%02X)\n", u1_t_led_states); /* Print processing summary including transformed values and LED count */ printf("INPUT: %3u -> TRANS: %ld.%02ld (%s) -> LED COUNT: %u\n\n", u1_a_input_value, s4_t_trans_integer, s4_t_trans_decimal, s1p_t_curr_state, u1_t_led_count); } /****************************************************************/ /* Module: Input Handler */ /* File: input_handler.c */ /* Description: Handles user input and command line parsing */ /****************************************************************/ #include "../include/input_handler.h" #include "../include/led_hysteresis.h" #include "../include/aip_common.h" /****************************************************************/ /* Function Name: s4_g_inp_getInputValues */ /* ----------------------------------------------------------- */ /* Description: Gets input values from stdin */ /* Arguments: U1P* u1pp_a_values: Output values array pointer */ /* U4* u4p_a_count: Output values count pointer */ /* Return: S4 status (1: success, 0: empty, NEGATIVEONE: error) */ /****************************************************************/ S4 s4_g_inp_getInputValues(U1P* u1pp_a_values, U4* u4p_a_count) { /* Initialize return value and working variables */ S4 s4_t_input_result; /* Default to error state */ U1 u1p_t_input_line[MAX_INPUT_LENGTH]; U1 u1p_t_temp_values[MAX_VALUE_NUMS]; U4 u4_t_input_count = (U4)DATAZERO; /* Valid value counter */ S1P s1p_t_input_result1; S4 s4_t_input_length; U1 u1_t_value_isValid; U1P u1p_t_value_ptr; U1P u1p_t_value_token; S4 s4_t_input_value; s1p_t_input_result1 = (S1P)NULL; s4_t_input_result = (S4)NEGATIVEONE; /* Prompt user and read input */ printf("ENTER VALUES (0-255, up to 10 ,SPACE SEPARATED): "); fflush(stdout); s1p_t_input_result1 = fgets((char*)u1p_t_input_line, sizeof(u1p_t_input_line), stdin); if ((S1P)NULL == s1p_t_input_result1) { s4_t_input_result = (S4)NEGATIVEONE; /* Read failure */ } /* Process input line */ else { s4_t_input_length = strlen((char*)u1p_t_input_line); /* Handle empty input case */ if (((S4)DATAONE == s4_t_input_length) && ((U1)NEWLINE_CHAR == u1p_t_input_line[DATAZERO])) { s4_t_input_result = (S4)DATAZERO; /* Empty line */ } /* Process non-empty input */ else { /* Remove trailing newline if present */ if ((s4_t_input_length > (S4)DATAZERO) && ((U1)NEWLINE_CHAR == u1p_t_input_line[s4_t_input_length - (S4)DATAONE])) { u1p_t_input_line[s4_t_input_length - (S4)DATAONE] = NULL_TERMINATOR; } /* Tokenize input using space/tab as delimiters */ u1p_t_value_token = strtok((char*)u1p_t_input_line, " \t"); /* Process each token */ while (u1p_t_value_token != (U1P)NULL) { u1_t_value_isValid = (U1)DATAONE; /* Flag for token validity */ u1p_t_value_ptr = u1p_t_value_token; /* Validate characters in token */ while (*u1p_t_value_ptr) { if ((*u1p_t_value_ptr < (U1)ASCII_ZERO)||(*u1p_t_value_ptr > (U1)ASCII_NINE)) { printf("SKIPPING INVALID TOKEN '%s' (NON-DIGIT CHAR '%c')\n", u1p_t_value_token, *u1p_t_value_ptr); u1_t_value_isValid = (U4)DATAZERO; break; } u1p_t_value_ptr++; } if ((U4)MAX_INPUT_NUMS <= u4_t_input_count) { printf("\n [!] Too many inputs (max %d). Truncating input.\n", MAX_INPUT_NUMS); break; /* Prevent buffer overflow */ } /* Validate numeric range */ if (u1_t_value_isValid) { s4_t_input_value = atoi((char*)u1p_t_value_token); if (s4_t_input_value < (U4)DATAZERO || s4_t_input_value >= (S4)MAX_INPUT_LENGTH) { printf("SKIPPING OUT-OF-RANGE TOKEN '%s' (VALUE %d)\n", u1p_t_value_token, s4_t_input_value); } else { u1p_t_temp_values[u4_t_input_count] = (U1)s4_t_input_value; u4_t_input_count = u4_t_input_count + (U4)DATAONE; } } /* Get next token */ u1p_t_value_token = strtok(NULL, " \t"); } /* Handle processing results */ *u4p_a_count = u4_t_input_count; if ((U4)DATAZERO == u4_t_input_count) { s4_t_input_result = (U4)DATAZERO; /* No valid inputs */ } /* Allocate memory for valid values */ else { *u1pp_a_values = (U1P)malloc(u4_t_input_count * sizeof(U1)); if (*u1pp_a_values == NULL) { s4_t_input_result = (S4)NEGATIVEONE; /* Allocation failure */ } /* Copy values and set success */ else { memcpy(*u1pp_a_values, u1p_t_temp_values, u4_t_input_count * sizeof(U1)); s4_t_input_result = (S4)DATAONE; /* Success */ } } } } /* Single return point */ return s4_t_input_result; } /****************************************************************/ /* Function Name: u1_g_inp_askContinue */ /* ----------------------------------------------------------- */ /* Description: Asks user if they want to continue */ /* Arguments: void */ /* Return: U1 TRUE to continue, FALSE to exit */ /****************************************************************/ U1 u1_g_inp_askContinue(void) { S1 s1p_t_ask_response[MAX_INPUT_LENGTH]; U1 u1_t_final_result = (U1)FALSE; U1 u1_t_valid_input = (U1)FALSE; S4 s4_t_input_length; while (!u1_t_valid_input) { /* Prompt user for input */ printf("CONTINUE? (y/n): "); fflush(stdout); /* Retrieve user input safely */ S1P s1p_t_input_result = fgets((char*)s1p_t_ask_response, sizeof(s1p_t_ask_response), stdin); /* Handle input retrieval errors */ if ((S1P)NULL == s1p_t_input_result) { printf("INPUT ERROR. PLEASE TRY AGAIN.\n"); continue; } /* Remove trailing newline character */ const S4 s4_t_input_length = strcspn((char*)s1p_t_ask_response, "\n"); s1p_t_ask_response[s4_t_input_length] = (S1)NULL_TERMINATOR; /* Validate non-empty input */ if (s4_t_input_length == (U1)DATAZERO) { printf("INPUT EMPTY. PLEASE RESPOND WITH 'y' OR 'n'.\n"); continue; } /* Precompute comparison results using standard bool */ const bool b_choice_is_yes = (strcasecmp((char*)s1p_t_ask_response, "y") == (U1)DATAZERO); const bool b_choice_is_no = (strcasecmp((char*)s1p_t_ask_response, "n") == (U1)DATAZERO); /* Process valid responses */ if (b_choice_is_yes) { u1_t_final_result = (U1)TRUE; u1_t_valid_input = (U1)TRUE; } else if (b_choice_is_no) { u1_t_final_result = (U1)FALSE; u1_t_valid_input = (U1)TRUE; } else { printf("INVALID INPUT '%s'. PLEASE ENTER 'y' OR 'n'.\n", s1p_t_ask_response); } } return u1_t_final_result; } /****************************************************************/ /* Function Name: v_g_inp_processUserInputs */ /* ----------------------------------------------------------- */ /* Description: Processes user inputs interactively */ /* Arguments: VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* Return: void */ /****************************************************************/ void v_g_inp_processUserInputs(VALUESTATEMACHINE* stp_a_STATE) { /* Main processing loop */ U4 u4_t_process_index; while ((U1)TRUE) { U1P u1p_a_values = (U1P)NULL; /* Pointer to input values array */ U4 u4_a_count = (U4)DATAZERO; /* Number of input values */ /* Get user input values */ S4 s4_t_RESULT = s4_g_inp_getInputValues(&u1p_a_values, &u4_a_count); /* Check for exit condition */ if ((S4)NEGATIVEONE == s4_t_RESULT) { break; /* Break loop on exit command */ } /* Handle empty input case */ else if ((U4)DATAZERO == s4_t_RESULT) { printf("EMPTY INPUT, "); if (!u1_g_inp_askContinue()) { break; /* Exit on user request */ } continue; /* Restart loop */ } /* Handle error case */ else if (s4_t_RESULT < (S4)DATAZERO) { printf("PLEASE RE-ENTER\n"); continue; /* Retry input */ } /* Process all input values */ for (u4_t_process_index = (U4)DATAZERO; u4_t_process_index < u4_a_count; u4_t_process_index++) { /* Display current input */ printf("--- INPUT SEQ %u: VALUE=%u ---\n", u4_t_process_index + (U4)DATAONE, u1p_a_values[u4_t_process_index]); /* Execute hysteresis control */ vd_Output_Led_Light_Ctl(stp_a_STATE, u1p_a_values[u4_t_process_index]); } /* Free allocated memory */ free(u1p_a_values); /* Check if user wants to continue */ if (!u1_g_inp_askContinue()) { break; /* Exit loop on user request */ } } } 列出每个函数的功能
09-19
/****************************************************************/ /* Module: Input Handler */ /* File: input_handler.c */ /* Description: Handles user input and command line parsing */ /****************************************************************/ #include "../include/input_handler.h" #include "../include/led_hysteresis.h" #include "../include/aip_common.h" /****************************************************************/ /* Function Name: s4_g_inp_getInputValues */ /* ----------------------------------------------------------- */ /* Description: Gets input values from stdin */ /* Arguments: U1P* u1pp_a_values: Output values array pointer */ /* U4* u4p_a_count: Output values count pointer */ /* Return: S4 status (1: success, 0: empty, NEGATIVEONE: error) */ /****************************************************************/ S4 s4_g_inp_getInputValues(U1P* u1pp_a_values, U4* u4p_a_count) { /* Initialize return value and working variables */ S4 s4_t_input_result; /* Default to error state */ U1 u1p_t_input_line[MAX_INPUT_LENGTH]; U1 u1p_t_temp_values[MAX_VALUE_NUMS]; U4 u4_t_input_count = (U4)DATAZERO; /* Valid value counter */ S1P s1p_t_input_result1; S4 s4_t_input_length; U1 u1_t_value_isValid; U1P u1p_t_value_ptr; U1P u1p_t_value_token; s1p_t_input_result1 = (S1P)NULL; s4_t_input_result = (S4)NEGATIVEONE; /* Prompt user and read input */ printf("ENTER VALUES (0-255, SPACE SEPARATED): "); fflush(stdout); s1p_t_input_result1 = fgets((char*)u1p_t_input_line, sizeof(u1p_t_input_line), stdin); if ((S1P)NULL == s1p_t_input_result1) { s4_t_input_result = (S4)NEGATIVEONE; /* Read failure */ } /* Process input line */ else { s4_t_input_length = strlen((char*)u1p_t_input_line); /* Handle empty input case */ if (((S4)DATAONE == s4_t_input_length) && ((U1)NEWLINE_CHAR == u1p_t_input_line[DATAZERO])) { s4_t_input_result = (S4)DATAZERO; /* Empty line */ } /* Process non-empty input */ else { /* Remove trailing newline if present */ if ((s4_t_input_length > (S4)DATAZERO) && ((U1)NEWLINE_CHAR == u1p_t_input_line[s4_t_input_length - (S4)DATAONE])) { u1p_t_input_line[s4_t_input_length - (S4)DATAONE] = NULL_TERMINATOR; } /* Tokenize input using space/tab as delimiters */ u1p_t_value_token = strtok((char*)u1p_t_input_line, " \t"); /* Process each token */ while ((u1p_t_value_token != (U1P)NULL) && (u4_t_input_count < (U4)MAX_VALUE_NUMS)) { u1_t_value_isValid = (U1)DATAONE; /* Flag for token validity */ u1p_t_value_ptr = u1p_t_value_token; /* Validate characters in token */ while (*u1p_t_value_ptr) { if ((*u1p_t_value_ptr < (U1)'0')||(*u1p_t_value_ptr > (U1)'9')) { printf("SKIPPING INVALID TOKEN '%s' (NON-DIGIT CHAR '%c')\n", u1p_t_value_token, *u1p_t_value_ptr); u1_t_value_isValid = (U4)DATAZERO; break; } u1p_t_value_ptr++; } /* Validate numeric range */ if (u1_t_value_isValid) { S4 s4_t_input_value = atoi((char*)u1p_t_value_token); if (s4_t_input_value < (U4)DATAZERO || s4_t_input_value >= (S4)MAX_INPUT_LENGTH) { printf("SKIPPING OUT-OF-RANGE TOKEN '%s' (VALUE %d)\n", u1p_t_value_token, s4_t_input_value); } else { u1p_t_temp_values[u4_t_input_count++] = (U1)s4_t_input_value; } } /* Get next token */ u1p_t_value_token = strtok(NULL, " \t"); } /* Handle processing results */ *u4p_a_count = u4_t_input_count; if ((U4)DATAZERO == u4_t_input_count) { s4_t_input_result = (U4)DATAZERO; /* No valid inputs */ } /* Allocate memory for valid values */ else { *u1pp_a_values = (U1P)malloc(u4_t_input_count * sizeof(U1)); if (*u1pp_a_values == NULL) { s4_t_input_result = (S4)NEGATIVEONE; /* Allocation failure */ } /* Copy values and set success */ else { memcpy(*u1pp_a_values, u1p_t_temp_values, u4_t_input_count * sizeof(U1)); s4_t_input_result = (S4)DATAONE; /* Success */ } } } } /* Single return point */ return s4_t_input_result; } /****************************************************************/ /* Function Name: u1_g_inp_askContinue */ /* ----------------------------------------------------------- */ /* Description: Asks user if they want to continue */ /* Arguments: void */ /* Return: U1 TRUE to continue, FALSE to exit */ /****************************************************************/ U1 u1_g_inp_askContinue(void) { S1 s1p_t_ask_response[MAX_INPUT_LENGTH]; U1 u1_t_final_result = (U1)FALSE; U1 u1_t_valid_input = (U1)FALSE; S4 s4_t_input_length; while (!u1_t_valid_input) { /* Prompt user for input */ printf("CONTINUE? (y/n): "); fflush(stdout); /* Retrieve user input safely */ S1P s1p_t_input_result = fgets((char*)s1p_t_ask_response, sizeof(s1p_t_ask_response), stdin); /* Handle input retrieval errors */ if ((S1P)NULL == s1p_t_input_result) { printf("INPUT ERROR. PLEASE TRY AGAIN.\n"); continue; } /* Remove trailing newline character */ const S4 s4_t_input_length = strcspn((char*)s1p_t_ask_response, "\n"); s1p_t_ask_response[s4_t_input_length] = (S1)NULL_TERMINATOR; /* Validate non-empty input */ if (s4_t_input_length == (U1)DATAZERO) { printf("INPUT EMPTY. PLEASE RESPOND WITH 'y' OR 'n'.\n"); continue; } /* Precompute comparison results using standard bool */ const bool b_choice_is_yes = (strcasecmp((char*)s1p_t_ask_response, "y") == (U1)DATAZERO); const bool b_choice_is_no = (strcasecmp((char*)s1p_t_ask_response, "n") == (U1)DATAZERO); /* Process valid responses */ if (b_choice_is_yes) { u1_t_final_result = (U1)TRUE; u1_t_valid_input = (U1)TRUE; } else if (b_choice_is_no) { u1_t_final_result = (U1)FALSE; u1_t_valid_input = (U1)TRUE; } else { printf("INVALID INPUT '%s'. PLEASE ENTER 'y' OR 'n'.\n", s1p_t_ask_response); } } return u1_t_final_result; } /****************************************************************/ /* Function Name: v_g_inp_processUserInputs */ /* ----------------------------------------------------------- */ /* Description: Processes user inputs interactively */ /* Arguments: VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* Return: void */ /****************************************************************/ void v_g_inp_processUserInputs(VALUESTATEMACHINE* stp_a_STATE) { /* Main processing loop */ U4 u4_t_process_index; while ((U1)TRUE) { U1P u1p_a_values = (U1P)NULL; /* Pointer to input values array */ U4 u4_a_count = (U4)DATAZERO; /* Number of input values */ /* Get user input values */ S4 s4_t_RESULT = s4_g_inp_getInputValues(&u1p_a_values, &u4_a_count); /* Check for exit condition */ if ((S4)NEGATIVEONE == s4_t_RESULT) { break; /* Break loop on exit command */ } /* Handle empty input case */ else if ((U4)DATAZERO == s4_t_RESULT) { printf("EMPTY INPUT, "); if (!u1_g_inp_askContinue()) { break; /* Exit on user request */ } continue; /* Restart loop */ } /* Handle error case */ else if (s4_t_RESULT < (S4)(U4)DATAZERO) { printf("PLEASE RE-ENTER\n"); continue; /* Retry input */ } /* Process all input values */ for (u4_t_process_index = (U4)DATAZERO; u4_t_process_index < u4_a_count; u4_t_process_index++) { /* Display current input */ printf("--- INPUT SEQ %u: VALUE=%u ---\n", u4_t_process_index + (U4)DATAONE, u1p_a_values[u4_t_process_index]); /* Execute hysteresis control */ vd_Output_Led_Light_Ctl(stp_a_STATE, u1p_a_values[u4_t_process_index]); } /* Free allocated memory */ free(u1p_a_values); /* Check if user wants to continue */ if (!u1_g_inp_askContinue()) { break; /* Exit loop on user request */ } } } /***************************************************************/ /* Module Name: LED hysteresis control */ /* File Name: led_hysteresis.c */ /* Description: Implements LED control with hysteresis */ /***************************************************************/ #include "../include/led_hysteresis.h" /*=============================================================*/ /* Function Name: s4_g_led_transformInput */ /*-------------------------------------------------------------*/ /* Description: Transforms input value to scaled integer */ /* Arguments: U1 u1_a_input_value: Input value (0-255) */ /* Return: Transformed value in fixed-point format */ /*=============================================================*/ S4 s4_g_led_transformInput(U1 u1_a_input_value) { S4 s4_t_trans_result; s4_t_trans_result = (S4)u1_a_input_value * (S4)LED_MULTIPLIER - (S4)LED_SUBTRACTOR; return s4_t_trans_result; } /*=============================================================*/ /* Function Name: u1_g_led_determineLedCount */ /*-------------------------------------------------------------*/ /* Description: Determines number of LEDs to light based on */ /* transformed value and direction */ /* Arguments: S4 s4_a_TRANS_value: Transformed input value */ /* bool b_a_direction: Current direction */ /* Return: Number of LEDs to light (0-8) */ /*=============================================================*/ U1 u1_g_led_determineLedCount(S4 s4_a_TRANS_value, bool b_a_direction) { U1 u1_t_led_count = (U1)DATAZERO; if (b_a_direction) { if (s4_a_TRANS_value < (S4)UP_THRESHOLD_0) { u1_t_led_count = (U1)DATAZERO; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_1) { u1_t_led_count = (U1)DATAONE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_2) { u1_t_led_count = (U1)DATATWO; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_3) { u1_t_led_count = (U1)DATATHREE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_4) { u1_t_led_count = (U1)DATAFOUR; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_5) { u1_t_led_count = (U1)DATAFIVE; } else if (s4_a_TRANS_value < (S4)UP_THRESHOLD_6) { u1_t_led_count = (U1)DATASIX; } else if (s4_a_TRANS_value <= (S4)UP_THRESHOLD_7) { u1_t_led_count = (U1)DATASEVEN; } else if (s4_a_TRANS_value <= (S4)UP_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } } else { if (s4_a_TRANS_value >= (S4) DOWN_THRESHOLD_8) { u1_t_led_count = (U1)DATAEIGHT; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_7) { u1_t_led_count = (U1)DATASEVEN; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_6) { u1_t_led_count = (U1)DATASIX; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_5) { u1_t_led_count = (U1)DATAFIVE; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_4) { u1_t_led_count = (U1)DATAFOUR; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_3) { u1_t_led_count = (U1)DATATHREE; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_2) { u1_t_led_count = (U1)DATATWO; } else if (s4_a_TRANS_value > (S4) DOWN_THRESHOLD_1) { u1_t_led_count = (U1)DATAONE; } } return u1_t_led_count; } /*=============================================================*/ /* Function Name: u1_g_led_generateLedStates */ /*-------------------------------------------------------------*/ /* Description: Generates LED states bitmask based on count */ /* Arguments: U1 u1_a_led_count: Number of LEDs to light */ /* Return: LED states bitmask (8-bit) */ /*=============================================================*/ U1 u1_g_led_generateLedStates(U1 u1_a_led_count) { U1 u1_t_generate_result; u1_t_generate_result = (U1)DATAZERO; if (u1_a_led_count >= (U1)NUM_LEDS) { u1_t_generate_result = (U1)LED_ALL_ON_MASK; } else if (u1_a_led_count > (U1)DATAZERO) { u1_t_generate_result = ((U1)DATAONE << u1_a_led_count) - (U1)DATAONE; } else { u1_t_generate_result = (U1)DATAZERO; } return u1_t_generate_result; } /*=============================================================*/ /* Function Name: b_g_hyst_determineDirection */ /*-------------------------------------------------------------*/ /* Description: Determines current direction with hysteresis */ /* Arguments: S4 s4_a_TRANS_value: Transformed input value */ /* VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* Return: Current direction (DIRECTION_UP/DIRECTION_DOWN) */ /*=============================================================*/ bool b_g_hyst_determineDirection(S4 s4_a_TRANS_value, VALUESTATEMACHINE* stp_a_STATE) { bool b_t_determine_result; S4 s4_t_value_difference; S4 s4_t_abs_diff; s4_t_value_difference = s4_a_TRANS_value - stp_a_STATE->s4_t_hyst_last_value; s4_t_abs_diff = (s4_t_value_difference > (S4)DATAZERO) ? s4_t_value_difference : -s4_t_value_difference; if (s4_t_abs_diff >= (S4)HYSTERESIS_THRESHOLD) { b_t_determine_result = (s4_t_value_difference >= (S4)DATAZERO) ? (bool)DATAONE : (bool)DATAZERO; } else { b_t_determine_result = stp_a_STATE->b_t_hyst_lsb_direction; } return b_t_determine_result; } /*=============================================================*/ /* Function Name: v_g_led_processInput */ /*-------------------------------------------------------------*/ /* Description: Processes input value and updates LED state */ /* Arguments: VALUESTATEMACHINE* stp_a_STATE: State pointer */ /* U1 u1_a_input_value: Input value (0-255) */ /* Return: void */ /*=============================================================*/ void vd_Output_Led_Light_Ctl(VALUESTATEMACHINE* stp_a_STATE, U1 u1_a_input_value) { S4 s4_t_trans_value; bool b_t_curr_direction; bool b_t_is_led_on; S1P s1p_t_curr_state; U1 u1_t_led_count; U1 u1_t_led_states; S4 s4_t_trans_integer; S4 s4_t_trans_decimal; U1 u1_t_process_index; U1 u1_t_led_maskid; s4_t_trans_value = s4_g_led_transformInput(u1_a_input_value); b_t_curr_direction = b_g_hyst_determineDirection(s4_t_trans_value, stp_a_STATE); u1_t_led_count = u1_g_led_determineLedCount(s4_t_trans_value, b_t_curr_direction); u1_t_led_states = u1_g_led_generateLedStates(u1_t_led_count); /* Update state */ stp_a_STATE->s4_t_hyst_last_value = s4_t_trans_value; stp_a_STATE->b_t_hyst_lsb_direction = b_t_curr_direction; s4_t_trans_integer= s4_t_trans_value / (S4)SCALE_FACTOR; s4_t_trans_decimal = (s4_t_trans_value < (S4)DATAZERO ? -s4_t_trans_value : s4_t_trans_value) % (S4)SCALE_FACTOR; s1p_t_curr_state = b_t_curr_direction ? "UP" : "DOWN"; /* Output results */ printf("LED STATE: "); for (u1_t_process_index = (U1)DATAZERO; u1_t_process_index < (U1)NUM_LEDS; u1_t_process_index++) { u1_t_led_maskid = (U1)DATAONE << u1_t_process_index; b_t_is_led_on = u1_t_led_states & u1_t_led_maskid; putchar(b_t_is_led_on ? (S1)LED_TURN_ON : (S1)LED_TURN_OFF); } printf(" (0x%02X)\n", u1_t_led_states); printf("INPUT: %3u -> TRANS: %ld.%02ld (%s) -> LED COUNT: %u\n\n",u1_a_input_value,s4_t_trans_integer,s4_t_trans_decimal,s1p_t_curr_state,u1_t_led_count); } 总结所有函数,分成3-4个模块,列出每个函数实现的功能
09-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值