标题:
基于STC15w单片机系列 自带的AD转换程序
[打印本页]
作者:
苏海
时间:
2020-2-15 16:53
标题:
基于STC15w单片机系列 自带的AD转换程序
15W系列是目前51单片机里面可用资源较多的处理器。一般的设计都可以用,本次分享下利用单片机自带的AD转换座一个数字电压表。显示用的LCD1602
单片机源程序如下:
#include<15w.H>
#include<math.h>
#include <string.h>
#include <stdio.h>
#include<intrins.h>
#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;
if(time1>50)
pwm=1;
else
pwm=0;
if(time>5000)
{ time=0;
led=~led ; }
}
复制代码
所有资料51hei提供下载:
15wAD转换.rar
(57.32 KB, 下载次数: 82)
2020-2-15 16:51 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
luoshi133
时间:
2020-2-21 04:23
下载学习学习,感谢楼主分享程序。
作者:
wsh791
时间:
2020-2-21 13:07
谢谢分享
作者:
dwy6122281
时间:
2021-4-29 15:06
具体用的哪款单片机芯片呢?
作者:
阿飞7812
时间:
2021-4-29 20:48
楼主如果单片电源5V,AD只在5V以内 ,如要能测量30V以内的电压程序应该怎样改 请指点下
作者:
rambo.hu
时间:
2021-5-1 10:53
电阻分压,我也想试试
作者:
bsljling
时间:
2021-5-2 20:20
我是小白:电阻分压,改变TEMP的比率好像就可以改变测量范围。不知对否。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1