TA的每日心情 | 开心 2024-4-26 16:14 |
---|
签到天数: 2 天 [LV.1]初来乍到
新手上路
- 积分
- 23
|
楼主 |
发表于 2024-4-25 09:31:05
|
显示全部楼层
今天上午又研究了一下,把LCD_buff[0]的表格从新做了一遍,然后瞬间看懂了,
原因就在于一个数码管的8,对应2个SEG线,注释的时候像我这样去表示就好理解一点,
原代码的注释,需要自己去找SEG对应的断,如下:
/*
B7 B6 B5 B4 B3 B2 B1 B0
LCD_buff[0]: 2H 3D 1H 2D 左下 1D B1 B0 左下为左下角的箭头, B0为电池框, B1为电量1
LCD_buff[1]: -- -- -- -- 4H 5D 3H 4D
LCD_buff[2]: 3C 3E 2C 2E 1C 1E B2 右上 右上为右上角的箭头, B2为电量2
LCD_buff[3]: -- -- -- -- 5C 5E 4C 4E
LCD_buff[4]: 3B 3G 2B 2G 1B 1G B3 - B3为电量3, -为左边符号
LCD_buff[5]: -- -- -- -- 5B 5G 4B 4G
LCD_buff[6]: 3A 3F 2A 2F 1A 1F B4 左上 左上为左上角的箭头
LCD_buff[7]: -- -- -- -- 5A 5F 4A 4F
*/
早上自己整理了一下,然后我的注释如下:
// 第3个8 第2个8 第1个8 电池电量显示
// | SEG15 SEG14 | SEG13 SEG12 | SEG11 SEG10 | SEG9 SEG8 |
// LCD_buff[0] = |C0S15-2H C0S14-3D |C0S13-1H C0S12-2D |C0S11-LD C0S10-1D| C0S9-B1 C0S8-B0|
// LCD_buff[2] = |C1S15-3C C1S14-3E |C1S13-2C C1S12-2E |C1S11-1C C1S10-1E| C1S9-B2 C1S8-RU|
// LCD_buff[4] = |C2S15-3B C2S14-3G |C2S13-2B C2S12-2G |C2S11-1B C2S10-1G| C2S9-B3 C2S8-* |
// LCD_buff[6] = |C3S15-3A C3S14-3F |C3S13-2A C3S12-2F |C3S11-1A C3S10-1F| C3S9-B4 C3S8-LU|
// 空 空 第5个8 第4个8
// | SEG23 SEG22 | SEG21 SEG20 | SEG19 SEG18 | SEG17 SEG16 |
// LCD_buff[1] = |C0S23-NC C0S22-NC |C0S21-NC C0S20-NC |C0S19-4H C0S18-5D| C0S17-3H C0S16-4D|
// LCD_buff[3] = |C1S23-NC C1S22-NC |C1S21-NC C1S20-NC |C1S19-5C C1S18-5E| C1S17-4C C1S16-4E|
// LCD_buff[5] = |C2S23-NC C2S22-NC |C2S21-NC C2S20-NC |C2S19-5B C2S18-5G| C2S17-4B C2S16-4G|
// LCD_buff[7] = |C3S23-NC C3S22-NC |C3S21-NC C3S20-NC |C3S19-5A C3S18-5F| C3S17-4A C3S16-4F|
这样一来就可以识别SEG线对应数码管的段,根据示例代码所示,继续往下看
u8 code T_LCD_mask[7] = {0x00,0x0C,0x30,0xC0,0x03,0x0C};//选中对应的SEG线CxSx横向2断(CE、BG、AF)填0
u8 code T_LCD_mask7[7] = {0x00,0x04,0x10,0x40,0x01,0x04};//选中对应的SEG线C0Sx断,D断 填0
u8 code T_SEG_ABC[7] = {0x00,0x08,0x20,0x80,0x02,0x08};//选中对应SEG线的C0Sx断,(dp、C、B、A)填1
u8 code T_SEG_DEFG[7] = {0x00,0x04,0x10,0x40,0x01,0x04};//选中对应SEG线的C0Sx断,(D、E、F、G)填1
上面这个数组,定义了每个SEG线纵向给LCD断码填0和填1的对应bit位;
下面这个函数,则根据所需要的对应n个数码管,选中对应的显存LCD_buff[x],去对LCD进行填0,然后需要显示的断填1;
详细可见如下我代入的试数值:
/********************** 装载显示5个8字 *****************************/
void LCD_load(u8 n, u8 dat) //n为第几个数字,为1~5,dat为要显示的数字
{
u8 i,k;
if((n == 0) || (n >= 6)) return; //合法值 1~5
dat = t_display[dat]; //取数字库真值:0-y; 设dat=1,真值=0x06 二进制:0000 0110
k = ~T_LCD_mask[n]; //设n=1 取反0x0c :k = 1111 0011,将LCD_buff[0、2、4、6]对应的第1个8两位对应的SEG10-11位置0
//设n=2 取反0x30 :k = 1100 1111,将LCD_buff[0、2、4、6]对应的第2个8两位对应的SEG12-13位置0
//意为将选中的缓存数组的SEG线,对应8的A-G断 清零
if(n <= 3)//选第1~3个数码管,SEG<=15:对应SEG线为: SEG10-11, SEG12-13, SEG14-15
{ //将A-G 断码清零
LCD_buff[0] &= ~T_LCD_mask7[n]; //04H取反:1111 1011 为 1D 清零
LCD_buff[2] &= k; //设n=1则k=1111 0011 为 1C 1E 清零
LCD_buff[4] &= k; // 同上 1B 1G 清零
LCD_buff[6] &= k; // 同上 1A 1F 清零
//设n=1,i设为SEG11线对应的 LD、1C、1B、1A断码 填1;
i = T_SEG_ABC[n]; //i=08H=0000 1000
//设n=1,i设为SEG10线对应的 1D、1E、1G、1F断码 填1;
k = T_SEG_DEFG[n]; //k=04H=0000 0100
//设dat=06H = 0000 0110 :BC段点亮 显示数字"1"
if(dat & 0x01) LCD_buff[6] |= i; //T_SEG_ABC[n]; //A
if(dat & 0x02) LCD_buff[4] |= i; //T_SEG_ABC[n]; //B
if(dat & 0x04) LCD_buff[2] |= i; //T_SEG_ABC[n]; //C
if(dat & 0x08) LCD_buff[0] |= k; //T_SEG_DEFG[n]; //D
if(dat & 0x10) LCD_buff[2] |= k; //T_SEG_DEFG[n]; //E
if(dat & 0x20) LCD_buff[6] |= k; //T_SEG_DEFG[n]; //F
if(dat & 0x40) LCD_buff[4] |= k; //T_SEG_DEFG[n]; //G
}
else//第4 or 5个数码管,上面指定SEG<=19:对应SEG线为: SEG16-17, SEG18-19
{ //将A-G 断码清零
LCD_buff[1] &= ~T_LCD_mask7[n]; //设n=4 取反01H=1111 1110 断码4D 清零
LCD_buff[3] &= k; //设n=4则k=1111 1100 为 4C 4E 清零
LCD_buff[5] &= k; // 同上 4B 4G 清零
LCD_buff[7] &= k; // 同上 4A 4F 清零
i = T_SEG_ABC[n]; //设n=4,i=02H=0000 0010 断码H C B A 填1
k = T_SEG_DEFG[n]; //设n=4,k=01H=0000 0001 断码D E G F 填1
if(dat & 0x01) LCD_buff[7] |= i; //T_SEG_ABC[n]; //A
if(dat & 0x02) LCD_buff[5] |= i; //T_SEG_ABC[n]; //B
if(dat & 0x04) LCD_buff[3] |= i; //T_SEG_ABC[n]; //C
if(dat & 0x08) LCD_buff[1] |= k; //T_SEG_DEFG[n]; //D
if(dat & 0x10) LCD_buff[3] |= k; //T_SEG_DEFG[n]; //E
if(dat & 0x20) LCD_buff[7] |= k; //T_SEG_DEFG[n]; //F
if(dat & 0x40) LCD_buff[5] |= k; //T_SEG_DEFG[n]; //G
}
} |
|