找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3656|回复: 4
收起左侧

比较全的lcd12864 51单片机并口驱动

[复制链接]
ID:162136 发表于 2017-10-3 13:33 | 显示全部楼层 |阅读模式
包括以下程序,算比较全的程序,除了卷动外
void LCD12864_Init(void);                                                                //初始化
void LCD12864_RBY(void);                                                                //读忙碌标记位
void LCD12864_WCmd(uchar cmd);                                                        //写命令
void LCD12864_WDat(uchar dat);                                                        //写数据
void LCD12864_Pos(uchar x,uchar y);                                                //位置
void LCD12864_WnDat(uchar* pBuff,uchar bytes);                        //写多个数据bytes=0:到‘\0’停,bytes!=0:数量
void LCD12864_InverseDDRam(uchar line);                                        //DDRam 反白显示
void LCD12864_DisDec(unsigned long number,uchar width);        //十进制显示一个数,width 为位数
void LCD12864_DisHex(unsigned long number,uchar width);        //十六进制显示一个数,width 为位数

void LCD12864_ClrGDRam(void);                                                                                //清绘图 GDRAM
uchar LCD12864_RDat(void);                                                                                        //读数据
void LCD12864_WGDRam(uchar x,uchar y,uchar mode);                                        //写入一个点到 GDRAM 绘图
void LCD12864_InverseGDRam(uchar sx,uchar sy,uchar ex,uchar ey);        //GDRam 反白显示
void LCD12864_DrawLine(uchar x1, uchar y1, uchar x2, uchar y2);                //画线
void LCD12864_DrawRectangle(uchar x1, uchar y1, uchar x2, uchar y2);//画矩形
void LCD12864_DrawCircle(uchar x,uchar y,uchar r);                                        //在指定位置画一个指定大小的圆
void LCD12864_DrawChar(uchar x,uchar y,uchar ascii,uchar size);                //画 ASCII 字符
void LCD12864_DrawnChar(uchar x,uchar y,uchar* pBuff,uchar bytes,uchar size);//画多个 ASCII 字符

void LCD12864_WCGRamLine(uchar addr,uint num);                                                //写入 1 个 16 位数据到 CGRam
void LCD12864_WCGRamBlock(uchar addr,uchar* pBuff,uchar mode);                //写入 16*16 位,一个块的数据
void LCD12864_DisCGRam(uchar addr);                                                                        //显示 CGRam 字符(自造字符)
void LCD12864_InverseCGRam(uchar addr,uchar mode);                                        //CGRam 反白显示

lcd2864

lcd2864

lcd12864 带中文字库 并口驱动.zip

11.13 KB, 下载次数: 37, 下载积分: 黑币 -5

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:162136 发表于 2017-10-6 12:34 | 显示全部楼层
//十进制显示一个数
//number(32位数) 范围: 0-4294967295(0xffffffff)
//width 为所占宽度
//width 范围: 0-10
void LCD12864_DisDec(unsigned long number,uchar width)        //十进制显示一个数,width 为所占宽度
{
        uchar i,num,fign = 0;
        unsigned long temp = 1;
        if((width == 0) || (width > 10)) return;                        //显示宽度(倍数)超范围直接返回
        if((width == 10) && (number > 999999999))                        //如果显示到 10 位并且有数值
        {
                LCD12864_WDat((number / 1000000000) + '0');
                width--;
                fign = 1;                                                                                //表示前面已有非 0 值
        }
        i = width-1;
        while(i--) temp *= 10;                                                                //显示余下最多 9 位
//        if(number / temp) fign = 1;                                                        //表示前面已有非 0 值
        for(i=width; i>1; i--)
        {
                num = ((number % (temp*10)) / temp);
                if(fign | num)                                                                        //前面有非 0 值或者当前是非 0 值
                {
                        LCD12864_WDat(num + '0');
                        fign = 1;
                }
                else LCD12864_WDat(' ');                                                //前面到当前都是非 0 值,显示空格
                temp /= 10;
        }
        LCD12864_WDat((number %10) + '0');                                        //最小位显示
}
//十六进制显示一个数
//number(32位数) 范围: 0x00000000-0xffffffff(4294967295)
//width 为所占宽度
//width 范围: 0-8
void LCD12864_DisHex(unsigned long number,uchar width)        //十六进制显示一个数,width 为所占宽度
{
        uchar i,temp,fign;
        if((width ==0) || (width >8)) return;                                //显示宽度(倍数)超出直接返回
        if(number & 0xf0000000) fign=1;
        else fign = 0;
        for(i = width -1; i>0; i--)
        {
                temp = (number >> (i*4)) &0x0f;
                if(fign | temp)
                {
                        if(temp >9) temp = temp -10+ 'A';
                        else temp = temp + '0';
                        LCD12864_WDat(temp);
                        fign = 1;
                }
                else LCD12864_WDat(' ');                                                //前面到当前都是非 0 值,显示空格
        }
        temp = (number & 0x0f);
        if(temp >9) temp = temp -10+ 'A';
        else temp = temp + '0';
                LCD12864_WDat(temp);
}
更正两个函数。
回复

使用道具 举报

ID:162136 发表于 2017-10-7 11:07 | 显示全部楼层
加一个卷动函数
//GDRam 卷动
//sx: 起始位置 x (列)坐标
//sy: 起始位置 y (行)坐标
//ex: 结束位置 x (列)坐标
//ey: 结束位置 y (行)坐标
//mode: 卷动方向
//mode = 0: 向上卷动
//mode != 0: 向下卷动
void LCD12864_ScrollGDRamLine(uchar sx,uchar sy,uchar ex,uchar ey,uchar mode)//GDRam 卷动行
{
        uchar s_dat[16];                                                                        //记录起始行数据
        uchar t_dat[16];                                                                        //临时数据
        uchar i;
        short dir;                                                                                        //方向
        uchar scroll_val = mode &0x3f;                                                //卷动量
        uchar sx_bit,ex_bit;                                                                //位置块中的偏移位
        uchar block_dis;                                                                        //块的差距
        uchar sx_block,ex_block;                                                        //起始和结束位置所在的块
        uint *ps = (uint*)s_dat;                                                        // 8 强制转换 为 16 位数据,方便移位
        uint *pt = (uint*)t_dat;                                                        // 8 强制转换 为 16 位数据,方便移位
        uint s_bit,e_bit;                                                                        //头尾位置数据
        uint temp;                                                                                        //临时数据
        if(mode==0) dir = 1;                                                                //方向
        else
        {
                i = ey;                                                                                        //起始位置和结束位置互换
                ey = sy;
                sy = i;
                dir = -1;                                                                                //方向
        }
        sx_bit = sx & 0x0f;                                                                        //位偏移量(1 块里有 16 个位)
        ex_bit = ex & 0x0f;
        sx_block = sx >> 4;                                                                        //块的位置
        ex_block = ex >> 4;                                                                        //块的位置
        block_dis = ex_block - sx_block;                                        //两块的差距量
///////       读出起始位置        //////////////////////////////////////////////////////
        LCD12864_WCmd(0X34);                                                                //扩展指令,关GDRAM显示
        i = sy;
        LCD12864_WCmd(0X80+(i&0x1f));                                                //行坐标
        if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                        //下半屏列坐标(以块为单位)
        else LCD12864_WCmd(0X80+sx_block);                                        //上半屏列坐标(以块为单位)
        i = LCD12864_RDat();                                                                //假读(读出不确定数据)
        i = 0;
        do
        {
                s_dat[i++] = LCD12864_RDat();                                        //高 8 位数据
                s_dat[i++] = LCD12864_RDat();                                        //低 8 位数据
        }while(i <= (block_dis<<1));
        s_bit = 0xffff >> sx_bit;                                                        //去掉不用互换的前头
        e_bit = 0xffff << (15- ex_bit);                                        //去掉不用互换的后尾
        while(1)
        {
////////         读出次行        /////////////////////////////////////////////////////
                i = sy+dir;
                LCD12864_WCmd(0X80+(i&0x1f));                                        //行坐标
                if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                //下半屏列坐标(以块为单位)
                else LCD12864_WCmd(0X80+sx_block);                                //上半屏列坐标(以块为单位)
                i = LCD12864_RDat();                                                        //假读(读出不确定数据)
                i = 0;
                do
                {
                        t_dat[i++] = LCD12864_RDat();                                //高 8 位数据
                        t_dat[i++] = LCD12864_RDat();                                //低 8 位数据
                }while(i <= (block_dis<<1));
/////////         数据互换       //////////////////////////////////////////////////
                i = 0;
                do                                                                                                //全部数据互换
                {
                        temp = ps[i];
                        ps[i] = pt[i];
                        pt[i] = temp;
                }while(++i <= block_dis);
                temp = (ps[0] & s_bit) | (pt[0] & (~s_bit));        //更换不用互换的前头和后尾
                pt[0] = (pt[0] & s_bit) | (ps[0] & (~s_bit));
                ps[0] = temp;
                temp = (ps[block_dis] & e_bit) | (pt[block_dis] & (~e_bit));
                pt[block_dis] = (pt[block_dis] & e_bit) | (ps[block_dis] & (~e_bit));
                ps[block_dis] = temp;
/////////        把次行数据到首行地址        /////////////////////////////////////////
                i = sy;
                LCD12864_WCmd(0X80+(i&0x1f));                                        //行坐标
                if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                //下半屏列坐标(以块为单位)
                else LCD12864_WCmd(0X80+sx_block);                                //上半屏列坐标(以块为单位)
                for(i=0;i>0;i--);                                                                //延时
                i=0;
                do
                {
                        LCD12864_WDat(s_dat[i++]);                                        //高 8 位数据
                        LCD12864_WDat(s_dat[i++]);                                        //低 8 位数据
                }while(i <= (block_dis<<1));                                                                                                                                                                                                                           
/////////         再次数据互换       //////////////////////////////////////////////////
                if(ey != sy)                                                                        //没到最后一行
                {
                        i = 0;
                        do                                                                                        //全部数据互换
                        {
                                temp = ps[i];
                                ps[i] = pt[i];
                                pt[i] = temp;
                        }while(++i <= block_dis);
                }
//////////       把起始行数据写到尾行地址      //////////////////////////////////////////
                else                                                                                        //到最后一行                                                                                                       
                {
                        i = sy;
                        LCD12864_WCmd(0X80+(i&0x1f));                                //行坐标
                        if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);        //下半屏列坐标(以块为单位)
                        else LCD12864_WCmd(0X80+sx_block);                        //上半屏列坐标(以块为单位)
                        i=0;
                        do
                        {
                                LCD12864_WDat(t_dat[i++]);                                //高 8 位数据
                                LCD12864_WDat(t_dat[i++]);                                //低 8 位数据
                        }while(i <= (block_dis<<1));
                        break;                                                                                //完成返回
                }
                sy += dir;                                                                                //下一行地址
        }       
        LCD12864_WCmd(0x36);                                                                //开绘图显示
        LCD12864_WCmd(0x30);                                                                //基本指令模式
}
回复

使用道具 举报

ID:162136 发表于 2017-10-7 11:57 | 显示全部楼层
卷动函数:
1:加入了位置限制和
2:修改了方向参数的传递
//GDRam 卷动
//sx: 起始位置 x (列)坐标(0-127)
//ex: 结束位置 x (列)坐标(0-127)
//sy: 起始位置 y (行)坐标(0-63)
//ey: 结束位置 y (行)坐标(0-63)
// 卷动方向:
//ey > sy: 向上卷动
//ey < sy: 向下卷动
void LCD12864_ScrollGDRamLine(uchar sx,uchar sy,uchar ex,uchar ey)//GDRam 卷动行
{
        uchar s_dat[16];                                                                        //记录起始行数据
        uchar t_dat[16];                                                                        //临时数据
        uchar i;
        short dir;                                                                                        //方向
        uchar sx_bit,ex_bit;                                                                //位置块中的偏移位
        uchar block_dis;                                                                        //块的差距
        uchar sx_block,ex_block;                                                        //起始和结束位置所在的块
        uint *ps = (uint*)s_dat;                                                        // 8 强制转换 为 16 位数据,方便移位
        uint *pt = (uint*)t_dat;                                                        // 8 强制转换 为 16 位数据,方便移位
        uint s_bit,e_bit;                                                                        //头尾位置数据
        uint temp;                                                                                        //临时数据
        if((sy>127)||(ey>127)||(sx>63)||(ex>63)) return;        //范围限制
        if(sx > ex)                                                                                        //调整 x 轴位置
        {
                i = sx;                                                                                        //sx 和 ex 调换,保证 ex >= sx
                sx = ex;
                ex = i;
        }
        if(sy==ey) return;                                                                        //没有卷动退出
        else if(ey>sy) dir = 1;                                                                //方向(向上卷动)
        else dir = -1;                                                                                //方向(向下卷动)
        sx_bit = sx & 0x0f;                                                                        //位偏移量(1 块里有 16 个位)
        ex_bit = ex & 0x0f;
        sx_block = sx >> 4;                                                                        //块的位置
        ex_block = ex >> 4;                                                                        //块的位置
        block_dis = ex_block - sx_block;                                        //两块的差距量
///////       读出起始位置        //////////////////////////////////////////////////////
        LCD12864_WCmd(0X34);                                                                //扩展指令,关GDRAM显示
        i = sy;
        LCD12864_WCmd(0X80+(i&0x1f));                                                //行坐标
        if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                        //下半屏列坐标(以块为单位)
        else LCD12864_WCmd(0X80+sx_block);                                        //上半屏列坐标(以块为单位)
        i = LCD12864_RDat();                                                                //假读(读出不确定数据)
        i = 0;
        do
        {
                s_dat[i++] = LCD12864_RDat();                                        //高 8 位数据
                s_dat[i++] = LCD12864_RDat();                                        //低 8 位数据
        }while(i <= (block_dis<<1));
        s_bit = 0xffff >> sx_bit;                                                        //去掉不用互换的前头
        e_bit = 0xffff << (15- ex_bit);                                        //去掉不用互换的后尾
        while(1)
        {
////////         读出次行        /////////////////////////////////////////////////////
                i = sy+dir;
                LCD12864_WCmd(0X80+(i&0x1f));                                        //行坐标
                if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                //下半屏列坐标(以块为单位)
                else LCD12864_WCmd(0X80+sx_block);                                //上半屏列坐标(以块为单位)
                i = LCD12864_RDat();                                                        //假读(读出不确定数据)
                i = 0;
                do
                {
                        t_dat[i++] = LCD12864_RDat();                                //高 8 位数据
                        t_dat[i++] = LCD12864_RDat();                                //低 8 位数据
                }while(i <= (block_dis<<1));
/////////         数据互换       //////////////////////////////////////////////////
                i = 0;
                do                                                                                                //全部数据互换
                {
                        temp = ps[i];
                        ps[i] = pt[i];
                        pt[i] = temp;
                }while(++i <= block_dis);
                temp = (ps[0] & s_bit) | (pt[0] & (~s_bit));        //更换不用互换的前头和后尾
                pt[0] = (pt[0] & s_bit) | (ps[0] & (~s_bit));
                ps[0] = temp;
                temp = (ps[block_dis] & e_bit) | (pt[block_dis] & (~e_bit));
                pt[block_dis] = (pt[block_dis] & e_bit) | (ps[block_dis] & (~e_bit));
                ps[block_dis] = temp;
/////////        把次行数据到首行地址        /////////////////////////////////////////
                i = sy;
                LCD12864_WCmd(0X80+(i&0x1f));                                        //行坐标
                if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);                //下半屏列坐标(以块为单位)
                else LCD12864_WCmd(0X80+sx_block);                                //上半屏列坐标(以块为单位)
                for(i=0;i>0;i--);                                                                //延时
                i=0;
                do
                {
                        LCD12864_WDat(s_dat[i++]);                                        //高 8 位数据
                        LCD12864_WDat(s_dat[i++]);                                        //低 8 位数据
                }while(i <= (block_dis<<1));                                                                                                                                                                                                                           
/////////         再次数据互换       //////////////////////////////////////////////////
                if(ey != sy)                                                                        //没到最后一行
                {
                        i = 0;
                        do                                                                                        //全部数据互换
                        {
                                temp = ps[i];
                                ps[i] = pt[i];
                                pt[i] = temp;
                        }while(++i <= block_dis);
                }
//////////       把起始行数据写到尾行地址      //////////////////////////////////////////
                else                                                                                        //到最后一行                                                                                                       
                {
                        i = sy;
                        LCD12864_WCmd(0X80+(i&0x1f));                                //行坐标
                        if(i&0x20) LCD12864_WCmd(0X80+sx_block+8);        //下半屏列坐标(以块为单位)
                        else LCD12864_WCmd(0X80+sx_block);                        //上半屏列坐标(以块为单位)
                        i=0;
                        do
                        {
                                LCD12864_WDat(t_dat[i++]);                                //高 8 位数据
                                LCD12864_WDat(t_dat[i++]);                                //低 8 位数据
                        }while(i <= (block_dis<<1));
                        break;                                                                                //完成返回
                }
                sy += dir;                                                                                //下一行地址
        }       
        LCD12864_WCmd(0x36);                                                                //开绘图显示
        LCD12864_WCmd(0x30);                                                                //基本指令模式
}
回复

使用道具 举报

ID:438288 发表于 2019-6-5 09:12 | 显示全部楼层
我要下来看看,我中文picc编译不过去,报非法字符
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表