////////////////【入门—八】ADC液晶屏显示/////////////////////
///////////////////IC:PIC18f14k50///////////////////////////////////
////////////////日期:2011-8-24///////////////////////////////////
////////////////说明:模拟输入口为AN10,也即RB4端口/////
////////////////参考电压:芯片内部固定FVR电压,1.024V////
//1602液晶屏的e、rw、rs端分别对应RB5,RB6,RB7//////
//模拟输入端接10Ω电阻并联0.1uF电容的下拉到地//////////
#include
#define uint unsigned int
#define uchar unsigned char
#define e PORTBbits.RB5 //液晶屏e端接RB5
#define rw PORTBbits.RB6 //液晶屏rw端接RB6
#define rs PORTBbits.RB7 //液晶屏rs端接RB7
#define ADGO ADCON0bits.GO //定义ADGO为启动ADC
#pragma config LVP=OFF //禁止单电源ICSP
//LVP必须禁止,否则RB3端口只能当做ICSP单电源引脚
//也可写成: CONFIG4Lbits.LVP=0;
uchar num;
uint lednum; //AD转换结果保存在lednum
uchar a1,a2,a3,a4,num; //a1--a4分别为液晶屏第二行第1、3、4、5位数void disp(uchar num1,uchar num2,uchar num3,uchar num4);//ADC液晶显示
uint get_ad(void); //获取ADC结果
uchar num;
void delay(uint z); //延时子程序
void ADC_init(void); //ADC初始化
void disp_init(void); //液晶屏初始化
const uchar table[]="The Voltage Is:"; //液晶屏第一行显示的字样
void write_com(uchar com); //对液晶屏写指令
void write_data(uchar dat); //写数据
void main()
{
ADC_init();
disp_init();
while(1)
{
delay(50);
lednum=get_ad();
a1=lednum/1000; //ADC结果千位上的数字
a2=lednum%1000/100; //ADC结果百位上的数字
a3=lednum%100/10; //ADC结果十位上的数字
a4=lednum%10; //ADC结果个位上的数字
disp(a1,a2,a3,a4);
}
}
void ADC_init()
{
TRSC=0; //C端口当IO口输出端,指令和数据输出给液晶屏显示
TRISB=0b00010000; //RB4输入状态作为A/D输入通道10
ANSELHbits.ANS10=1; //选择ADC通道10,即AN10
ADCON0=0b00101001; //使能ADC,通道选择10
ADCON1=0b00001000; //正向参考电压由FVR提供
ADCON2=0b10001101; //ADC结果右对齐保存,采集时间2TAD,时钟Fosc/16
REFCON0=0b10010000; //使能FVR,固定参考电压选择1.024V
}
void write_com(uchar com) //LED1602控制字输入
{
TRISB=0b00010000;
TRISC=0;
e=0;
rw=0;
rs=0; //写指令:RS=L,RW=L,D0~D7=指令码,E=高脉冲PORTC=com; //写指令到液晶
delay(5);
e=1;
delay(5);
e=0;
}
void write_data(uchar dat) //LCD1602数据输入
{
TRISC=0;
e=0;
rw=0;
rs=1; //写数据:RS=H,RW=L,D0~D7=指令码,E=高脉冲PORTC=dat; //写数据到液晶
delay(5);
e=1;
delay(5);
e=0;
}
void disp_init()
{
TRISC=0; //选择C端口为液晶屏数据的输入口
write_com(0x38); //液晶开显示
write_com(0x0c); //显示光标,光标闪烁
write_com(0x06); //读或写一个字符后地址指针加一,光标加一write_com(0x01); //显示清屏:1、数据指针清零;2、所有显示清零
write_com(0x80); //第一行首位
for(num=0;num<15;num++)
{
write_data(table[num]); //循环15次把“The Voltage Is:”写进第一行
delay(50);
}
}
uint get_ad() //数模转换结果
{
uint adval;
float advalf,adv;
for(num=0;num<50;num++)
{
ADGO=1; //开ADC
while(ADGO); //当ADGO为0表示这次ADC转换完成,即转换完成的时候再进行下一步
adval=ADRESH; //00000000 00000011 将8字节变成16字节
adval=adval<<8|ADRESL; //00000011 11111111 把转换结果的高位和低位放进同一个16位数里面
advalf=adval/1023.0*1.024; //模拟输入实际电压大小
adval=advalf*1000; //乘以1000送到液晶输出
adv=adv+adval; //取样50次,相加
}
adv=adv/50; //取样50次,取平均值
return (adv); //将结果返回
}
void disp(uchar num1,uchar num2,uchar num3,uchar num4)
{
write_com(0x80+0x40);
write_data(num1+0x30); //液晶第二行第一位数
delay(1);
write_com(0x80+0x41);
write_data('.'); //液晶第二行第二位放置小数点delay(1);
write_com(0x80+0x42);
write_data(num2+0x30); //液晶第二行第三位数
delay(1);
write_com(0x80+0x43);
write_data(num3+0x30); //液晶第二行第四位数
delay(1);
write_com(0x80+0x44);
write_data(num4+0x30); //液晶第二行第五位数
delay(1);
}
void delay(uint z) //z毫秒延时子程序
{
uint x,y;
for(x=110;x>0;x--)
for(y=z;y>0;y--);
}