📄 lcd106x56.c
字号:
remaining_bits = 8;
byte_offset++;
mask = l_mask_array[0];
}
}
}
}
void lcd_vert_dotline(unsigned char top, unsigned char bottom,
unsigned char column)
{
unsigned char bit_pos;
unsigned char byte_offset;
unsigned char y_bits;
unsigned char remaining_bits;
unsigned char mask;
bit_pos = top & 0x07; /* get starting bit offset into byte */
byte_offset = top >> 3; /* get byte offset into y direction */
y_bits = (bottom - top) + 1; /* get length in the x direction to write */
remaining_bits = 8 - bit_pos; /* number of bits left in byte */
mask = l_mask_array[bit_pos]; /* get mask for this bit */
while(y_bits) /* while there are still bits to write */
{
if((remaining_bits == 8) && (y_bits > 7))
{
/* here if we are byte aligned and have at least 1 byte to write */
/* do the entire byte at once instead of bit by bit */
while(y_bits > 7) /* while there are at least 8 more bits to do */
{
l_display_array[byte_offset][column] = 0x55;
byte_offset++;
y_bits -= 8;
}
}
else
{
/* we are not byte aligned or an entire byte does not need written */
/* do each individual bit */
if (mask & 0x55)
l_display_array[byte_offset][column] |= mask;
if(l_mask_array[0] & 0x80)
mask >>= 1;
else
mask <<= 1;
y_bits--;
remaining_bits--;
if(remaining_bits == 0)
{
/* might have bust gotton byte aligned */
/* so reset for beginning of a byte */
remaining_bits = 8;
byte_offset++;
mask = l_mask_array[0];
}
}
}
}
/*
**
** Clears a line into the display memory starting at left going to
** right, on the given row. No runtime error checking is performed.
** It is assumed that left is less than right.
**
*/
void lcd_clr_horz_line(unsigned char left, unsigned char right,
unsigned char row)
{
unsigned char bit_pos;
unsigned char byte_offset;
unsigned char mask;
unsigned char col;
bit_pos = row & 0x07; /* get the bit offset into a byte */
byte_offset = row >> 3; /* get the byte offset into x array */
mask = l_mask_array[bit_pos]; /* get the mask for this bit */
for(col = left; col <= right; col++)
{
l_display_array[byte_offset][col] &= ~mask;
}
}
/*
**
** Clears a vertical line into display memory starting at the top
** going to the bottom in the given column. No runtime error checking
** is performed. It is assumed that top is less than bottom and that
** the column is in range.
**
*/
void lcd_clr_vert_line(unsigned char top, unsigned char bottom,
unsigned char column)
{
unsigned char bit_pos;
unsigned char byte_offset;
unsigned char y_bits;
unsigned char remaining_bits;
unsigned char mask;
bit_pos = top & 0x07; /* get starting bit offset into byte */
byte_offset = top >> 3; /* get byte offset into y direction */
y_bits = (bottom - top) + 1; /* get length in the x direction to write */
remaining_bits = 8 - bit_pos; /* number of bits left in byte */
mask = l_mask_array[bit_pos]; /* get mask for this bit */
while(y_bits) /* while there are still bits to write */
{
if((remaining_bits == 8) && (y_bits > 7))
{
/* here if we are byte aligned and have at least 1 byte to write */
/* do the entire byte at once instead of bit by bit */
while(y_bits > 7) /* while there are at least 8 more bits to do */
{
l_display_array[byte_offset][column] = 0x00;
byte_offset++;
y_bits -= 8;
}
}
else
{
/* we are not byte aligned or an entire byte does not need written */
/* do each individual bit */
l_display_array[byte_offset][column] &= ~mask;
if(l_mask_array[0] & 0x80)
mask >>= 1;
else
mask <<= 1;
y_bits--;
remaining_bits--;
if(remaining_bits == 0)
{
/* might have bust gotton byte aligned */
/* so reset for beginning of a byte */
remaining_bits = 8;
byte_offset++;
mask = l_mask_array[0];
}
}
}
}
/*
**
** Draws a box in display memory starting at the left/top and going
** to the right/bottom. No runtime error checking is performed.
** It is assumed that left is less than right and that top is less
** than bottom.
**
*/
void lcd_box(unsigned char left, unsigned char top,
unsigned char right, unsigned char bottom)
{
/* to draw a box requires two vertical lines */
lcd_vert_line(top,bottom,left);
lcd_vert_line(top,bottom,right);
/* and two horizonal lines */
lcd_horz_line(left,right,top);
lcd_horz_line(left,right,bottom);
}
void lcd_bar(unsigned char left, unsigned char top, unsigned char bottom)
{
lcd_vert_line(top,bottom,left);
lcd_vert_line(top,bottom,left+1);
lcd_vert_line(top,bottom,left+2);
lcd_vert_line(top,bottom,left+3);
lcd_vert_line(top,bottom,left+4);
}
/*
**
** Clears a box in display memory starting at the Top left and going
** to the bottom right. No runtime error checking is performed and
** it is assumed that Left is less than Right and that Top is less
** than Bottom.
**
*/
void lcd_clr_box(unsigned char left, unsigned char top,
unsigned char right, unsigned char bottom)
{
/* to undraw the box undraw the two vertical lines */
lcd_clr_vert_line(top,bottom,left);
lcd_clr_vert_line(top,bottom,right);
/* and the two horizonal lines that comprise it */
lcd_clr_horz_line(left,right,top);
lcd_clr_horz_line(left,right,bottom);
}
/*
**
** Writes a glyph to the display at location x,y
**
** Arguments are:
** column - x corrdinate of the left part of glyph
** row - y coordinate of the top part of glyph
** width - size in pixels of the width of the glyph
** height - size in pixels of the height of the glyph
** glyph - an unsigned char pointer to the glyph pixels
** to write assumed to be of length "width"
**
*/
void lcd_glyph(unsigned char left, unsigned char top,
unsigned char width, unsigned char height,
unsigned char *glyph, unsigned char store_width)
{
unsigned char bit_pos;
unsigned int byte_offset;
unsigned char y_bits;
unsigned int remaining_bits;
unsigned char mask;
unsigned char char_mask;
unsigned char x;
unsigned char *glyph_scan;
unsigned int glyph_offset;
bit_pos = top & 0x07; /* get the bit offset into a byte */
glyph_offset = 0; /* start at left side of the glyph rasters */
char_mask = 0x80; /* initial character glyph mask */
for (x = left; x < (left + width); x++)
// for (x = (left+width); x > left; x--)
{
byte_offset = top >> 3; /* get the byte offset into y direction */
y_bits = height; /* get length in y direction to write */
remaining_bits = 8 - bit_pos; /* number of bits left in byte */
mask = l_mask_array[bit_pos]; /* get mask for this bit */
glyph_scan = glyph + glyph_offset; /* point to base of the glyph */
/* boundary checking here to account for the possibility of */
/* write past the bottom of the screen. */
// while((y_bits) && (byte_offset < Y_BYTES)) /* while there are bits still to write CLM*/
while (y_bits) /* while there are bits still to write */
{
/* check if the character pixel is set or not */
if(*glyph_scan & char_mask)
l_display_array[byte_offset][x] |= mask; /* set image pixel */
// else
// l_display_array[byte_offset][x] &= ~mask; /* clear the image pixel */
mask <<= 1; // CLM
y_bits--;
remaining_bits--;
if(remaining_bits == 0)
{
/* just crossed over a byte boundry, reset byte counts */
remaining_bits = 8;
byte_offset++;
mask = l_mask_array[0];
}
/* bump the glyph scan to next raster */
glyph_scan += store_width;
}
/* shift over to next glyph bit */
char_mask >>= 1;
if(char_mask == 0) /* reset for next byte in raster */
{
char_mask = 0x80;
glyph_offset++;
}
}
}
unsigned char lcd_text_align(unsigned char left, unsigned char top, unsigned char font, char *str, unsigned char Align)
{
unsigned char width, TotalWidth;
unsigned char glyph;
char *n;
BCSCTL2 = SELM_3+DIVM_0; // MCLK = XT1 div 0 (7.3728 MHz), SMCLK fra DCO
TotalWidth = 0;
n = str; // Gem start pointer
while (*str != 0x00)
{
glyph = (unsigned char)*str;
glyph = fonts[font]->mapping_table[glyph];
width = fonts[font]->glyph_width; /* check if it is a fixed width */
if (width == 0)
width = fonts[font]->width_table[glyph]; /* get the variable width instead */
TotalWidth += width;
str++; /* point to next character in string */
}
if (Align == 0)
{
glyph = left-TotalWidth;
lcd_text(glyph,top,font,n);
}
if (Align == 1)
glyph = lcd_text(left-(TotalWidth / 2),top,font,n);
BCSCTL2 = SELM_3+DIVM_1; // MCLK = XT1 div 2 (3.6864 MHz), SMCLK fra DCO
return (glyph);
}
unsigned char lcd_text(unsigned char left, unsigned char top, unsigned char font, char *str)
{
unsigned char x = left;
unsigned char glyph;
unsigned char width;
unsigned char height;
unsigned char store_width;
unsigned char *glyph_ptr;
unsigned char leading = 0;
unsigned char trailing = 0;
int offset;
BCSCTL2 = SELM_3+DIVM_0; // MCLK = XT1 div 0 (7.3728 MHz), SMCLK fra DCO
while(*str != 0x00)
{
glyph = (unsigned char)*str;
glyph = fonts[font]->mapping_table[glyph];
width = fonts[font]->glyph_width; /* check if it is a fixed width */
if (width == 0)
width = fonts[font]->width_table[glyph]; /* get the variable width instead */
height = fonts[font]->glyph_height;
store_width = width >> 3;
if (width & 0x07)
store_width++;
offset = fonts[font]->offset_table[glyph];
glyph_ptr = fonts[font]->glyph_table + offset;
/* range check / limit things here */
if(x > SCRN_RIGHT)
x = SCRN_RIGHT;
if((x + width) > SCRN_RIGHT+1)
width = SCRN_RIGHT - x + 1;
if(top > SCRN_BOTTOM)
top = SCRN_BOTTOM;
if((top + height) > SCRN_BOTTOM+1)
height = SCRN_BOTTOM - top + 1;
if (fonts[font]->detail_table)
{
leading = fonts[font]->detail_table[glyph].leading;
trailing = fonts[font]->detail_table[glyph].trailing;
height = trailing - leading + 1;
}
lcd_glyph(x, top + leading, width, height, glyph_ptr, store_width); /* plug symbol into buffer */
x += width; /* move right for next character */
str++; /* point to next character in string */
}
BCSCTL2 = SELM_3+DIVM_1; // MCLK = XT1 div 2 (3.6864 MHz), SMCLK fra DCO
if (x > MaxX)
MaxX = x;
return (x);
}
void lcd_pic(unsigned char left, unsigned char top, struct IMG_DEF *img)
{
unsigned char width = img->width_in_pixels;
unsigned char height = img->height_in_pixels;
unsigned char *glyph = img->char_table;
unsigned char store_width = (width + 7) >> 3;
lcd_glyph(left,top,width,height,glyph,store_width); /* plug symbol into buffer */
}
void DrawCircle(unsigned char mx, unsigned char my, unsigned char r)
{
/*
A first point of the circle is x=r,y=0.
For a closed circle boundary line, the next possible point is either
the left neighbour (x-1,y) or the lower neighbour (x,y+1).
We insert x and y into the circles defining equation x*x+y*y=r*r to
calculate radius error. Whichever gives less error is the better point
for the circle. From this we calculate again the best neighbour. For
symmetry reasons, we only need do do it for an eighth of the circle
and mirror it.
*/
int x=r,
y=0,
nrx, // new sqared radius if we dec x
nry, // new sqared radius if we inc y
erx, // error if we dec x
ery, // error if we inc y
r2=r*r, // square of r
ar2=r2; // radius of a circle that goes through last drawn point
do{
lcd_dot(mx+x, my+y);
lcd_dot(mx+x, my-y);
lcd_dot(mx-x, my+y);
lcd_dot(mx-x, my-y);
lcd_dot(mx+y, my+x);
lcd_dot(mx+y, my-x);
lcd_dot(mx-y, my+x);
lcd_dot
(mx-y, my-x);
nry=ar2+2*y+1; // if we inc y nyr=(y+1)^2+x^2 = y^2+2y+1+x^2 = r^2+2y+1
nrx=ar2-2*x+1; // if we dec x nxr=y^2+(x-1)^2 = y^2+x^2-2x-1 = r^2-2x+1
ery=r2-nry; if (ery<0) ery=-ery;
erx=r2-nrx; if (erx<0) erx=-erx;
if (ery<erx) {
y++;
ar2=nry;
} else {
x--;
ar2=nrx;
}
} while (x>=y);
}
/*
**
** Updates area of the display. Writes data from display
** RAM to the lcd display controller.
**
** Arguments Used:
** top top line of area to update.
** bottom bottom line of area to update.
**
*/
//void lcd_update(unsigned char Left, unsigned char top, unsigned Right, unsigned char bottom)
//{
// lcd_clear_area(150, 58, SCRN_RIGHT, SCRN_BOTTOM);
// DispChar(Mode, 0);
// lcd_text_align(157,57,SN5,&DispBuffer[0], CENTRE);
// lcd_update1(Left, top, Right, bottom);
// lcd_update1(150, 57, SCRN_RIGHT, SCRN_BOTTOM);
//}
void lcd_update(unsigned char Left, unsigned char top, unsigned Right, unsigned char bottom)
{
unsigned char x;
unsigned char y;
unsigned char yt;
unsigned char yb;
unsigned char *colptr;
unsigned char Data;;
BCSCTL2 = SELM_3+DIVM_0; // MCLK = XT1 div 0 (7.3728 MHz), SMCLK fra DCO
yt = top >> 3; /* setup bytes of range */
yb = bottom >> 3;
for(y = yt; y <= yb; y++)
{
/* setup the page number for the y direction */
Data = LCD_SET_PAGE+y;
P4OUT &= ~0x68; // A0, WE, CS lav
P5OUT = Data;
P4OUT |= 0xC8; // CS, WR, RD h鴍
/* setup column of update to left side */
Data = LCD_SET_COL_HI+((Left + 0x02) >> 4);
P4OUT &= ~0x68; // A0, WE, CS lav
P5OUT = Data;
P4OUT |= 0xC8; // CS, WR, RD h鴍
Data = LCD_SET_COL_LO+((Left + 0x02) & 0x0F);
P4OUT &= ~0x68; // A0, WE, CS lav
P5OUT = Data;
P4OUT |= 0xC8; // CS, WR, RD h鴍
P4OUT |= 0x20; // A0 h鴍
colptr = &l_display_array[y][Left];
for (x=0; x < (Right-Left)+1; x++)
{
Data = *colptr++;
P4OUT &= ~0x48; // WE, CS lav
P5OUT = Data;
P4OUT |= 0xC8; // CS, WR, RD h鴍
}
}
if (Flags2 & DISPBLINK)
{
if (!(Flags2 & BLINKON))
DispSendCmd(0xA8); // Standby
else
DispSendCmd(0xE1); // Reset standby
}
else
DispSendCmd(0xE1); // Reset standby
BCSCTL2 = SELM_3+DIVM_1; // MCLK = XT1 div 2 (3.6864 MHz), SMCLK fra DCO
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -