Screen operations for C embedded system programming practices

Source: Internet
Author: User
Chinese Character Processing

The problem to be solved now is that embedded systems often need to provide a limited number of Chinese characters for necessary display functions instead of a complete Chinese Character Library. For example, there is no need to provide the "email" display function on the LCD of a microwave oven; a "Short Message" is not required on the LCD of an air conditioner that provides the Chinese character display function, and so on. However, a mobile phone or PHS usually needs to include a complete Chinese Character Library.

If the Chinese Character Library is relatively complete, it is very easy to calculate the offset of the Chinese character model in the library by the internal code: the Chinese Character Library is arranged in the order of location, the first byte is the area code of the Chinese character, and the last byte is the location code of the word. 94 Chinese characters are recorded in each area, and the location number is the position of the word in the area. Therefore, the formula for calculating the specific position of Chinese characters in the Chinese font is 94 * (area code-1) + location code-1. Minus 1 is because the array starts with 0 and the location code starts with 1. Just multiply the number of bytes occupied by a Chinese character model, that is, (94 * (area code-1) + location code-1) * The number of bytes occupied by a Chinese character model, take the 16*16 dot matrix font as an example. The formula is: (94 * (area code-1) + (location code-1) * 32. The 32-byte information starting from this position in the Chinese character library records the font information of the word.

For a system that contains a complete Chinese Character Library, we can use the preceding rule to calculate the position of the model. But what if I only provide a small number of Chinese characters? For example, dozens to hundreds? The best practice is:

Definition macro:

# Define ex_font_char (value)
# Define ex_font_unicode_val (value ),
# Define ex_font_ansi_val (value ),

Define struct:

Typedef struct _ wide_unicode_font16x16
{
Word value;/* Internal Code */
Byte data [32];/* modulo lattice */
} Unicode;
# Define chinese_char_num... /* Number of Chinese characters */

Array Used for storage of the model:

Unicode Chinese [chinese_char_num] =
{
{
Ex_font_char ("industry ")
Ex_font_unicode_val (0x4e1a)
{0x04, 0x40, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0x44, 0x46, 0x24, 0x4c, 0x24, 0x48, 0x14, 0x50, 0x1c, 0x50, 0x14, 0x60, 0x04, 0x40, 0x04, 0x40, 0x04, 0x44, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00}
},
{
Ex_font_char ("medium ")
Ex_font_unicode_val (0x4e2d)
{0x01, 0x00, 0x01, 0x00, 0x21, 0x08, 0x3f, 0xfc, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08, 0x21, 0x08,
0x3f, 0xf8, 0x21, 0x08, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}
},
{
Ex_font_char ("Cloud ")
Ex_font_unicode_val (0x4e91)
{0x00, 0x00, 0x00, 0x30, 0x3f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xff, 0xfe, 0x03, 0x00, 0x07, 0x00,

0x06, 0x40, 0x0c, 0x20, 0x18, 0x10, 0x31, 0xf8, 0x7f, 0x0c, 0x20, 0x08, 0x00, 0x00}
},
{
Ex_font_char ("parts ")
Ex_font_unicode_val (0x4ef6)
{0x10, 0x40, 0x1a, 0x40, 0x13, 0x40, 0x32, 0x40, 0x23, 0xfc, 0x64, 0x40, 0xa4, 0x40, 0x28, 0x40, 0x2f, 0xfe,

0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40, 0x20, 0x40}
}
}

To display a specific Chinese character, you only need to find the internal code from the array and the same as the Chinese character internal code. If the preceding Chinese characters are arranged in the order of inner code size in the array, you can use the binary search method to find the Chinese character model more efficiently.

This is a very effective way to organize the Chinese Character Library, which can ensureProgramHas a good structure.

System Time Display

The system time can be read from NVRAM. Generally, the system reads the current time every second with the second interrupt generated by NVRAM and displays it on the LCD. There is a efficiency issue about time display. Because time has its own particularity, that is, there is only one minute change in 60 seconds, and there is only one hour change in 60 minutes. If we refresh the read time completely on the screen each time, it wastes a lot of system time.

A better way is to store the hour, minute, and second in the time display function with static variables, and update the display only when its content changes.

Extern void displaytime (...)
{
Static byte byhour, byminute, bysecond;
Byte bynewhour, bynewminute, bynewsecond;
Bynewhour = getsyshour ();
Bynewminute = getsysminute ();
Bynewsecond = getsyssecond ();

If (bynewhour! = Byhour)
{
... /* Display hours */
Byhour = bynewhour;
}
If (bynewminute! = Byminute)
{
... /* Display minutes */
Byminute = bynewminute;
}
If (bynewsecond! = Bysecond)
{
... /* Display seconds */
Bysecond = bynewsecond;
}
}

This example can also prove the powerful power of the static keyword in C language. Of course, in the C ++ language, static has more powerful power, which makes some data and functions out of the "object" and become part of the "class, it is precisely this characteristic that has made countless excellent designs of the software.
Animation display

There is no such thing as an animation, and there is no such thing as an animation. A still picture goes a lot more way. As time changes, different static images are displayed on the screen, which is the essence of animation. Therefore, the timer must be used to display animations on the LCD of an embedded system. The world without hardware or software timers cannot be imagined:

(1) Without a timer, an operating system will not be able to rotate the time slice, so it will not be able to schedule multiple tasks, so it will no longer become a multi-task operating system;

(2) Without a timer, a multimedia playing software will not work because it does not know when to switch to the next frame;

(3) Without a timer, a network protocol cannot run because it cannot know when packet transmission times out and re-transmits it. It cannot complete a specific task at a specific time.

Therefore, no timer will mean no operating system, no network, no multimedia. What kind of darkness will this mean? Therefore, reasonable and flexible use of various timers is the most basic requirement for a software engineer!

In an embedded system with 80186 as the main chip, we need to use the interrupt of the hardware timer as the software timer to change the display content of the screen after the interrupt occurs. In the displayed time "XX: XX", let the colon alternate or not. After each second interruption occurs, you need to call showdot:

Void showdot ()
{
Static bool bshowdot = true;/* The Power of static keywords again */
If (bshowdot)
{
Showchar (':', xpos, ypos );
}
Else
{
Showchar ('', xpos, ypos );
}
Bshowdot =! Bshowdot;
}

Menu operations

Countless questions have finally emerged. In this section, we will see how the software structure will change even if a tiny bit of Object-oriented thinking is used in the C language!

I used to be an idiot and was dizzy by the menu. I gave a system like this:


Figure 1 menu example

You must use the "shortcut →" key on the keyboard to switch the menu focus. When the user is in a menu, if you press the OK and cancel keys on the keyboard, call the processing function corresponding to the focus menu. I used to do this silly thing:

/* Press OK */
Void onokkey ()
{
/* Click OK to determine the focus menu and call the corresponding processing function */
Switch (currentfocus)
{
Case menu1:
Menu1onok ();
Break;
Case menu2:
Menu2onok ();
Break;
...
}
}
/* Press the cancel key */
Void oncancelkey ()
{
/* Determine which focus menu to press the cancel key and call the corresponding processing function */
Switch (currentfocus)
{
Case menu1:
Menu1oncancel ();
Break;
Case menu2:
Menu2oncancel ();
Break;
...
}
}

One day, I did this:

/* Encapsulate menu attributes and operations together */
Typedef struct tagsysmenu
{
Char * text;/* menu text */
Byte xpos;/* x coordinate of the menu on the LCD */
Byte ypos;/* Y coordinate of the menu on the LCD */
Void (* onokfun) ();/* process the function pointer by pressing the OK key on the menu */
Void (* oncancelfun) ();/* handle function pointer by pressing the cancel key on the menu */
} Sysmenu, * lpsysmenu;

When defining a menu, you only need:

Static sysmenu menu [menu_num] =
{
{
"Menu1", 0, 48, menu1onok, menu1oncancel
}
,
{
"Menu2", 7, 48, menu2onok, menu2oncancel
}
,
{
"Menu3", 7, 48, menu3onok, menu3oncancel
}
,
{
"Menu4", 7, 48, menu4onok, menu4oncancel
}
...
};

The processing of the OK key and the cancel key becomes:

/* Press OK */
Void onokkey ()
{
Menu [currentfocusmenu]. onokfun ();
}
/* Press the cancel key */
Void oncancelkey ()
{
Menu [currentfocusmenu]. oncancelfun ();
}

The program has been greatly simplified and has begun to be highly scalable! We only use the encapsulation idea in the object-oriented method to make the program structure clear. The result is that more menus can be added to the system without modifying the program, the system's key processing functions remain unchanged.

Object Oriented, really god!
Simulate the MessageBox Function

MessageBox function, which is a super blockbuster in Windows programming, does not know how many functions are used for the first time. Remember the first time we used MessageBox in Windows to output "Hello, world! "Is it a novelty in the dialog box? No statistics are available. How many programmers in the world learn windows programming from MessageBox ("Hello, world! ",...) . In my undergraduate school, there is a widely used word called "'hello, world' programmers", which means entry-level programmers, But it seems "'hello, world Level "is more funny and vivid.


Figure 2 classic Hello, world!

Figure 2 shows two kinds of the "Hello, world" dialog box of the eternal classic, one is "OK", the other is "OK", and the other is "cancel ". Yes, MessageBox does, and there should be two types! This is entirely determined by specific application requirements.

The embedded system does not provide MessageBox for us. However, given its powerful functions, we need to simulate a simulated MessageBox function:

/*************************************** ***
/* Function name: MessageBox
/* Function Description: the pop-up dialog box displays information to remind users.
/* Parameter description: lpstr --- reminds the user of the string output information
/* Type --- output format (id_ OK = 0, id_okcancel = 1)
/* Return value: return the key value received in the dialog box. There are only two types of key_ OK and key_cancel.
/*************************************** ***
Typedef Enum type {id_ OK, id_okcancel} msg_type;
Extern byte MessageBox (lpbyte lpstr, byte type)
{
Byte keyValue =-1;

Clearscreen ();/* clear screen */
Displaystring (xpos, ypos, lpstr, true);/* display string */
/* Determine whether to display OK or cancel based on the dialog box type */
Switch (type)
{
Case id_ OK:
Displaystring (13, ypos + high + 1, "OK", 0 );
Break;
Case id_okcancel:
Displaystring (8, ypos + high + 1, "OK", 0 );
Displaystring (17, ypos + high + 1, "cancel", 0 );
Break;
Default:
Break;
}
Drawrect (0, 0,239, ypos + high + 16 + 4);/* draw an external frame */
/* MessageBox is a mode dialog box that blocks running and waits for the button */
While (keyValue! = Key_ OK) | (keyValue! = Key_cancel ))
{
KeyValue = getsyskey ();
}
/* Return key type */
If (keyValue = key_ OK)
{
Return id_ OK;
}
Else
{
Return id_cancel;
}
}

The above functions are similar to the MessageBox we use in VC ++? By implementing this function, you will see that it has infinite advantages in embedded systems.

Summary

This article is the seriesArticleIt provides some clever ways to handle the screen display of embedded systems. We will not be troubled by the messy display content on the LCD.

the screen is an important aid to the survival of embedded systems, and the ugly face of the screen will escape other users. If the screen programming is not well handled, it will be the least systematic and chaotic part of the software, and I have suffered a lot from it.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.