搜索
bottom↓
回复: 0

PIC新手发一个用PIC16F877A驱动12864的程序

[复制链接]

出0入0汤圆

发表于 2010-6-30 15:35:34 | 显示全部楼层 |阅读模式
#include <pic.h>
#include<string.h>
__CONFIG(XT&UNPROTECT&PWRTEN&BORDIS&WDTDIS&LVPDIS);
#define  rs  RD5                    //定义LCD的数据/命令控制口
#define  rw  RD6                    //定义LCD的读/写控制口
#define  e   RD7                    //定义LCD的使能口
#define  psb RC7                    //定义通信方式控制口
#define  rst RD4                    //定义复位口
#define  nop()  asm("nop")          //定义nop()函数
#define  KEY1  RC0
#define  KEY2  RC1
#define  KEY3  RC2
#define  KEY4  RC3
#define  Bell  RC4
#define  Led   RD1


const unsigned char TAB1A[ ]={0xB4,0xB2,0xC7,0xB0,0xC3,0xF7,
                     0xD4,0xC2,0xB9,0xE2,0xA3,0xAC};
const unsigned char TAB1B[ ]={0xD2,0xC9,0xCA,0xC7,0xB5,0xD8,
                     0xC9,0xCF,0xCB,0xAA,0xA1,0xA3};
const unsigned char TAB1C[ ]={0xBE,0xD9,0xCD,0xB7,0xCD,0xFB,
                     0xC3,0xF7,0xD4,0xC2,0xA3,0xAC};
const unsigned char TAB1D[ ]={0xB5,0xCD,0xCD,0xB7,0xCB,0xBC,
                     0xB9,0xCA,0xCF,0xE7,0xA1,0xA3};


unsigned int lcd_x;                //定义LCD页地址寄存器
unsigned int lcd_y;                //定义LCD列地址寄存器
bit busy;                         //定义LCD忙标志位

void init();                        //申明I/O口设置函数
void lcd_init();                    //申明LCD初始化函数
void clear_p();                     //申明清屏函数
void han_wr2a();                    //申明显示公司名称函数
void han_wr2b();                    //申明显示公司web函数
void han_wr2c();                    //申明显示公司tel函数
void han_wr2d();                    //申明显示公司fax函数
void wr_zb();                       //申明有关显示设置函数
void flash();                       //申明设置LCD显示闪烁函数
void qushu(int counts,const unsigned char *ps);       //申明查表获取显示数据
void send_d(unsigned char x);       //申明送一字节数据显示函数
void send_i(unsigned char x);       //申明送一字节控制命令函数
void chk_busy();                    //申明检测LCD是否工作繁忙函数
void delay();                       //申明延时函数1,供各命令之间的延时和决定显示快慢
void delay1();                      //申明延时函数2,用以决定显示闪烁快慢
void mDelay(int Dat)         //延时子程序
{
        volatile char j;
        for (;Dat>0;--Dat)
                for (j=255;j>0;--j);        
}
void han_wr2k11();
void han_wr2k2();
void han_wr2k3();
void han_wr2k4();
void _Bell(void);
//定时器2初始化函数

void init_T2()
{
INTCON=0xc0;//*开总中断,允许外部设备中断
PIE1=0x02;  //*使能定时器2中断
TMR2=0;     //清空计数器
PR2=100;    //设定比较寄存器的值为100
T2CON=0x0D; //使能计数功能,前分频系数为4
}
void Led_flash(void)
      {Led=1;
      mDelay(200);
      Led=0;
      mDelay(200);}
unsigned int intnum;
//-------------------------------------------
//主程序
void main()
{      
       //init_Time();  
       init();                      //调用I/O口设置函数
       lcd_init();                  //调用LCD初始化函数   
       clear_p();                   //调用清屏函数
       han_wr2a();                  //调用显示公司名称函数
       mDelay(1000);
       han_wr2b();                  //调用显示公司web函数
       mDelay(1000);
       han_wr2c();                  //调用显示公司tel函数
       mDelay(1000);
       han_wr2d();                  //申明显示公司fax函数
       mDelay(500);
       delay();                     //延长显示一段时间
       init_T2();  
   while(1)
     {
      //Led_flash();
      if(KEY1==0) _Bell();
  }
}

//-------------------------------------------
//I/O口设置函数
void init()
{
  TRISA=0X00;                       //设置A口为输出
  TRISB=0X00;
  TRISC=0X0F;
  TRISD=0X00;                       //设置D口为输出
  ADCON1=0X06;                      //设置A口为普通I/O口
}

//-------------------------------------------
//LCD初始化函数
void lcd_init()
{
  rst=0;                            //复位LCD
  delay();                          //保证复位所需要的时间
  rst=1;                            //恢复LCD正常工作
  nop();        
  psb=1;                            //设置LCD为8位并口通信
  send_i(0x30);                     //基本指令操作
  send_i(0x01);                     //清除显示
  send_i(0x06);                     //指定在写入或读取时,光标的移动方向
  send_i(0x0c);                     //开显示,关光标,不闪烁
}

//-------------------------------------------
//显示公司名称函数
void han_wr2a()
{
  send_i(0x81);                     //设置显示位置:第一行
  qushu(0xc,TAB1A);                 //调用取数函数,共14个数据,保存在数组TAB1A里
}

//-------------------------------------------
//显示公司web函数  
void han_wr2b()
{
  send_i(0x91);                    //设置显示位置:第二行
  qushu(0xC,TAB1B);               //调用取数函数,共16个数据,保存在数组TAB1B里
}  
  
//-------------------------------------------
//显示公司tel函数
void han_wr2c()
{
  send_i(0x89);                   //设置显示位置:第三行
  qushu(0XC,TAB1C);              //调用取数函数,共16个数据,保存在数组TAB1C里
}

//-------------------------------------------
//显示公司fax函数
void han_wr2d()
{
  send_i(0x99);                  //设置显示位置:第四行
  qushu(0XC,TAB1D);             //调用取数函数,共16个数据,保存在数组TAB1D里
}
//
void han_wr2k11()
{
  send_i(0x80);                  //设置显示位置:第四行
  qushu(0X10,KTAB1);             //调用取数函数,共16个数据,保存在数组TAB1D里
}
//
void han_wr2k2()
{
  send_i(0x90);                  //设置显示位置:第四行
  qushu(0X10,KTAB2);             //调用取数函数,共16个数据,保存在数组TAB1D里
}
//
void han_wr2k3()
{
  send_i(0x88);                  //设置显示位置:第四行
  qushu(0X10,KTAB3);             //调用取数函数,共16个数据,保存在数组TAB1D里
}
//
void han_wr2k4()
{
  send_i(0x98);                  //设置显示位置:第四行
  qushu(0X10,KTAB4);             //调用取数函数,共16个数据,保存在数组TAB1D里
}
//有关显示设置函数
void wr_zb()
{
  send_i(lcd_y);
  send_i(lcd_x);
}

//-------------------------------------------
//显示闪烁函数
void flash()
{
  send_i(0x08);                  //关显示
  delay1();                      //延长一定时间
  send_i(0x0c);                  //开显示
  delay1();
  delay1();                      //延长关显示两倍的时间
  send_i(0x08);                  //关显示
  delay1();
  send_i(0x0c);                  //开显示
  delay1();
  delay1();
  send_i(0x08);                  //关显示
  delay1();
  send_i(0x0c);                  //开显示
  delay1();
  delay1();
}

//-------------------------------------------
//清屏函数
void clear_p()
{
  send_i(0x1);                   //清除所有显示
  send_i(0x34);                  //扩展指令操作
  send_i(0x30);                  //基本指令操作
}

//------------------------------------------
//查表函数
void qushu(int counts,const unsigned char *ps)
{
  int i;                         //定义循环变量
  for(i=counts;i>0;i--)          //循环counts次
     {  
        send_d(*ps);             //查表取数并调用显示一个字节数据函数送显示
        delay();                 //延长一定时间,确保能看到数据一个个的显示出来
        ps++;                    //取下一个数据
     }
}

//-------------------------------------------
//显示一字节数据函数
void send_d(unsigned char x)
{
   chk_busy();                  //检测LCD是否工作繁忙
   rs=1;                        //设置该字节数据是显示数据
   rw=0;                        //设置该次操作为写
   PORTB=x;                     //送数据口PORTD
   e=1;                         //使能
   nop();
   nop();
   nop();                       
   e=0;                         //禁止
}

//--------------------------------------------
//送一字节命令代码函数
void send_i(unsigned char x)
{
   chk_busy();                  //检测LCD是否工作繁忙
   rs=0;                        //设置该字节数据为控制命令
   rw=0;                        //设置此次操作为写
   PORTB=x;                     //送数据口PORTD
   e=1;                         //使能
   nop();
   nop();
   nop();
   e=0;                         //禁止
}

//-------------------------------------------
//检测LCD是否工作繁忙
void chk_busy()
{  
   busy=1;                      //先置位繁忙标志位
   TRISB=0XFF;                  //更改通信为输入
   rs=0;                        //设置该字节数据为命令代码
   rw=1;                        //设置此次操作为读
   while(busy)                  
      {
         nop();
         nop();
         nop();
         e=1;                   //使能
         nop();
         nop();
         nop();
         if(!RB7) busy=0;       //检测LCD是否工作繁忙
         nop();
         nop();
         nop();
         e=0;                   //禁止
      }
   e=0;                         //禁止
   TRISB=0X00;                  //恢复通信为输出
}

//-------------------------------------------
//延时函数
void delay()
{
    int i;
    for(i=0;i<5000;i++)
       {;}
}

//-------------------------------------------
//延时函数1
void delay1()
{
    int i;
    for(i=0;i<10;i++)
      {
        delay();               //调用延时函数
      }
}
//-------------------------------------------
void _Bell(void)
    {int i;
     for(i=0;i<5;i++)
        {Bell=1;
         mDelay(100);
         Bell=0;
         mDelay(500);}
     }
void interrupt time0()
{
TMR2IF=0;
// TMR2=56;
// RD0=!RD0;//
intnum++;
if(intnum==100)
        {
         intnum=0;
          Led=!Led; }}
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-9 02:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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