| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/io.h>
- #include <signal.h>
- #include <string.h>
- #define PORT_80 0x80
- #define SCAN_DELAY 5000
- const unsigned char segment_codes[] = {
- 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, // 0-7
- 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, // 8-F
- 0x00, 0x40 // Off, horizontal bar
- };
- typedef struct {
- int running;
- int display_value;
- } DisplayContext;
- DisplayContext ctx = {1, 0};
- void signal_handler(int sig) {
- printf("\nExiting...\n");
- ctx.running = 0;
- outb(0x00, PORT_80); // Clear Display
- }
- // Initialize I/O permissions
- int init_io() {
- if (iopl(3) < 0) {
- perror("iopl failed");
- return -1;
- }
-
- return 0;
- }
- // Display a single number at the specified position
- void display_digit(int digit, int position) {
- unsigned char code;
-
- if (digit < 0 || digit > 15) {
- code = segment_codes[16]; // 熄灭
- } else {
- code = segment_codes[digit];
- }
-
- // Position 0 uses low 4 bits, and position 1 uses high 4 bits (depending on hardware connection)
- if (position == 0) {
- outb(code, PORT_80);
- } else {
- outb(code, PORT_80);
- }
- }
- // Display two digits
- void display_two_digits(int num) {
- char value = num & 0xff;
- outb(value, PORT_80);
- return;
- int tens = num / 10;
- int ones = num % 10;
- int scan_count = 50;
-
- for (int i = 0; i < scan_count && ctx.running; i++) {
- // Display ten digits
- outb(segment_codes[tens], PORT_80);
- usleep(SCAN_DELAY);
-
- // Display one digit
- outb(segment_codes[ones], PORT_80);
- usleep(SCAN_DELAY);
- }
- }
- // Display a number in hexadecimal format
- void display_hex(int value) {
- char values = value & 0xff;
- outb(values, PORT_80);
- return;
- // for (int i = 0; i < 50 && ctx.running; i++) {
- // outb(segment_codes[high], PORT_80);
- // usleep(SCAN_DELAY);
-
- // outb(segment_codes[low], PORT_80);
- // usleep(SCAN_DELAY);
- // }
- }
- // Display a number in decimal format
- void blink_display(int num, int times) {
- for (int i = 0; i < times && ctx.running; i++) {
- display_two_digits(num);
- usleep(500000); // 500ms
-
- outb(0x00, PORT_80);
- usleep(300000); // 300ms
- }
- }
- // Scroll a text message across the display
- void scroll_display(const char *text) {
- int len = strlen(text);
-
- for (int i = 0; i <= len && ctx.running; i++) {
- for (int j = 0; j < 20 && ctx.running; j++) {
- if (i < len) {
- int digit = text[i] - '0';
- if (digit >= 0 && digit <= 9) {
- outb(segment_codes[digit], PORT_80);
- }
- }
- usleep(SCAN_DELAY);
- }
- }
- }
- int main(int argc, char *argv[]) {
- int choice = 0;
- int value;
-
-
- if (init_io() < 0) {
- printf("error\n");
- return 1;
- }
-
- signal(SIGINT, signal_handler);
-
- for (int i = 0; i < 3 && ctx.running; i++) {
- outb(0xFF, PORT_80);
- usleep(300000);
- outb(0x00, PORT_80);
- usleep(200000);
- }
- printf("test finish\n\n");
-
- while (ctx.running) {
- printf("\nPlease select a mode:\n");
- printf("1. Show Numbers (0-99)\n");
- printf("2. Display Hex (00-FF)\n");
- printf("3. Flashing display\n");
- printf("4. Scrolling\n");
- printf("5. counter\n");
- printf("6. exit\n");
- printf("select: ");
-
- if (scanf("%d", &choice) != 1) {
- while(getchar() != '\n');
- continue;
- }
-
- switch(choice) {
- case 1:
- printf("Enter numbers (0-99): ");
- scanf("%d", &value);
- if (value >= 0 && value <= 99) {
- printf("show %d\n", value);
- display_two_digits(value);
- }
- break;
-
- case 2:
- printf("Enter hexadecimal value (00-FF): ");
- scanf("%x", &value);
- if (value >= 0 && value <= 0xFF) {
- printf("show 0x%02X\n", value);
- display_hex(value);
- }
- break;
-
- case 3:
- printf("Enter numbers and flashes: ");
- scanf("%d %d", &value, &choice);
- blink_display(value, choice);
- break;
-
- case 4:
- printf("Input digital string: ");
- char text[10];
- scanf("%s", text);
- scroll_display(text);
- break;
-
- case 5:
- printf("Counter mode (press Ctrl+C to exit)\n");
- for (int i = 0; i <= 99 && ctx.running; i++) {
- printf("\rcount: %d", i);
- fflush(stdout);
- display_two_digits(i);
- }
- printf("\n");
- break;
-
- case 6:
- ctx.running = 0;
- break;
-
- default:
- printf("Invalid selection\n");
- }
- }
-
- // 清理
- outb(0x00, PORT_80);
- printf("\nexit\n");
-
- return 0;
- }
|