求pic16f877a单片机的12864液晶串行显示驱动程序!
网上一大把啊,需要的话联系我
已发到你的邮箱.希望能帮到你.
阁下说的pic16f877a单片机的12864液晶串行显示驱动程序!你用的屏应该是12864带中文字库,控制芯片是ST7920的屏,那你就可以用模块内置自带的中文字库,只要根据ST7920中文字型码表里提出你想的内容就可以了,你可以在网下一个"ST7920中文字型码表",网上有很多,里面都是12864液晶串行接口的汉字库,你从里面调出来用就可以!
参考资料(不包含自调字库)
/*-------------------------------------
ST7920串行驱动程序
--------------------------------------*/
#ifndef ST7920_H
#define ST7920_H
/*--------------------------------*/
//#include<reg52.h>
/*--------------------------------*/
#define uchar unsigned char
#define uint unsigned int
/*--------------------------------
下面是ST7920的内部指令宏定义
--------------------------------*/
#define bascmd 0x30 /*使用基本指令集*/
#define clear 0x01 /*清屏*/
#define turn 0x02 /*地址归位*/
#define entset 0x06 /*游标右移,DDRAM地址计数器AC+1*/
#define gor 0x1c /*整屏右移*/
#define gol 0x18 /*整屏左移*/
#define dison 0x0c /*显示开,关光标*/
#define cgrama 0x40 /*cgram基地止*/
#define ddrama 0x80 /* 设定DDRAM 地址,第一行80H~87H,第二行90H~97H */
#define page0 0x80
#define page1 0x90
#define page2 0x88
#define page3 0x98
#define extcmd 0x34 /*使用扩展指令集*/
#define reverse 0x04 /*反白显示*/
#define mapdison 0x36/*扩充指令图形显示开*/
/*--------------------------------
硬件接口
--------------------------------*/
#define LCM_DATA P0 /* P0口,作为数据总线 */
sbit LCM_RS = P1^7; /* 数据(H)/指令(L) */
sbit LCM_RW = P1^6; /* 读(H)/写(L) */
sbit LCM_EN = P1^5; /* 使能-写(H->L)/读(H) */
sbit LCM_PSB = P1^4; /* 8位或4位串口 */
sbit LCM_BF = LCM_DATA^7; /* LCD模块内部忙标志 */
/*------------------------------*/
void delay(uint t);
void Ldelay(uint t1);
void LCM_busy();
void LCM_wrcmd(uchar cmd);
void LCM_wrdat(uchar dat);
void LCM_add(uchar x,uchar y);
void LCM_basinit();
void LCM_wrpagestr(uchar add,uchar* dis,uchar num);
void LCM_mapclr();
void LCM_extinit();
void LCM_12864map(uchar code *dis);
void LCM_6464map(uchar x,uchar *p);
void LCM_3232word(uchar x,uchar *p);
#endif
以下是并行方式的驱动:
#include"ST7920.h"
/*------------------------------*
函数名:void delay(uint t)
延时t个5倍指令周期,1个指令周期约为1us
*--------------------------------*/
void delay(uint t)
{
while(t--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
void Ldelay(uint t1)
{
while(t1--)
delay(1000);
}
/*------------------------------*
读忙函数,等待液晶处于就绪态
LCM_busy=1时为忙
*-------------------------------*/
void LCM_busy()
{
LCM_RS = 0;
LCM_RW = 1;
LCM_EN = 1;
while(LCM_BF);
LCM_EN = 0;
}
/*------------------------------*
向LCM写指令
*-------------------------------*/
void LCM_wrcmd(uchar cmd)
{
LCM_busy();
LCM_RS = 0;
LCM_RW = 0;
LCM_DATA = cmd;
LCM_EN = 1;
delay(1);
LCM_EN = 0;
}
/*------------------------------*
向LCM写数据
*-------------------------------*/
void LCM_wrdat(uchar dat)
{
LCM_busy();
LCM_RS = 1;
LCM_RW = 0;
LCM_DATA = dat;
LCM_EN = 1;
delay(1);
LCM_EN = 0;
}
/*------------------------------*
写地址函数,基本指令集,文字
*-------------------------------*/
void LCM_add(uchar x,uchar y)
{
switch(x)
{
case 0:x=page0;break;
case 1:x=page1;break;
case 2:x=page2;break;
case 3:x=page3;break;
}
LCM_wrcmd(x+y);
// delay(8);
}
/*------------------------------*
LCM初始化函数,基本指令集
*-------------------------------*/
void LCM_basinit()
{
LCM_PSB = 1;
LCM_wrcmd(bascmd);
delay(80);
LCM_wrcmd(entset);
delay(80);
LCM_wrcmd(dison);
delay(80);
LCM_wrcmd(clear);
delay(1000);
}
void LCM_extinit()
{
LCM_wrcmd(0x34);
delay(80);
LCM_wrcmd(0x02);
delay(80);
}
/*------------------------------*
向某一行写字符串
*-------------------------------*/
void LCM_wrpagestr(uchar add,uchar* dis,uchar num)
{
LCM_wrcmd(add);
while(num--)
{
LCM_wrdat(*dis++);
}
}
/*------------------------------*
图形清屏函数
*-------------------------------*/
void LCM_mapclr()
{
uint i,j;
LCM_extinit();
for(i=0;i<512;i+=16)
{
LCM_wrcmd(0x80+i/16);
LCM_wrcmd(0x80);
for(j=0;j<16;j++)
{
LCM_wrdat(0x00);
}
}
for(i=0;i<512;i+=16)
{
LCM_wrcmd(0x80+i/16);
LCM_wrcmd(0x88);
for(j=0;j<16;j++)
{
LCM_wrdat(0x00);
}
}
}
/*----------------------------*
输入一幅128*64的图像
*----------------------------*/
void LCM_12864map(uchar *p)
{
uint i,j;
LCM_extinit();
LCM_mapclr();
for(i=0;i<512;i+=16)
{
LCM_wrcmd(0x80+i/16);
LCM_wrcmd(0x80);
delay(1);
for(j=0;j<16;j++)
{
LCM_wrdat(p[j+i]);
}
LCM_wrcmd(0x80+i/16);
LCM_wrcmd(0x88);
delay(1);
for(j=0;j<16;j++)
{
LCM_wrdat(p[512+j+i]);
}
}
LCM_wrcmd(mapdison);
delay(16);
}
void LCM_6464map(uchar x,uchar *p)
{
uint i,j;
LCM_extinit();
LCM_mapclr();
for(i=0;i<256;i+=8)
{
LCM_wrcmd(0x80+i/8);
LCM_wrcmd(0x80+x);
delay(1);
for(j=0;j<8;j++)
{
LCM_wrdat(p[j+i]);
}
LCM_wrcmd(0x80+i/8);
LCM_wrcmd(0x88+x);
delay(1);
for(j=0;j<8;j++)
{
LCM_wrdat(p[256+j+i]);
}
}
LCM_wrcmd(mapdison);
delay(16);
}
/*----------------------------*
自定义图形文字32*32
*----------------------------*/
void LCM_3232word(uchar x,uchar *p)
{
uint i,j;
for(i=0;i<128;i+=4)
{
LCM_wrcmd(0x80+i/4);
LCM_wrcmd(0x80+x);
delay(1);
for(j=0;j<4;j++)
{
LCM_wrdat(p[j+i]);
}
}
LCM_wrcmd(mapdison);
delay(16);
}
以下是串行方式的驱动
#include"ST7920_s.h"
/*------------------------------*
函数名:void delay(uint t)
延时t个5倍指令周期,1个指令周期约为1us
*--------------------------------*/
void delay(uint t)
{
while(t--)
{
_nop_();_nop_();_nop_();_nop_();_nop_();
}
}
void Ldelay(uint t1)
{
while(t1--)
delay(1000);
}
/*------------------------------*
读忙函数,等待液晶处于就绪态
LCM_busy=1时为忙
*-------------------------------*/
/*void LCM_busy()
{
LCM_RS = 0;
LCM_RW = 1;
LCM_EN = 1;
while(LCM_BF);
LCM_EN = 0;
}
/*------------------------------*
向LCM写1byte
*-------------------------------*/
void LCM_wrbyte(uchar DATA)
{
uchar i;
for(i=0;i<8;i++)
{
LCM_SID=DATA&0x80; //取出最高位
LCM_CLK=1;
// _nop_();
LCM_CLK=0;
// _nop_();
DATA<<=1; //左移
}
}
/*------------------------------*
start=0向LCM写指令
start=1向LCM写数据
*-------------------------------*/
void LCM_wrcord(bit start, uchar DATA) //写指令或数据
{
uchar start_data,Hdata,Ldata;
if(start==0) start_data=0xf8; //写指令
else start_data=0xfa; //写数据
Hdata=DATA&0xf0; //取高四位
Ldata=(DATA<<4)&0xf0; //取低四位
LCM_wrbyte(start_data); //发送起始信号
delay(3); //延时是必须的
LCM_wrbyte(Hdata); //发送高四位
delay(1); //延时是必须的
LCM_wrbyte(Ldata); //发送低四位
delay(1); //延时是必须的
}
/*------------------------------*
写地址函数,基本指令集,文字
*-------------------------------*/
void LCM_add(uchar x,uchar y)
{
switch(x)
{
case 0:x=page0;break;
case 1:x=page1;break;
case 2:x=page2;break;
case 3:x=page3;break;
}
LCM_wrcord(0,x+y);
}
/*------------------------------*
LCM初始化函数,基本指令集
*-------------------------------*/
void LCM_basinit()
{
LCM_PSB = 0; //串口驱动模式
LCM_CS=1;
LCM_wrcord(0,bascmd); //8 位介面,基本指令集
LCM_wrcord(0,dison); //显示打开,光标关,反白关
LCM_wrcord(0,clear); //清屏,将DDRAM的地址计数器归零
}
void LCM_extinit()
{
LCM_wrcord(0,0x34);
LCM_wrcord(0,0x02);
}
/*------------------------------*
向某一行写字符串
*-------------------------------*/
void LCM_wrpagestr(uchar add,uchar* dis,uchar num)
{
LCM_wrcord(0,add);
while(num--)
{
LCM_wrcord(1,*dis++);
}
}
希望能对你有帮助,祝你开发成功!
为什么PIC16F877 RA设置为输入口后,RA口电平没有变化单片机老是检测有输...
如果RA口什么也没接(浮空),发生这种现象是很正常的。PIC单片机的I\/O口设置为输入时呈高阻态,阻值高达20兆欧以上,在引脚上很容易引入包括人体感应在内的各种干扰,逻辑电平是不确定的,而且电平变化的随机性也很大,测量设备未必能实时检出正确结果,但单片机的程序如果一直在扫描I\/O口,则可以检测...
pic16f877的工作电压是5V,那它的输入高低电平是多少?
单片机都是CMOS电平,5V电源系统,CMOS与TTL电平可以兼容,必要时TTL器件加一个上拉电阻,一般高电平范围0.7*Vcc--Vcc,低电平0V---0.2*Vcc ,比较可靠。
单片机pic16f877a与MSC-51的区别
单片机pic16f877a好像不是51内核的。51内核的单片机是可以兼容的,区别在扩展出一些SPI口、I2C口等,还有就是内存大点,读取扩展内存的方式等,详细看芯片资料。
pic16f877a高电平时的电压是多少
1、pic16f877a高电平时的电压与你的供电电压有关,通常为VDD-0.7V。2、pic16f877的供电电压在2.0-5.5V范围内都可以正常工作,电压越高,功耗越大。
PIC16F877A单片机这是曼陀铃音的do,为什么?求详细解释
每个音符都有自己的频率,这个相当于一个波形发生器,由定时器控制频率~接上喇叭就可以发出声音了
我想用Proteus仿真PIC16F877,怎么得到PIC16F877的HEX文件呢?
虽然我觉得已经说清楚了,但如果你是个新手,操作起来可能还会有问题,建立你去买一本书,它能告诉你,以上的二种方法的详细过程,除此之外,书中还好好多PROTEUS的仿真例子,它能助你从一个PIC新手成长为高手。附光盘中有所有的线路图和程序。它是北航出版社的《PIC16系列单片机C程序设计与PROTEUS仿真...
PIC单片机能用串口下载程序吗?例如16F877
当然可以咯,JDM烧路器完全能满足你要求.在你不想花钱买ICD2或者PICKIT的时候,DIY不失为一个学习动手的机会.我已经贴上了JDM完整电路,你可以在如下地址找到IC-Prog烧录PC端程序.http:\/\/www.ic-prog.com\/download.html
这个pic编程器怎么样烧写pic16f877
照着这个图可以做出PIC16F877的编程器的,这种是JDM编程器,要用IC-PROG烧写软件,网上可以免费下个。图是的是18引脚的PIC编程器,但PIC16877编程也同样只用到MCLR PGD PGM PGC VCC VSS 几个引脚,你从网上找一个18引脚的单片机(如16F628),查一下它的MCLR PGD PGM PGC VCC VSS 引脚是接在图...
带差分放大的单片机有哪些
STC89C52、PIC16F877A等型号。1、STC89C52:STC89C52是一款常用的8位单片机,差分放大功能。采用了高性能CMOS工艺,配备了多种外设和接口。通过其内置的模拟比较器和运算放大器等电路,可以实现差分信号输入、抑制噪声以及提高系统精度。2、PIC16F877A:PIC16F877A是Microchip推出的一款强大而灵活的8位单片机...
pic16f877A单片机 可以用一个电容接在电源脚!然后作短暂的断电记忆作用...
我想用超级电容器肯定可以,100S也能保持,因单片机的电流只是几毫安,等效电阻几百欧,用1-2法拉超级电容即可,但不要给除单片机以外的器件供电
厉佳三代: 在使用PIC16F877A单片机时,如果使用定时器0,那么最好不要写TMR0,因为每次的写操作都会导致定时器0的预分频器清零.一般都是定义一个变量,来做定时器0计时值的累计,这样才会将误差降到最小.另外就是仿真的时间不一定准确
朔城区17056176160: pic16f877a单片机 - ?
厉佳三代: 不知道你用的电源电压是多少,假如是5V,串联1K电阻 5V/1K=5ma 串联500欧姆电阻5V/0.5=10ma 你串联510欧姆的电阻就可.
朔城区17056176160: 请推荐一款PIC的单片机, 要串口收发与至少1个IO口. - ?
厉佳三代: PIC12F1822,PIC12F1840是8脚的,Flash:3.4/ 7K ,eeprom 256、RAM:128· PIC12LF1840T48A,14/TSSOP封装,$1.12,Flash: 7K ,eeprom、RAM:256 都有串口.
朔城区17056176160: DS1302芯片如何进行12/24 制显示时间转换的编程(C语言) - ?
厉佳三代: 修改DS1302芯片的(85h、84h)寄存的BIT7进行12/24小时模式切换,BIT7=1是12小时模式,BIT7=0是24小时模式.
朔城区17056176160: 求pic16f877a自写程序储存器的C语言程序(就是能通过自己的指令向自己写程序) - ?
厉佳三代: 可直接使用C编译器(例如:HI-tech)自带的函数 eeprom_read(uchar addr) eeprom_write(uchar addr,uchar data)
朔城区17056176160: 请问诸位PIC单片机高手:我有一个PIC16F877A芯片,用PICKIT2烧程序(一个改变引脚电平的).?
厉佳三代: 如果你是测量RA0~RA5,RE0~RE2端口出现这种情况,那么肯定是你没有在程序中对ADCON1寄存器进行初始化,因为PIC16F87X单片机的RA和RE端口默认是AD输入引脚,仅设置方向控制寄存器TRISA,TRISE是不够的
朔城区17056176160: 求助,单片机PIC16F877A模拟PWM输出程序,谢谢!?
厉佳三代: 20K周期是50us每次变化10%就是1/10喽?5us入一次中断的单片机时钟频率20M,指令频率就是5MHz,指令周期的话……0.2us对吧?5us/0.2us=2525个指令周期进入中断一次虽然不是不可能,不过很玄,很极限了
朔城区17056176160: ds1302的c语言程序 - ?
厉佳三代: 这是一个PIC16F877A单片机的源程序,你参考一下#include<pic.h> //包含单片机内部资源预定义 __CONFIG(0x1832); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡#define i_o RB4 //定义DS1302的...
朔城区17056176160: 求pic16f877a单片机的12864液晶串行显示驱动程序!?
厉佳三代: 阁下说的pic16f877a单片机的12864液晶串行显示驱动程序! 你用的屏应该是12864带中文字库,控制芯片是ST7920的屏,那你就可以用模块内置自带的中文字库,只要根据ST7920中文字型码表里提出你想的内容就可以了,你可以在网下一个...
朔城区17056176160: PIC 单片机的AD值怎么计算 - ?
厉佳三代: 看你用的是PIC那个系列的单片机了. PIC12、PIC16、PIC18、pic24等系列的单片机基本上都是10位精度的AD,而dsPIC30/33系列单片机有12位精度的AD. 在这只说10位精度的AD的计算. 首先2的10次方就是1024,也就是说AD采集到的数据用0到1023这1024个数值来表示,这还需要看你设置的参考电压的值,如果设置参考电压为5V(VREF引脚接5V),则参考电压范围是0V~5V,其对应的就是0~1023. 所以 AD值 = (采集到的数据 * 5V)/ 1023