用ICC7写了一个12864驱动函数,本想用函数指针变量调用函数来减小代码量,但实际代码量却由7%曾大到10%了,不知怎么回事,忘高手解惑??
#include<mytouwenjian.h>
#define ddr_com DDRC|=0X7E //控制口输出
#define RS_COM PORTC&=~bit(4)//命令
#define RS_DATE PORTC|=bit(4)
#define WR_R PORTC|=bit(5)//读
#define WR_W PORTC&=~bit(5)
#define E PORTC|=bit(6)//使能
#define E_N PORTC&=~bit(6)
#define PSB_B PORTC|=bit(1)//并口模式
#define PSB_C PORTC&=~bit(1)
#define RET PORTC&=~bit(3)//复位 低电平有效
#define RET_N PORTC|=bit(3)
#define ddr PORTA //数据口
#define ddr_r PINA //读引脚
#define ddr_in DDRA=0//数据口输入
#define ddr_out DDRA=0xff //数据口输出
void wrie_com12864(uchar com);//写指令
void wrie_date12864(uchar date);//写8位数据
void inlist12864();//初始化
void write_lianxu12864(uchar date[],uchar lenth);//连续写数据
uchar read_date12864( );//读8位数据
uchar read_mang12864( );//读忙
void huitu_dadian12864(uchar dress_x,uchar dress_y);//任意位置打点函数x(0--127) y(0--63)
void huitu_inlist12864();
void write_changfangxing(uchar start_x,uchar start_y,uchar lang,uchar waite);//画方形 16位起始位置 长和宽
void main()
{
uchar n,nn,mm,aa[]="任意打点",bb[]="Good";
inlist12864();
huitu_inlist12864();
write_changfangxing(3,3,122,58);
write_changfangxing(10,10,108,44);
for(nn=0;nn<20;nn++) huitu_dadian12864(30+nn,30+nn);
write_changfangxing(28,28,21,21);
write_changfangxing(55,23,21,21);
write_changfangxing(10,18,108,0);
write_changfangxing(90,10,0,44);
write_changfangxing(93,25,20,5);
write_changfangxing(103,32,5,20);
/*
n=sizeof(aa)-1;//计算数组长度
wrie_com12864(0x82);
write_lianxu12864(aa,n);
n=sizeof(bb)-1;//计算数组长度
wrie_com12864(0x93);
write_lianxu12864(bb,n);*/
}
void wrie_com12864(uchar com)//写指令
{
while(read_mang12864( ));//读忙
ddr_out;
RS_COM;
WR_W;
E;
ddr=com;
yanshi_5us(1);
E_N;
}
void wrie_date12864(uchar date)//写8位数据
{
while(read_mang12864( ));//读忙
ddr_out;
RS_DATE;
WR_W;
E;
ddr=date;
yanshi_5us(1);
E_N;
}
uchar read_date12864( )//读8位数据
{
uchar date;
while(read_mang12864( ));//读忙
ddr_in;
RS_DATE;
WR_R;
E_N;
E;
yanshi_5us(1);
date=ddr_r;
E_N;
return date;
}
uchar read_mang12864( )//读忙
{
uchar com;
ddr_in;
RS_COM;
WR_R;
E_N;
E;
yanshi_5us(1);
com=ddr_r;
E_N;
com&=0x80;//返回0或者非0
return com;
}
void inlist12864()//初始化
{
yanshi_1ms(20);
ddr_com;//控制口设置为输出
RET; //复位
RET_N;
PSB_B;//并口
wrie_com12864(0x30);
yanshi_1ms(10);
wrie_com12864(0x30);
yanshi_1ms(10);
wrie_com12864(0x0c);//整体显示 不显示光标
yanshi_1ms(10);
wrie_com12864(0x01);//清屏
yanshi_1ms(10);
wrie_com12864(0x06);//光标右移
yanshi_1ms(10);
}
void write_lianxu12864(uchar date[],uchar lenth)//连续写数据
{
uchar n;
for(n=0;n<lenth;n++)
wrie_date12864(date[n]);
}
void huitu_inlist12864()
{
uchar n,m;
wrie_com12864(0x34);//绘图功能 显示关
for(n=0;n<32;n++)
{
wrie_com12864(0x80+n);//先写Y轴地址
wrie_com12864(0x80); //再写X轴地址(连续 前面不能有语句)显示数据写完后X轴地址自动加一
for(m=0;m<16;m++)
{
wrie_date12864(0x00);
wrie_date12864(0x00);
}
}
wrie_com12864(0x36);//绘图功能 显示开
wrie_com12864(0x32);//返回基本功能 显示开
}
void huitu_dadian12864(uchar dress_x,uchar dress_y)//任意位置打点函数
{
uchar d_x,d_y,dat,dress_date_l,dress_date_h;
wrie_com12864(0x34);//绘图功能 显示关
/************************计算打点位置************************/
if(dress_y<32)//判断上半屏
{
d_y=dress_y; //判断dress_y在Y轴位置0--31
if(dress_x<15) d_x=0;//判断dress_x在X轴位置
else d_x=dress_x/16; //X轴上半屏位置0--7
}
else //判断下半屏
{
d_y=dress_y-32;
if(dress_x<15) d_x=8;
else d_x=dress_x/16+8;//X轴下半屏位置8--15
}
wrie_com12864(0x80+d_y);
wrie_com12864(0x80+d_x);
/***********************计算打点数据************************/
dat=dress_x%16;//得到点位置16位粗数据
if(dat<8) //点在高字节
{
dat=bit(7-dat);//原dat为高位点 须倒位
/* 处理数据实现打点时不对旁边位置数据有影响*/
dress_date_h=read_date12864( );//假读
dress_date_h=read_date12864( );//读当前位置数据
dress_date_l=read_date12864( );//读当前位置数据
dress_date_h=dat|dress_date_h;
wrie_com12864(0x80+d_y);//读数据导致地址改变 须重新设置地址
wrie_com12864(0x80+d_x);
wrie_date12864(dress_date_h); //先写高位再写低位
wrie_date12864(dress_date_l);
}
else //点在低字节
{
dat=dat%8;
dat=bit(7-dat);//倒位
dress_date_h=read_date12864( );//假读
dress_date_h=read_date12864( );//读当前位置数据
dress_date_l=read_date12864( );//读当前位置数据
dress_date_l=dat|dress_date_l;
wrie_com12864(0x80+d_y);
wrie_com12864(0x80+d_x);
wrie_date12864(dress_date_h);
wrie_date12864(dress_date_l);
}
wrie_com12864(0x36);//绘图功能 显示开
wrie_com12864(0x32);//返回基本功能 显示开
}
void write_changfangxing(uchar start_x,uchar start_y,uchar lang,uchar waite)//16位起始位置 长和宽
{
uchar n;
//huitu_dadian12864(start_x,start_y);//任意位置打点函数
for(n=0;n<=lang;n++) huitu_dadian12864(start_x+n,start_y);//水平画线
for(n=0;n<=lang;n++) huitu_dadian12864(start_x+n,start_y+waite);
for(n=0;n<=waite;n++) huitu_dadian12864(start_x,start_y+n);//垂直画线
for(n=0;n<=waite;n++) huitu_dadian12864(start_x+lang,start_y+n);
}
下面使用了函数指针变量来调用函数
#include<mytouwenjian.h>
#define ddr_com DDRC|=0X7E //控制口输出
#define RS_COM PORTC&=~bit(4)//命令
#define RS_DATE PORTC|=bit(4)
#define WR_R PORTC|=bit(5)//读
#define WR_W PORTC&=~bit(5)
#define E PORTC|=bit(6)//使能
#define E_N PORTC&=~bit(6)
#define PSB_B PORTC|=bit(1)//并口模式
#define PSB_C PORTC&=~bit(1)
#define RET PORTC&=~bit(3)//复位 低电平有效
#define RET_N PORTC|=bit(3)
#define ddr PORTA //数据口
#define ddr_r PINA //读引脚
#define ddr_in DDRA=0//数据口输入
#define ddr_out DDRA=0xff //数据口输出
void (*p_hanshu)(uchar);//定义全局函数指针变量
uchar (*pp_hanshu)();
void (*ppp_hanshu)(uchar,uchar);
void wrie_com12864(uchar com);//写指令
void wrie_date12864(uchar date);//写8位数据
void inlist12864();//初始化
void write_lianxu12864(uchar date[],uchar lenth);//连续写数据
uchar read_date12864( );//读8位数据
uchar read_mang12864( );//读忙
void huitu_dadian12864(uchar dress_x,uchar dress_y);//任意位置打点函数
void huitu_inlist12864();
void write_changfangxing(uchar start_x,uchar start_y,uchar lang,uchar waite);//16位起始位置 长和宽
void main()
{
uchar n,nn,mm,aa[]="任意打点",bb[]="Good";
inlist12864();
huitu_inlist12864();
write_changfangxing(3,3,122,58);
write_changfangxing(10,10,108,44);
for(nn=0;nn<20;nn++) huitu_dadian12864(30+nn,30+nn);
write_changfangxing(28,28,21,21);
write_changfangxing(55,23,21,21);
write_changfangxing(10,18,108,0);
write_changfangxing(90,10,0,44);
write_changfangxing(93,25,20,5);
write_changfangxing(103,32,5,20);
/*
n=sizeof(aa)-1;//计算数组长度
wrie_com12864(0x82);
write_lianxu12864(aa,n);
n=sizeof(bb)-1;//计算数组长度
wrie_com12864(0x93);
write_lianxu12864(bb,n);*/
}
void wrie_com12864(uchar com)//写指令
{
pp_hanshu=read_mang12864;//将读忙函数地址给函数指针变量
while(*pp_hanshu);//调用读忙函数
ddr_out;
RS_COM;
WR_W;
E;
ddr=com;
yanshi_5us(1);
E_N;
}
void wrie_date12864(uchar date)//写8位数据
{
pp_hanshu=read_mang12864;//将读忙函数地址给函数指针变量
while(*pp_hanshu);//调用读忙函数
ddr_out;
RS_DATE;
WR_W;
E;
ddr=date;
yanshi_5us(1);
E_N;
}
uchar read_date12864( )//读8位数据
{
uchar date;
pp_hanshu=read_mang12864;//将读忙函数地址给函数指针变量
while(*pp_hanshu);//调用读忙函数
ddr_in;
RS_DATE;
WR_R;
E_N;
E;
yanshi_5us(1);
date=ddr_r;
E_N;
return date;
}
uchar read_mang12864( )//读忙
{
uchar com;
ddr_in;
RS_COM;
WR_R;
E_N;
E;
yanshi_5us(1);
com=ddr_r;
E_N;
com&=0x80;//返回0或者非0
return com;
}
void inlist12864()//初始化
{
p_hanshu=wrie_com12864;
yanshi_1ms(20);
ddr_com;//控制口设置为输出
RET; //复位
RET_N;
PSB_B;//并口
(*p_hanshu)(0x30);
yanshi_1ms(10);
(*p_hanshu)(0x30);
yanshi_1ms(10);
(*p_hanshu)(0x0c);//整体显示 不显示光标
yanshi_1ms(10);
(*p_hanshu)(0x01);//清屏
yanshi_1ms(10);
(*p_hanshu)(0x06);//光标右移
yanshi_1ms(10);
}
void write_lianxu12864(uchar date[],uchar lenth)//连续写数据
{
uchar n;
p_hanshu=wrie_date12864;
for(n=0;n<lenth;n++)
(*p_hanshu)(date[n]);
}
void huitu_inlist12864()
{
uchar n,m;
p_hanshu=wrie_com12864;
(*p_hanshu)(0x34);//绘图功能 显示关
for(n=0;n<32;n++)
{
p_hanshu=wrie_com12864;
(*p_hanshu)(0x80+n);//先写Y轴地址
(*p_hanshu)(0x80); //再写X轴地址(连续 前面不能有语句)显示数据写完后X轴地址自动加一
for(m=0;m<16;m++)
{
p_hanshu=wrie_date12864;
(*p_hanshu)(0x00);
(*p_hanshu)(0x00);
}
}
p_hanshu=wrie_com12864;
(*p_hanshu)(0x36);//绘图功能 显示开
(*p_hanshu)(0x32);//返回基本功能 显示开
}
void huitu_dadian12864(uchar dress_x,uchar dress_y)//任意位置打点函数
{
uchar d_x,d_y,dat,dress_date_l,dress_date_h;
p_hanshu=wrie_com12864;
(*p_hanshu)(0x34);//绘图功能 显示关
/************************计算打点位置************************/
if(dress_y<32)//判断上半屏
{
d_y=dress_y; //判断dress_y在Y轴位置0--31
if(dress_x<15) d_x=0;//判断dress_x在X轴位置
else d_x=dress_x/16; //X轴上半屏位置0--7
}
else //判断下半屏
{
d_y=dress_y-32;
if(dress_x<15) d_x=8;
else d_x=dress_x/16+8;//X轴下半屏位置8--15
}
(*p_hanshu)(0x80+d_y);
(*p_hanshu)(0x80+d_x);
/***********************计算打点数据************************/
dat=dress_x%16;//得到点位置16位粗数据
if(dat<8) //点在高字节
{
pp_hanshu=read_date12864;
dat=bit(7-dat);//原dat为高位点 须倒位
dress_date_h=(*pp_hanshu)( );//假读
dress_date_h=(*pp_hanshu)( );//读当前位置数据
dress_date_l=(*pp_hanshu)( );//读当前位置数据
dress_date_h=dat|dress_date_h;
p_hanshu=wrie_com12864;
(*p_hanshu)(0x80+d_y);//读数据导致地址改变 须重新设置地址
(*p_hanshu)(0x80+d_x);
p_hanshu=wrie_date12864;
(*p_hanshu)(dress_date_h); //先写高位再写低位
(*p_hanshu)(dress_date_l);
}
else //点在低字节
{
dat=dat%8;
dat=bit(7-dat);//倒位
pp_hanshu=read_date12864;
dress_date_h=(*pp_hanshu)( );//假读
dress_date_h=(*pp_hanshu)( );//读当前位置数据
dress_date_l=(*pp_hanshu)( );//读当前位置数据
dress_date_l=dat|dress_date_l;
p_hanshu=wrie_com12864;
(*p_hanshu)(0x80+d_y);
(*p_hanshu)(0x80+d_x);
p_hanshu=wrie_date12864;
(*p_hanshu)(dress_date_h);
(*p_hanshu)(dress_date_l);
}
p_hanshu=wrie_com12864;
(*p_hanshu)(0x36);//绘图功能 显示开
(*p_hanshu)(0x32);//返回基本功能 显示开
}
void write_changfangxing(uchar start_x,uchar start_y,uchar lang,uchar waite)//16位起始位置 长和宽
{
uchar n;
//huitu_dadian12864(start_x,start_y);//任意位置打点函数
ppp_hanshu=huitu_dadian12864;
for(n=0;n<=lang;n++) (*ppp_hanshu)(start_x+n,start_y);//水平画线
for(n=0;n<=lang;n++) (*ppp_hanshu)(start_x+n,start_y+waite);
for(n=0;n<=waite;n++) (*ppp_hanshu)(start_x,start_y+n);//垂直画线
for(n=0;n<=waite;n++) (*ppp_hanshu)(start_x+lang,start_y+n);
}
|
|