first

first
欢迎使用“可调增益放大器 Multisim”设计资源包!本资源专为电子爱好者、学生以及工程师设计,旨在展示如何在著名的电路仿真软件Multisim环境下,实现一个具有创新性的数字控制增益放大器项目。 项目概述 在这个项目中,我们通过巧妙结合模拟电路与数字逻辑,设计出一款独特且实用的放大器。该放大器的特点在于其增益可以被精确调控,并非固定不变。用户可以通过控制键,轻松地改变放大器的增益状态,使其在1到8倍之间平滑切换。每一步增益的变化都直观地通过LED数码管显示出来,为观察和调试提供了极大的便利。 技术特点 数字控制: 使用数字输入来调整模拟放大器的增益,展示了数字信号对模拟电路控制的应用。 动态增益调整: 放大器支持8级增益调节(1x至8x),满足不同应用场景的需求。 可视化的增益指示: 利用LED数码管实时显示当前的放大倍数,增强项目的交互性和实用性。 Multisim仿真环境: 所有设计均在Multisim中完成,确保了设计的仿真准确性和学习的便捷性。 使用指南 软件准备: 确保您的计算机上已安装最新版本的Multisim软件。 打开项目: 导入提供的Multisim项目文件,开始查看或修改设计。 仿真体验: 在仿真模式下测试放大器的功能,观察增益变化及LED显示是否符合预期。 实验与调整: 根据需要调整电路参数以优化性能。 实物搭建 (选做): 参考设计图,在真实硬件上复现实验。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "../include/menu_system.h" /*===================================================================================================================================*/ /* Module Constants */ /*===================================================================================================================================*/ static const U1 u1_s_MENU_first_level_names[(U1)FIRST_LEVEL_MENU_COUNT] = {'A', 'B', 'C'}; static const U1 u1_s_MENU_second_level_names[(U1)FIRST_LEVEL_MENU_COUNT][(U1)SECOND_LEVEL_MENU_COUNT][(U1)DATATHREE] = { {"A1", "A2", "A3"}, {"B1", "B2", "B3"}, {"C1", "C2", "C3"} }; /*===================================================================================================================================*/ /* Global Menu System */ /*===================================================================================================================================*/ ST_MENU_SYSTEM st_g_MENU_system; /*===================================================================================================================================*/ /* Function Name: v_g_MENU_initializeSystem */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Initializes the menu system with doubly linked lists */ /* Arguments: void */ /* Return: void */ /*===================================================================================================================================*/ void v_g_MENU_initializeSystem(void) { U1 u1_t_first_index; U1 u1_t_second_index; ST_FIRST_LEVEL_MENU_NODE* stp_t_prev_first; ST_FIRST_LEVEL_MENU_NODE* stp_t_current_first; ST_SECOND_LEVEL_MENU_NODE* stp_t_prev_second[(U1)FIRST_LEVEL_MENU_COUNT]; ST_SECOND_LEVEL_MENU_NODE* stp_t_horizontal_prev[(U1)SECOND_LEVEL_MENU_COUNT]; /* Initialize first level menu nodes */ stp_t_prev_first = (ST_FIRST_LEVEL_MENU_NODE*)NULL; for (u1_t_first_index = (U1)DATAZERO; u1_t_first_index < (U1)FIRST_LEVEL_MENU_COUNT; u1_t_first_index++) { stp_t_current_first = (ST_FIRST_LEVEL_MENU_NODE*)malloc(sizeof(ST_FIRST_LEVEL_MENU_NODE)); if (stp_t_current_first != (ST_FIRST_LEVEL_MENU_NODE*)NULL) { stp_t_current_first->u1_t_menu_id = u1_t_first_index; stp_t_current_first->u1p_t_menu_name = (U1P)&u1_s_MENU_first_level_names[u1_t_first_index]; stp_t_current_first->stp_t_prev = stp_t_prev_first; stp_t_current_first->stp_t_next = (ST_FIRST_LEVEL_MENU_NODE*)NULL; stp_t_current_first->stp_t_second_level_head = NULL; if (stp_t_prev_first != (ST_FIRST_LEVEL_MENU_NODE*)NULL) { stp_t_prev_first->stp_t_next = stp_t_current_first; } else { st_g_MENU_system.stp_t_first_level_head = stp_t_current_first; } stp_t_prev_first = stp_t_current_first; /* Initialize second level menu nodes for this first level */ stp_t_prev_second[u1_t_first_index] = NULL; for (u1_t_second_index = (U1)DATAZERO; u1_t_second_index < SECOND_LEVEL_MENU_COUNT; u1_t_second_index++) { ST_SECOND_LEVEL_MENU_NODE* stp_t_current_second; stp_t_current_second = (ST_SECOND_LEVEL_MENU_NODE*)malloc(sizeof(ST_SECOND_LEVEL_MENU_NODE)); if (stp_t_current_second != NULL) { stp_t_current_second->u1_t_menu_id = u1_t_second_index; stp_t_current_second->u1p_t_menu_name = (U1P)&u1_s_MENU_second_level_names[u1_t_first_index][u1_t_second_index]; stp_t_current_second->stp_t_prev = stp_t_prev_second[u1_t_first_index]; stp_t_current_second->stp_t_next = NULL; stp_t_current_second->stp_t_horizontal_prev = NULL; stp_t_current_second->stp_t_horizontal_next = NULL; stp_t_current_second->stp_t_parent = stp_t_current_first; if (stp_t_prev_second[u1_t_first_index] != NULL) { stp_t_prev_second[u1_t_first_index]->stp_t_next = stp_t_current_second; } else { stp_t_current_first->stp_t_second_level_head = stp_t_current_second; } stp_t_prev_second[u1_t_first_index] = stp_t_current_second; } } /* Make vertical list circular */ if (stp_t_current_first->stp_t_second_level_head != NULL) { stp_t_prev_second[u1_t_first_index]->stp_t_next = stp_t_current_first->stp_t_second_level_head; stp_t_current_first->stp_t_second_level_head->stp_t_prev = stp_t_prev_second[u1_t_first_index]; } } } /* Make first level list circular */ if (st_g_MENU_system.stp_t_first_level_head != (ST_FIRST_LEVEL_MENU_NODE*)NULL) { stp_t_prev_first->stp_t_next = st_g_MENU_system.stp_t_first_level_head; st_g_MENU_system.stp_t_first_level_head->stp_t_prev = stp_t_prev_first; } /* Build horizontal links between second level menus */ for (u1_t_second_index = (U1)DATAZERO; u1_t_second_index < SECOND_LEVEL_MENU_COUNT; u1_t_second_index++) { ST_FIRST_LEVEL_MENU_NODE* stp_t_first_iter; ST_SECOND_LEVEL_MENU_NODE* stp_t_second_iter; stp_t_horizontal_prev[u1_t_second_index] = NULL; stp_t_first_iter = st_g_MENU_system.stp_t_first_level_head; /* Find the second level node at position u1_t_second_index for each first level */ while (stp_t_first_iter != (ST_FIRST_LEVEL_MENU_NODE*)NULL) { stp_t_second_iter = stp_t_first_iter->stp_t_second_level_head; /* Traverse to the correct position in vertical list */ for (u1_t_first_index = (U1)DATAZERO; u1_t_first_index < u1_t_second_index; u1_t_first_index++) { if (stp_t_second_iter != NULL) { stp_t_second_iter = stp_t_second_iter->stp_t_next; } } if (stp_t_second_iter != NULL) { if (stp_t_horizontal_prev[u1_t_second_index] != NULL) { stp_t_horizontal_prev[u1_t_second_index]->stp_t_horizontal_next = stp_t_second_iter; stp_t_second_iter->stp_t_horizontal_prev = stp_t_horizontal_prev[u1_t_second_index]; } stp_t_horizontal_prev[u1_t_second_index] = stp_t_second_iter; } stp_t_first_iter = (stp_t_first_iter->stp_t_next != st_g_MENU_system.stp_t_first_level_head) ? stp_t_first_iter->stp_t_next : (ST_FIRST_LEVEL_MENU_NODE*)NULL; } /* Make horizontal list circular */ if (st_g_MENU_system.stp_t_first_level_head != (ST_FIRST_LEVEL_MENU_NODE*)NULL && stp_t_horizontal_prev[u1_t_second_index] != NULL) { ST_SECOND_LEVEL_MENU_NODE* stp_t_first_horizontal; stp_t_first_horizontal = st_g_MENU_system.stp_t_first_level_head->stp_t_second_level_head; /* Traverse to the correct position */ for (u1_t_first_index = (U1)DATAZERO; u1_t_first_index < u1_t_second_index; u1_t_first_index++) { if (stp_t_first_horizontal != NULL) { stp_t_first_horizontal = stp_t_first_horizontal->stp_t_next; } } if (stp_t_first_horizontal != NULL) { stp_t_horizontal_prev[u1_t_second_index]->stp_t_horizontal_next = stp_t_first_horizontal; stp_t_first_horizontal->stp_t_horizontal_prev = stp_t_horizontal_prev[u1_t_second_index]; } } } /* Set initial state to A2 */ st_g_MENU_system.u1_t_current_state = MENU_STATE_SECOND_LEVEL; st_g_MENU_system.stp_t_current_first_level = st_g_MENU_system.stp_t_first_level_head; /* A */ /* Find A2 in the second level list */ if (st_g_MENU_system.stp_t_current_first_level != (ST_FIRST_LEVEL_MENU_NODE*)NULL && st_g_MENU_system.stp_t_current_first_level->stp_t_second_level_head != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_first_level->stp_t_second_level_head->stp_t_next; /* A2 */ } } /*===================================================================================================================================*/ /* Function Name: v_g_MENU_cleanupSystem */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Cleans up the menu system and frees memory */ /* Arguments: void */ /* Return: void */ /*===================================================================================================================================*/ void v_g_MENU_cleanupSystem(void) { ST_FIRST_LEVEL_MENU_NODE* stp_t_first_iter; ST_FIRST_LEVEL_MENU_NODE* stp_t_first_temp; ST_SECOND_LEVEL_MENU_NODE* stp_t_second_iter; ST_SECOND_LEVEL_MENU_NODE* stp_t_second_temp; U1 u1_t_first_count; if (st_g_MENU_system.stp_t_first_level_head != NULL) { stp_t_first_iter = st_g_MENU_system.stp_t_first_level_head; u1_t_first_count = (U1)DATAZERO; do { /* Free second level nodes */ if (stp_t_first_iter->stp_t_second_level_head != NULL) { stp_t_second_iter = stp_t_first_iter->stp_t_second_level_head; U1 u1_t_second_count = (U1)DATAZERO; do { stp_t_second_temp = stp_t_second_iter; stp_t_second_iter = stp_t_second_iter->stp_t_next; free(stp_t_second_temp); u1_t_second_count++; } while ((stp_t_second_iter != stp_t_first_iter->stp_t_second_level_head) && (u1_t_second_count < (U1)SECOND_LEVEL_MENU_COUNT)); } stp_t_first_temp = stp_t_first_iter; stp_t_first_iter = stp_t_first_iter->stp_t_next; free(stp_t_first_temp); u1_t_first_count++; } while (stp_t_first_iter != st_g_MENU_system.stp_t_first_level_head && u1_t_first_count < (U1)FIRST_LEVEL_MENU_COUNT); } } /*===================================================================================================================================*/ /* Function Name: u1_g_MENU_getKeyboardInput */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Gets keyboard input and converts to key ID */ /* Arguments: void */ /* Return: U1 : Key ID */ /*===================================================================================================================================*/ U1 u1_g_MENU_getKeyboardInput(void) { U1 u1_t_input_buffer[100]; /* Increased buffer size for safety */ U1 u1_t_return_value; S4 s4_t_scanf_result; U1 u1_t_input_length; u1_t_return_value = (U1)KEY_NONE; /* Clear input buffer first */ fflush(stdin); /* Print input prompt */ printf("\nEnter command (W=Up, A=Left, S=Down, D=Right, Q=Quit): "); fflush(stdout); s4_t_scanf_result = scanf("%99s", u1_t_input_buffer); /* Limit input to 99 characters */ if (s4_t_scanf_result == (U1)DATAONE) { /* Get input length for validation */ u1_t_input_length = (U1)strlen((const char*)u1_t_input_buffer); /* Only process single character inputs */ if (u1_t_input_length == (U1)DATAONE) { switch(u1_t_input_buffer[(U1)DATAZERO]) { case 'a': case 'A': u1_t_return_value = KEY_LEFT; break; case 'd': case 'D': u1_t_return_value = KEY_RIGHT; break; case 'w': case 'W': u1_t_return_value = KEY_UP; break; case 's': case 'S': u1_t_return_value = KEY_DOWN; break; case 'q': case 'Q': u1_t_return_value = KEY_QUIT; break; default: u1_t_return_value = KEY_NONE; break; } } else { /* Input too long */ printf("Error: Please enter only one character\n"); u1_t_return_value = KEY_NONE; } } else { /* scanf failed */ printf("Error: Failed to read input\n"); u1_t_return_value = KEY_NONE; } /* Clear any remaining characters in input buffer */ while (getchar() != '\n'); return u1_t_return_value; } /*===================================================================================================================================*/ /* Function Name: v_g_MENU_printCurrentMenu */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Prints currently selected menu item */ /* Arguments: void */ /* Return: void */ /*===================================================================================================================================*/ void v_g_MENU_printCurrentMenu(void) { if (st_g_MENU_system.u1_t_current_state == MENU_STATE_FIRST_LEVEL) { if (st_g_MENU_system.stp_t_current_first_level != NULL) { printf("Current Selection: %c\n", *(st_g_MENU_system.stp_t_current_first_level->u1p_t_menu_name)); } } else { if (st_g_MENU_system.stp_t_current_second_level != NULL) { printf("Current Selection: %s\n", st_g_MENU_system.stp_t_current_second_level->u1p_t_menu_name); } } } /*===================================================================================================================================*/ /* Function Name: v_g_MENU_printMenuStatus */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Prints complete menu status */ /* Arguments: void */ /* Return: void */ /*===================================================================================================================================*/ void v_g_MENU_printMenuStatus(void) { ST_FIRST_LEVEL_MENU_NODE* stp_t_first_iter; ST_SECOND_LEVEL_MENU_NODE* stp_t_second_iter; U1 u1_t_first_count; printf("\n=== Menu Navigation System ===\n"); printf("Menu State: %s\n", (st_g_MENU_system.u1_t_current_state == MENU_STATE_FIRST_LEVEL) ? "FIRST LEVEL" : "SECOND LEVEL"); printf("First Level: "); stp_t_first_iter = st_g_MENU_system.stp_t_first_level_head; u1_t_first_count = (U1)DATAZERO; if (stp_t_first_iter != NULL) { do { if (stp_t_first_iter == st_g_MENU_system.stp_t_current_first_level && st_g_MENU_system.u1_t_current_state == MENU_STATE_FIRST_LEVEL) { printf("[%c] ", *(stp_t_first_iter->u1p_t_menu_name)); } else { printf(" %c ", *(stp_t_first_iter->u1p_t_menu_name)); } stp_t_first_iter = stp_t_first_iter->stp_t_next; u1_t_first_count++; } while (stp_t_first_iter != st_g_MENU_system.stp_t_first_level_head && u1_t_first_count < (U1)FIRST_LEVEL_MENU_COUNT); } printf("\nSecond Level: "); stp_t_first_iter = st_g_MENU_system.stp_t_first_level_head; u1_t_first_count = (U1)DATAZERO; if (stp_t_first_iter != NULL) { do { stp_t_second_iter = stp_t_first_iter->stp_t_second_level_head; if (stp_t_second_iter != NULL) { U1 u1_t_second_count = (U1)DATAZERO; do { if (stp_t_second_iter == st_g_MENU_system.stp_t_current_second_level && st_g_MENU_system.u1_t_current_state == MENU_STATE_SECOND_LEVEL) { printf("[%s] ", stp_t_second_iter->u1p_t_menu_name); } else { printf(" %s ", stp_t_second_iter->u1p_t_menu_name); } stp_t_second_iter = stp_t_second_iter->stp_t_next; u1_t_second_count++; } while (stp_t_second_iter != stp_t_first_iter->stp_t_second_level_head && u1_t_second_count < SECOND_LEVEL_MENU_COUNT); } if (u1_t_first_count < ((U1)FIRST_LEVEL_MENU_COUNT - (U1)DATAONE)) { printf("| "); } stp_t_first_iter = stp_t_first_iter->stp_t_next; u1_t_first_count++; } while (stp_t_first_iter != st_g_MENU_system.stp_t_first_level_head && u1_t_first_count < (U1)FIRST_LEVEL_MENU_COUNT); } printf("\n"); } /*===================================================================================================================================*/ /* Function Name: v_g_MENU_handleKeyEvent */ /* --------------------------------------------------------------------------------------------------------------------------------- */ /* Description: Handles key event and updates menu position */ /* Arguments: const U1 u1_a_key_id : Key ID */ /* Return: void */ /*===================================================================================================================================*/ void v_g_MENU_handleKeyEvent(const U1 u1_a_key_id) { switch (u1_a_key_id) { case (U1)KEY_LEFT: if ((U1)MENU_STATE_FIRST_LEVEL == st_g_MENU_system.u1_t_current_state) { /* Move left in first level circular list */ if (st_g_MENU_system.stp_t_current_first_level != NULL) { st_g_MENU_system.stp_t_current_first_level = st_g_MENU_system.stp_t_current_first_level->stp_t_prev; } } else { /* Move left in second level horizontal circular list */ if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_second_level->stp_t_horizontal_prev; if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_first_level = st_g_MENU_system.stp_t_current_second_level->stp_t_parent; } } } break; case (U1)KEY_RIGHT: if ((U1)MENU_STATE_FIRST_LEVEL == st_g_MENU_system.u1_t_current_state) { /* Move right in first level circular list */ if (st_g_MENU_system.stp_t_current_first_level != NULL) { st_g_MENU_system.stp_t_current_first_level = st_g_MENU_system.stp_t_current_first_level->stp_t_next; } } else { /* Move right in second level horizontal circular list */ if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_second_level->stp_t_horizontal_next; if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_first_level = st_g_MENU_system.stp_t_current_second_level->stp_t_parent; } } } break; case (U1)KEY_UP: if ((U1)MENU_STATE_FIRST_LEVEL == st_g_MENU_system.u1_t_current_state) { /* Up key does nothing in first level */ } else { /* Check if we're at A1/B1/C1 - if so, jump to first level */ if (st_g_MENU_system.stp_t_current_second_level != NULL && st_g_MENU_system.stp_t_current_second_level->u1_t_menu_id == (U1)DATAZERO) { /* We're at A1/B1/C1, jump to first level */ st_g_MENU_system.u1_t_current_state = MENU_STATE_FIRST_LEVEL; } else { /* Move up in second level vertical circular list */ if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_second_level->stp_t_prev; } } } break; case (U1)KEY_DOWN: if ((U1)MENU_STATE_FIRST_LEVEL == st_g_MENU_system.u1_t_current_state) { /* Special patch: jump to corresponding A1/B1/C1 in second level */ if (st_g_MENU_system.stp_t_current_first_level != NULL && st_g_MENU_system.stp_t_current_first_level->stp_t_second_level_head != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_first_level->stp_t_second_level_head; st_g_MENU_system.u1_t_current_state = MENU_STATE_SECOND_LEVEL; } } else { /* Move down in second level vertical circular list */ if (st_g_MENU_system.stp_t_current_second_level != NULL) { st_g_MENU_system.stp_t_current_second_level = st_g_MENU_system.stp_t_current_second_level->stp_t_next; } } break; default: /* No operation for other keys */ break; v_g_MENU_printCurrentMenu(); } } 不修改任何代码,只是加点注释,形如/* English */
10-30
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值