我给你来个程序试试
- #include <pic.h> //调用PIC16F87XA单片机的头文件
- //根据选项,配置字应该如下所示:
- //__CONFIG(HS&WRTEN&WDTDIS&BOREN&PWRTDIS&UNPROTECT&DUNPROT&DEBUGDIS&LVPDIS);
- //实际使用中,这样太麻烦,对于默认选项,我们将其忽略掉:
- __CONFIG(HS&WDTDIS&LVPDIS);
- //---------------------------------------
- //1602液晶相关I/O设置
- #define E RB3 //1602液晶的E脚接在RB3口上
- #define RW RB4 //1602液晶的RW脚接在RB4口上
- #define RS RB5 //1602液晶的RS脚接在RB5口上
- //---------------------------------------
- //---------------------------------------
- //A/D转换用寄存器设置
- unsigned int ADbuf; //10位A/D转换,设置16位的unsigend int型寄存器用来暂存A/D转换结果
- //---------------------------------------
- void Delay1602(unsigned int t)
- {
- unsigned int k; //定义一个16位寄存器用来做延时用
- for(k=0;k<t;k++); //延时
- }
- void LCD1602_busy(void)
- {
- TRISD7=1; //将RD7口设置为输入口,为读做准备
- RS=0; //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
- RW=1; //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
- E=1; //RS=0、RW=1、E=1时,忙信号输出到DB7,由RD7读入
- while(RD7==1); //由RD7读入1,表示1602液晶忙,需要等待
- E=0; //读完以后,恢复E的电平
- TRISD7=0; //将RD7口设置为输出口
- }
- void LCD1602_Write_com(unsigned char combuf)
- {
- RS=0; //选择指令寄存器
- RW=0; //选择写状态
- PORTD=combuf; //将命令字通过RD口送至DB
- E=1; //E高电平将命令字写入1602液晶
- asm("NOP"); //添加一个空操作,使高电平至少维持1us
- E=0; //写完以后,恢复E的电平
- }
- void LCD1602_Write_com_busy(unsigned char combuf)
- {
- LCD1602_busy(); //调用忙检测函数
- LCD1602_Write_com(combuf); //调用忙检测函数
- }
- void LCD1602_Write_data_busy(unsigned char databuf)
- {
- LCD1602_busy(); //调用忙检测函数
- RS=1; //选择数据寄存器
- RW=0; //选择写状态
- PORTD=databuf; //将命令字通过RD口送至DB
- E=1; //E高电平将命令字写入1602液晶
- asm("NOP"); //添加一个空操作,使高电平至少维持1us
- E=0; //写完以后,恢复E的电平
- }
- void LCD1602_Write_address(unsigned char x,unsigned char y)
- {
- x&=0x0f; //列地址限制在0-15间
- y&=0x01; //行地址限制在0-1间
- if(y==0) //如果是第一行
- LCD1602_Write_com_busy(x|0x80); //将列地址写入
- else //如果是第二行
- LCD1602_Write_com_busy((x+0x40)|0x80); //将列地址写入
- }
- void LCD1602_init(void)
- {
- Delay1602(1500); //调用延时函数
- LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
- Delay1602(500); //调用延时函数
- LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
- Delay1602(500); //调用延时函数
- LCD1602_Write_com(0x38); //8位数据总线,两行显示模式,5*7点阵显示
- LCD1602_Write_com_busy(0x38); //8位数据总线,两行显示模式,5*7点阵显示
- LCD1602_Write_com_busy(0x08); //显示功能关,无光标
- LCD1602_Write_com_busy(0x01); //清屏
- LCD1602_Write_com_busy(0x06); //写入新的数据后,光标右移,显示屏不移动
- LCD1602_Write_com_busy(0x0C); //显示功能开,无光标
- }
- void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
- {
- LCD1602_Write_address(x,y); //先将地址信息写入
- LCD1602_Write_data_busy(buf); //再写入要显示的数据
- }
- void main(void) //主函数,单片机开机后就是从这个函数开始运行
- {
- TRISA=0B11111111; //初始化RA5-RA0的输入输出方向
- TRISB=0B11000111; //初始化RB7-RB0的输入输出方向
- TRISD=0B00000000; //初始化RD7-RD0的输入输出方向
- PORTA=0B00000000; //初始化RA5-RA0数值
- PORTB=0B00000000; //初始化RB7-RB0的数值
- PORTD=0B00000000; //初始化RD7-RD0的数值
- LCD1602_init(); //调用1602液晶初始化函数
- //****A/D模块初始化****
- ADCON1=0B10001110; //RA0为A/D输入口;ADFM=1,转换后数据右移,ADRESL为低8位数据
- ADIE=0; //禁止A/D中断
- //*********************
- LCD1602_Disp(2,0,'-');
- LCD1602_Disp(3,0,'-');
- LCD1602_Disp(4,0,'A');
- LCD1602_Disp(5,0,'N');
- LCD1602_Disp(6,0,'0');
-
- LCD1602_Disp(8,0,'T');
- LCD1602_Disp(9,0,'E');
- LCD1602_Disp(10,0,'S');
- LCD1602_Disp(11,0,'T');
- LCD1602_Disp(12,0,'-');
- LCD1602_Disp(13,0,'-');
- while(1) //死循环,单片机初始化后,将一直运行这个死循环
- {
- //***启动一次A/D转换***
- ADCON0=0B00000001; //选择AN0通道准备进行A/D转换,启动A/D模块
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- asm("NOP"); //略做延时
- ADGO=1; //开始进行A/D转换
- while(ADGO) continue; //等待A/D转换结束
- ADbuf=ADRESH*256+ADRESL;//将10位A/D转换结果暂存在ADbuf
- //*********************
- //*******************************
- LCD1602_Disp(5,1,'A');
- LCD1602_Disp(6,1,'D');
- LCD1602_Disp(7,1,'=');
- //***1602液晶显示0-255***
- LCD1602_Disp(8,1,(ADbuf/1000)+'0'); //在第2行的第9列显示百位
- LCD1602_Disp(9,1,((ADbuf%1000)/100)+'0'); //在第2行的第10列显示百位
- LCD1602_Disp(10,1,(ADbuf%100)/10+'0'); //在第2行的第11列显示十位
- LCD1602_Disp(11,1,ADbuf%10+'0'); //在第2行的第12列显示个位
- //***********************
- }
- }
复制代码 |