源程序
#include <reg52.h>
#include<stdio.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
sbit START=P3^2;
sbit ALE=P3^2;
sbit EOC=P3^3;
sbit OE=P3^4;
sbit B1=P3^5;
sbit B2=P3^6;
sbit B3=P3^7;
sbit GREEN=P2^0;
sbit YELLOW=P2^1;
sbit RED=P2^2;
bit flag500ms = 0; //500ms定时标志
unsigned char T0RH = 0; //T0重载值的高字节
unsigned char T0RL = 0; //T0重载值的低字节
unsigned char select = 0;
float low=0.15;
float high=0.55;
//待显示的第一行字符串
//unsigned char code str1[] = "Read:";
//待显示的第二行字符串,需保持与第一行字符串等长,较短的行可用空格补齐
//unsigned char code str2[] = "V";
void conv_start(void);
int read_data();
extern void delay_ms(int);
void ConfigTimer0(unsigned int ms);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y,
unsigned char *str, unsigned int len,unsigned int index);
void main()
{
unsigned char res = 0;
unsigned char a = 0;
float vol=0;
float judge=0;
unsigned char str2[6];
unsigned char str1[]="CO:";
unsigned char str3[]="%";
unsigned char str4[]=" L:";
unsigned char str5[3];
unsigned char str6[]="% ";
unsigned char str7[]="H:";
unsigned char str8[3];
unsigned char str9[]=" ";
unsigned char index = 0; //移动索引
unsigned char bufMove1[32]; //移动显示缓冲区1
unsigned char bufMove2[32]; //移动显示缓冲区2
EA = 1; //开总中断
ConfigTimer0(10); //配置T0定时10ms
InitLcd1602(); //初始化液晶
//缓冲区开头一段填充为空格
GREEN=0;
YELLOW=0;
RED=0;
while (1)
{
memset(bufMove2, 0, sizeof(bufMove2));
res=read_data();
vol=res/255.0*100.0;
judge=res/255.0;
switch (select)
{
case 0:
strcpy(bufMove2,str4);
strcat(bufMove2,str5);
strcat(bufMove2,str6);
strcat(bufMove2,str7);
strcat(bufMove2,str8);
strcat(bufMove2,str3);break;
case 1:
strcpy(bufMove2,str4);
strcat(bufMove2,str5);
strcat(bufMove2,str6);break;
case 2:
strcpy(bufMove2,str9);
strcat(bufMove2,str7);
strcat(bufMove2,str8);
strcat(bufMove2,str3);break;
case 3: select=0;break;
}
sprintf(str2,"%.2f",vol);
sprintf(str5,"%.0f",low*100.0);
sprintf(str8,"%.0f",high*100.0);
strcpy(bufMove1,str1);
strcat(bufMove1,str2);
strcat(bufMove1,str3);
if(judge<low)
{
GREEN=1;YELLOW=0;RED=0;
}
else if(judge<high)
{
if(flag500ms)
{
GREEN=0;YELLOW=1;RED=0;
}
else
{
GREEN=0;YELLOW=0;RED=0;
}
}
else
{
if(flag500ms)
{
GREEN=0;YELLOW=0;RED=1;
}
else
{
GREEN=0;YELLOW=0;RED=0;
}
}
if (flag500ms) //每500ms移动一次屏幕
{
flag500ms = 0;
//从缓冲区抽出需显示的一段字符显示到液晶上
LcdShowStr(0,0,bufMove1,16,index);
LcdShowStr(0,1,bufMove2,16,index);
//移动索引递增,实现左移
index++;
if (index >= 16)
{ //起始位置达到字符串尾部后即返回从头开始
index = 0;
}
}
}
}
/* 配置ADC芯片 */
void conv_start()
{
ALE=1;
START=1;
delay_ms(1); //当晶振较高时加延时
ALE=0;
START=0;
// delay_ms(5); //当晶振较高时加延时
}
int read_data()
{
int i;
//delay_ms(5);
//while(!EOC); //IF EOC==0,means busy
OE=1;
conv_start();
while(!EOC);
//delay_ms(5);
i=P0;
OE=0;
return i;
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{
unsigned long tmp; //临时变量
tmp = 11059200 / 12; //定时器计数频率
tmp = (tmp * ms) / 1000; //计算所需的计数值
tmp = 65536 - tmp; //计算定时器重载值
tmp = tmp + 12; //补偿中断响应延时造成的误差
T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零T0的控制位
TMOD |= 0x01; //配置T0为模式1
TH0 = T0RH; //加载T0重载值
TL0 = T0RL;
ET0 = 1; //使能T0中断
TR0 = 1; //启动T0
}
/* T0中断服务函数,定时500ms */
void InterruptTimer0() interrupt 1
{
static unsigned char tmr500ms = 0;
TH0 = T0RH; //重新加载重载值
TL0 = T0RL;
tmr500ms++;
if(tmr500ms%33==0&&B1==0)
{
select++;
}
if(tmr500ms%33==0&&B2==0&&select==1)
{
low=low+0.01;
}
if(tmr500ms%33==0&&B3==0&&select==1)
{
low=low-0.01;
}
if(tmr500ms%33==0&&B2==0&&select==2)
{
high=high+0.01;
}
if(tmr500ms%33==0&&B3==0&&select==2)
{
high=high-0.01;
}
if (tmr500ms >= 100)
{
tmr500ms = 0;
flag500ms = 1;
}
}
#include <reg52.h>
#define LCD1602_DB P1
sbit LCD1602_RS = P2^3;
sbit LCD1602_RW = P2^4;
sbit LCD1602_E = P2^5;
void delay_ms(int t)
{
int j;
for( ;t!=0; t--)
for (j=0;j<255;j++);
}
/* 等待液晶准备好 */
void LcdWaitReady()
{
unsigned char sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //读取状态字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重复检测直到其等于0为止
}
/* 向LCD1602液晶写入一字节命令,cmd-待写入命令值 */
void LcdWriteCmd(unsigned char cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
delay_ms(5);
LCD1602_E = 1;
delay_ms(5);
LCD1602_E = 0;
}
/* 向LCD1602液晶写入一字节数据,dat-待写入数据值 */
void LcdWriteDat(unsigned char dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
delay_ms(5);
LCD1602_E = 1;
delay_ms(5);
LCD1602_E = 0;
}
/* 设置显示RAM起始地址,亦即光标位置,(x,y)-对应屏幕上的字符坐标 */
void LcdSetCursor(unsigned char x, unsigned char y)
{
unsigned char addr;
if (y == 0) //由输入的屏幕坐标计算显示RAM的地址
addr = 0x00 + x; //第一行字符地址从0x00起始
else
addr = 0x40 + x; //第二行字符地址从0x40起始
LcdWriteCmd(addr | 0x80); //设置RAM地址
}
/* 在液晶上显示字符串,(x,y)-对应屏幕上的起始坐标,
str-字符串指针,len-需显示的字符长度 */
void LcdShowStr(unsigned char x, unsigned char y,
unsigned char *str, unsigned int len,unsigned int index)
{
int t,i;
t=len-index;
LcdSetCursor(x, y); //设置起始地址
if (y==0)
{
while (t) //连续写入len个字符数据
{
LcdWriteDat(str[16-t]);
t--;
}
for(i=0;i<index;i++) //连续写入len个字符数据
{
LcdWriteDat(str[i]);
}
}
if (y==1)
{
for(i=0;i<16;i++) //连续写入len个字符数据
{
LcdWriteDat(str[i]);
}
}
}
/* 初始化1602液晶 */
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2显示,5*7点阵,8位数据接口
LcdWriteCmd(0x0C); //显示器开,光标关闭
LcdWriteCmd(0x06); //文字不动,地址自动+1
LcdWriteCmd(0x01); //清屏
}
|