张三是一位刚参加工作不久的单片机工程师,就职于能力有限公司。
这天,老板给了一个任务,给他们公司的产品增加一个液晶屏LCD1602,显示五个页面,可通过上下按键进行切换。
张三心想,这简单啊。于是定义了五个2*16的二维数组A、B、C、D、E,同时定义了一个变量page,按一下+键,page加一,按一下-键,page减一。page值最大到4,最小为0.
0对应数组A,1对应数组B,依次类推。例如,数组A如下:
uint8_t A[2][16] = {
{"nengliyouxian "},
{"chanpinniubi "},
};
显示函数如下:
if(page == 0)
{
for(i=0;i<4;i++)
{
Lcd1602A_SetPoint(i+1,0);
Lcd1602A _DisplayString(16,A[i]);
}
}
else if(Page == 1)
{
for(i=0;i<4;i++)
{
Lcd1602A _SetPoint(i+1,0);
Lcd1602A _DisplayString(16,B[i]);
}
}
……………..
代码很快写完了,很顺利。但是老板是个想法很多的人,时不时的会让张三调整显示的顺序,或者增加一个页面,又或者减少一个页面。
于是张三经常要调整page值和数组的对应关系,增加或减少显示页面的函数。
这时保洁阿姨过来,看了一眼,说:
你定义一个指针数组,把这几个页面数组的首地址按顺序存下来,显示页面的时候通过页面数组的首地址来显示就行了,显示函数就不用写那么麻烦了。调整页面顺序的话,修改指针数组里的顺序就行了!
张三说:阿姨,我不太会用指针………….
阿姨:很简单,RAM其实和单元楼很像,变量地址就是门牌号A-1-301,变量名就是这个地址里住的人的姓名。通过变量名取值就是通过姓名获取这个人对应的年龄,通过地址取值就是通过地址获取这里住的人的年龄。例如:
unsigned char a = 0;
unsigned char *p;
p = &a;
定义变量的时候,前面加个*,就是指针变量。给指针变量赋值的时候,两者必须是同类型,都是char、int。变量前面加个&,表示获取这个变量的地址,然后就存进p里了。
张三:所以p里面现在是个地址?那怎么得到这个地址对应的变量值?
阿姨:很简单,定义一个同类型变量b,b = * p; 就完了。
张三:这么简单?
阿姨:就这么简单!小伙子没事别老坐着,多爬爬楼就懂了。
所以程序改成了这样,首先是指针数组(存储指针的数组):
uint8_t *page_p[5]; //5个页面
然后给数组赋初值:
page_p[0] = A[0]; //A0表示二维数组A的首地址
page_p[1] = B[0];
page_p[2] = C[0];
page_p[3] = C[0];
page_p[3] = E[0];
然后是显示函数:
void display_page(uint8_t *page_num)
{
Lcd1602A _SetPoint(1,0);
Lcd1602A _DisplayString(16,page_num);
Lcd1602A _SetPoint(2,0);
Lcd1602A _DisplayString(16,page_num + 16);
}
如果要显示页面A,只需要给i赋值0:
display_page(page_p[i]);
B、C、D、E同理。
从此,张三变成了一个爱爬楼的单片机工程师。
未完………
呵呵,能力有限~