test_ssegment.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/io.h>
  5. #include <signal.h>
  6. #include <string.h>
  7. #define PORT_80 0x80
  8. #define SCAN_DELAY 5000
  9. const unsigned char segment_codes[] = {
  10. 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, // 0-7
  11. 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, // 8-F
  12. 0x00, 0x40 // Off, horizontal bar
  13. };
  14. typedef struct {
  15. int running;
  16. int display_value;
  17. } DisplayContext;
  18. DisplayContext ctx = {1, 0};
  19. void signal_handler(int sig) {
  20. printf("\nExiting...\n");
  21. ctx.running = 0;
  22. outb(0x00, PORT_80); // Clear Display
  23. }
  24. // Initialize I/O permissions
  25. int init_io() {
  26. if (iopl(3) < 0) {
  27. perror("iopl failed");
  28. return -1;
  29. }
  30. return 0;
  31. }
  32. // Display a single number at the specified position
  33. void display_digit(int digit, int position) {
  34. unsigned char code;
  35. if (digit < 0 || digit > 15) {
  36. code = segment_codes[16]; // 熄灭
  37. } else {
  38. code = segment_codes[digit];
  39. }
  40. // Position 0 uses low 4 bits, and position 1 uses high 4 bits (depending on hardware connection)
  41. if (position == 0) {
  42. outb(code, PORT_80);
  43. } else {
  44. outb(code, PORT_80);
  45. }
  46. }
  47. // Display two digits
  48. void display_two_digits(int num) {
  49. char value = num & 0xff;
  50. outb(value, PORT_80);
  51. return;
  52. int tens = num / 10;
  53. int ones = num % 10;
  54. int scan_count = 50;
  55. for (int i = 0; i < scan_count && ctx.running; i++) {
  56. // Display ten digits
  57. outb(segment_codes[tens], PORT_80);
  58. usleep(SCAN_DELAY);
  59. // Display one digit
  60. outb(segment_codes[ones], PORT_80);
  61. usleep(SCAN_DELAY);
  62. }
  63. }
  64. // Display a number in hexadecimal format
  65. void display_hex(int value) {
  66. char values = value & 0xff;
  67. outb(values, PORT_80);
  68. return;
  69. // for (int i = 0; i < 50 && ctx.running; i++) {
  70. // outb(segment_codes[high], PORT_80);
  71. // usleep(SCAN_DELAY);
  72. // outb(segment_codes[low], PORT_80);
  73. // usleep(SCAN_DELAY);
  74. // }
  75. }
  76. // Display a number in decimal format
  77. void blink_display(int num, int times) {
  78. for (int i = 0; i < times && ctx.running; i++) {
  79. display_two_digits(num);
  80. usleep(500000); // 500ms
  81. outb(0x00, PORT_80);
  82. usleep(300000); // 300ms
  83. }
  84. }
  85. // Scroll a text message across the display
  86. void scroll_display(const char *text) {
  87. int len = strlen(text);
  88. for (int i = 0; i <= len && ctx.running; i++) {
  89. for (int j = 0; j < 20 && ctx.running; j++) {
  90. if (i < len) {
  91. int digit = text[i] - '0';
  92. if (digit >= 0 && digit <= 9) {
  93. outb(segment_codes[digit], PORT_80);
  94. }
  95. }
  96. usleep(SCAN_DELAY);
  97. }
  98. }
  99. }
  100. int main(int argc, char *argv[]) {
  101. int choice = 0;
  102. int value;
  103. if (init_io() < 0) {
  104. printf("error\n");
  105. return 1;
  106. }
  107. signal(SIGINT, signal_handler);
  108. for (int i = 0; i < 3 && ctx.running; i++) {
  109. outb(0xFF, PORT_80);
  110. usleep(300000);
  111. outb(0x00, PORT_80);
  112. usleep(200000);
  113. }
  114. printf("test finish\n\n");
  115. while (ctx.running) {
  116. printf("\nPlease select a mode:\n");
  117. printf("1. Show Numbers (0-99)\n");
  118. printf("2. Display Hex (00-FF)\n");
  119. printf("3. Flashing display\n");
  120. printf("4. Scrolling\n");
  121. printf("5. counter\n");
  122. printf("6. exit\n");
  123. printf("select: ");
  124. if (scanf("%d", &choice) != 1) {
  125. while(getchar() != '\n');
  126. continue;
  127. }
  128. switch(choice) {
  129. case 1:
  130. printf("Enter numbers (0-99): ");
  131. scanf("%d", &value);
  132. if (value >= 0 && value <= 99) {
  133. printf("show %d\n", value);
  134. display_two_digits(value);
  135. }
  136. break;
  137. case 2:
  138. printf("Enter hexadecimal value (00-FF): ");
  139. scanf("%x", &value);
  140. if (value >= 0 && value <= 0xFF) {
  141. printf("show 0x%02X\n", value);
  142. display_hex(value);
  143. }
  144. break;
  145. case 3:
  146. printf("Enter numbers and flashes: ");
  147. scanf("%d %d", &value, &choice);
  148. blink_display(value, choice);
  149. break;
  150. case 4:
  151. printf("Input digital string: ");
  152. char text[10];
  153. scanf("%s", text);
  154. scroll_display(text);
  155. break;
  156. case 5:
  157. printf("Counter mode (press Ctrl+C to exit)\n");
  158. for (int i = 0; i <= 99 && ctx.running; i++) {
  159. printf("\rcount: %d", i);
  160. fflush(stdout);
  161. display_two_digits(i);
  162. }
  163. printf("\n");
  164. break;
  165. case 6:
  166. ctx.running = 0;
  167. break;
  168. default:
  169. printf("Invalid selection\n");
  170. }
  171. }
  172. // 清理
  173. outb(0x00, PORT_80);
  174. printf("\nexit\n");
  175. return 0;
  176. }