15W系列是目前51单片机里面可用资源较多的处理器。一般的设计都可以用,本次分享下利用单片机自带的AD转换座一个数字电压表。显示用的LCD1602
单片机源程序如下:
#include<15w.H>
#include
#include
#include
#include
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int WORD;
#define ADC_POWER 0x80 //ADC电源控制位
#define ADC_FLAG 0x10 //ADC完成标志
#define ADC_START 0x08 //ADC起始控制位
#define ADC_SPEEDLL 0x00 //540个时钟
#define ADC_SPEEDL 0x20 //360个时钟
#define ADC_SPEEDH 0x40 //180个时钟
#define ADC_SPEEDHH 0x60 //90个时钟
unsigned char ch = 0; //ADC通道号
int time;
int time1;
int time2;
float p;
sbit RS = P5^5; //定义端口
sbit RW = P5^4;
sbit EN = P5^3;
sbit pwm=P2^7;
sbit key1 = P2^0;
sbit key2=P2^1;
sbit led=P5^1;
unsigned char ti[]={'0','1',0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
/*------------------------------------------------
uS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下 T=tx2+5 uS
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{
while(--t);
}
/*------------------------------------------------
mS延时函数,含有输入参数 unsigned char t,无返回值
unsigned char 是定义无符号字符变量,其值的范围是
0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{
while(t--)
{
//大致延时1mS
DelayUs2x(245);
DelayUs2x(245);
}
}
/*------------------------------------------------
判忙函数
------------------------------------------------*/
bit LCD_Check_Busy(void)
{
P4= 0xFF;
RS=0;
RW=1;
EN=0;
_nop_();
EN=1;
return (bit)(P4 & 0x80);
}
/*------------------------------------------------
写入命令函数
------------------------------------------------*/
void LCD_Write_Com(unsigned char com)
{
while(LCD_Check_Busy()); //忙则等待
RS=0;
RW=0;
EN=1;
P4= com;
_nop_();
EN=0;
}
/*------------------------------------------------
写入数据函数
------------------------------------------------*/
void LCD_Write_Data(unsigned char Data)
{
while(LCD_Check_Busy()); //忙则等待
RS=1;
RW=0;
EN=1;
P4= Data;
_nop_();
EN=0;
}
/*------------------------------------------------
清屏函数
------------------------------------------------*/
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
/*------------------------------------------------
写入字符串函数
------------------------------------------------*/
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
/*------------------------------------------------
写入字符函数
------------------------------------------------*/
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
void display(uint temp) //显示程序
{
int A1,A2,A3;
A1=temp/100;
A2=temp%100/10;
A3=temp%100%10/1;
LCD_Write_Char(4,0,ti[A1]);
LCD_Write_Char(5,0,ti[A2]);
LCD_Write_Char(6,0,'.');
LCD_Write_Char(7,0,ti[A3]);
LCD_Write_Char(8,0,'V');
}
/*----------------------------
软件延时
----------------------------*/
void Delay(WORD n)
{
WORD x;
while (n--)
{
x = 5000;
while (x--);
}
}
/*----------------------------
初始化ADC
----------------------------*/
void InitADC()
{
P1ASF = 0x01; //设置P1口为AD口
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
Delay(2); //ADC上电并延时
}
void Timer0Init(void) //200微秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x5C; //设置定时初值
TH0 = 0xF7; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
EA=1;
}
void main()
{
float i,j;
P0M0 = 0x00;
P0M1 = 0x00;
P1M0 = 0x00;
P1M1 = 0x00;
P2M0 = 0x00;
P2M1 = 0x00;
P3M0 = 0x00;
P3M1 = 0x00;
P4M0 = 0x00;
P4M1 = 0x00;
P5M0 = 0x00;
P5M1 = 0x00;
LCD_Init();
LCD_Clear();//清屏
InitADC(); //初始化ADC
IE = 0xa0; //使能ADC中断
Timer0Init();
while(1){
i=p*5;
j=((i/256)*10);
display(j);
DelayMs(500);
}
}
/*----------------------------
ADC中断服务程序
----------------------------*/
void adc_isr() interrupt 5 using 1
{
ADC_CONTR &= !ADC_FLAG; //清除ADC中断标志
p=ADC_RES ; //读取高8位结果并发送到串口
// SendData(ADC_LOW2); //显示低2位结果
ch = 0; //切换到下一个通道
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ADC_START | ch;
}
void tm0_isr() interrupt 1
{
time++;
time1++;
time2++;
if(time1>100)
time1=0;
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』