#include <sst89E564RD.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define disdata P0 //显示数据码输出口
#define channel_0 0x02 //单通道0输入选择
#define channel_1 0x03 //单通道1输入选择
sbit ADC_CS = P3^4; //片选端
sbit ADC_CLK= P1^0; //时钟端
sbit ADC_DI = P1^1; //数据输入输出复用
sbit ADC_DO = P1^1; //DI和DO端都接在P1.1
sbit ACC0=ACC^0; //通道与输入方式控制字
sbit ACC1=ACC^1; //通道与输入方式控制字
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
uint data dis[4]={0x00,0x00,0x00,0x00};
//定义3个显示数据单元和一个数据存储单元
uchar code dis4[] = {"DIGITALVOLTMETER"};
uchar code dis5[] = {" VOLTAGE: . V "};
/********************************************************************/
/* */
/* 延时函数 */
/* */
/********************************************************************/
void delay(uchar ms)
{
while(ms--)
{
uchar i;
for(i=0;i<250;i++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/********************************************************************/
/* */
/*检查LCD忙状态 */
/*lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 */
/* */
/********************************************************************/
bit lcd_busy()
{
bit result;
LCD_RS = 0;
LCD_RW = 1;
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
result = (bit)(P0&0x80);
LCD_EN = 0;
return result;
}
/********************************************************************/
/* */
/*写指令数据到LCD */
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。 */
/* */
/********************************************************************/
void lcd_wcmd(uchar cmd)
{
while(lcd_busy());
LCD_RS = 0;
LCD_RW = 0;
LCD_EN = 0;
_nop_();
_nop_();
P0 = cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/********************************************************************/
/* */
/*写显示数据到LCD */
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。 */
/* */
/********************************************************************/
void lcd_wdat(uchar dat)
{
while(lcd_busy());
LCD_RS = 1;
LCD_RW = 0;
LCD_EN = 0;
P0 = dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN = 0;
}
/********************************************************************/
/* */
/* LCD初始化设定 */
/* */
/********************************************************************/
void lcd_init()
{
lcd_wcmd(0x38); //16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c); //显示开,关光标
delay(5);
lcd_wcmd(0x06); //移动光标
delay(5);
lcd_wcmd(0x01); //清除LCD的显示内容
delay(5);
}
/********************************************************************/
/* */
/* 设定显示位置 */
/* */
/********************************************************************/
void lcd_pos(uchar pos)
{
lcd_wcmd(pos | 0x80); //数据指针=80+地址变量
}
/********************************************************************/
/* */
/* 启动ADC转换 */
/* */
/********************************************************************/
void ADC_start()
{
ADC_CS=1; //一个转换周期开始
_nop_();
ADC_CLK=0;
_nop_();
ADC_CS=0; //CS置0,片选有效
_nop_();
ADC_DI=1; //DI置1,起始位
_nop_();
ADC_CLK=1; //第一个脉冲
_nop_();
ADC_DI=0; //在负跳变之前加一个DI反转操作
_nop_();
ADC_CLK=0;
_nop_();
}
/********************************************************************/
/* */
/*AD转换函数 */
/*选择输入通道,输入信号的模式《单端输入,或差分输入》 */
/*模数转换 */
/* */
/********************************************************************/
int ADC_read(uchar mode)
{
uchar i;
ADC_start(); //启动转换开始
ACC=mode;
ADC_DI=ACC1; //输出控制位1,DI=1,单通道输入,DI=0,差分输入。
ADC_CLK=1; //第二个脉冲
_nop_();
ADC_DI=0;
ADC_CLK=0;
_nop_();
ADC_DI=ACC0; //输出控制位0,DI=0,通道0输入,DI=1,通道1输入。
ADC_CLK=1; //第三个脉冲
_nop_();
ADC_DI=1;
ADC_CLK=0; //输入模式和通道号已经选择完。
ADC_CLK=1; //第四个脉冲
ACC=0;
for(i=8;i>0;i--) //读取8位数据
{
ADC_CLK=0; //脉冲下降沿
ACC=ACC<<1;
ACC0=ADC_DO; //读取DO端数据
_nop_();
_nop_();
ADC_CLK=1;
}
ADC_CS=1; //CS=1,片选无效。
return(ACC);
}
/********************************************************************/
/* */
/* 数据处理与显示 */
/* 将采集到的数据进行16进制转换为ASCLL码,并送显示。 */
/* */
/********************************************************************/
show_value(uchar ad_data)
{
dis[2]=ad_data/51; //AD值转换为3为BCD码,最大为5.00V。
dis[2]=dis[2]+0x30;
dis[3]=ad_data%51; //余数暂存
dis[3]=dis[3]*10; //计算小数第一位
dis[1]=dis[3]/51;
dis[1]=dis[1]+0x30;
dis[3]=dis[3]%51;
dis[3]=dis[3]*10; //计算小数第二位
dis[0]=dis[3]/51; //
dis[0]=dis[0]+0x30;
lcd_pos(0x4a);
lcd_wdat(dis[2]); //整数位显示
lcd_pos(0x4c);
lcd_wdat(dis[1]); //第一位小数显示
lcd_pos(0x4d);
lcd_wdat(dis[0]); //第二位小数显示
}
/************************************************
评论0