最好用有内置ADC的芯片,例如15WS404AS。非得用STC15W204S那只能模拟ADC功能,把下面程序的串口发送部分改成LED显示即可。
/*------------------------------------------------------------------*/
/* --- STC MCU International Limited -------------------------------*/
/* --- STC 1T Series MCU RC Demo -----------------------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-755-82944243 ----------------------------------------*/
/* --- Tel: 86-755-82948412 ----------------------------------------*/
/* If you want to use the program or the program referenced in the */
/* article, please specify in which data and procedures from STC */
/*------------------------------------------------------------------*/
/*
功能描述: 使用STC15F系列C版本做的RC测量电压的例子.
*/
#include "reg51.h"
/********宏定义*******/
#define MAIN_Fosc 22118400L //定义主时钟
#define uchar unsigned char
#define uint unsigned int
/********特殊功能寄存器*******/
sfr AUXR = 0x8e; //Auxiliary register
sfr P3M1 = 0xB1; //P3M1.N,P3M0.N =00--->Standard, 01--->push-pull
sfr P3M0 = 0xB2; // =10--->pure input, 11--->open drain
/********端口定义*******/
sbit P_TXD1 = P3^1; //定义模拟串口发送脚,打印信息用
sbit P_RC = P3^2; //RC 检测端口
/********变量与子程序声明*******/
uchar SampleCnt; //发送结果的采样间隔计数
uchar LineCnt; //每行显示结果计数
bit B_Over; //超量程标志
bit B_ADC_OK; //检测完成标志
uint adc; //RC做的ADC值
void RC_start(void); //RC检测开始
void Tx1Send(uchar dat); //发送数据
void InitTimer(void); //初始化定时器
void delay_ms(uchar ms); //延时
///////////////////////////////////////////////////////////
void main(void)
{
InitTimer(); //初始化定时器
P3M1 |= 1 << 2; //P3.2 开漏模式
P3M0 |= 1 << 2;
P_RC = 0; //RC 检测端口
while (1)
{
delay_ms(5); //放电时间
B_ADC_OK = 0; //清除ADC结束标志
B_Over = 0; //清除超量程标志
RC_start(); //RC 检测开始
while(!B_ADC_OK && !B_Over); //等待ADC结束或超量程
if(B_ADC_OK) //检测完成标志为1
{
if(++SampleCnt >= 100) //1秒钟发一个结果给串口
{
SampleCnt = 0;
Tx1Send(adc / 10000 + '0'); //send to PC from the UART
Tx1Send(adc % 10000 / 1000 + '0');
Tx1Send(adc % 1000 / 100 + '0');
Tx1Send(adc % 100 / 10 + '0');
Tx1Send(adc % 10 + '0');
Tx1Send(' ');
Tx1Send(' ');
if(++LineCnt >= 10) //10个结果后换行
{
LineCnt = 0;
Tx1Send(0x0d); //send CR
Tx1Send(0x0a);
}
}
}
}
}
/***************延时函数*****************/
void delay_ms(uchar ms)
{
uint i;
do
{
i = MAIN_Fosc / 14000L; //1T
while(--i) ; //13T per loop
}while(--ms);
}
/**************** Timer初始化函数 ************/
void InitTimer(void)
{
TMOD = 0; //16位自动重装
TH0 = 0; //
TL0 = 0; //
TR0 = 0; //关定时器0
ET0 = 1; //开定时器0中断
EA = 1; //开总中断
}
/********************* INT0外部中断函数 *************************/
void INT0_int () interrupt 0 //
{
if(INT0 && !B_Over) //上升沿中断,无超时
{
TR0 = 0; //关定时器0
P_RC = 0; //RC 检测端口置0
adc = TH0; //读定时寄存器高8位数据
adc =(adc<<8)+TL0; //高8位数据+低8位数据
B_ADC_OK = 1; //标志ADC结束
}
}
/********************** Timer0中断函数************************/
void timer0 (void) interrupt 1
{
TR0 = 0; //超量程关闭
B_Over = 1; //标志超量程
}
/**************** RC启动函数 ******************************/
void RC_start()
{ //使用定时器0计时
TH0 = 0; //计数寄存器清0
TL0 = 0;
B_Over = 0; //超时标志清0
P_RC = 1; //RC 检测端口置1
TR0 = 1; //开启定时器
IE0 = 0; //外部中断0请求标志清0
EX0 = 1; //INT0 开外中断
IT0 = 0; //INT0 上升/下降沿均可触发中断
}
/********************** 模拟串口相关函数************************/
void BitTime(void) //位时间函数
{
uint i;
i = ((MAIN_Fosc / 100) * 104) / 130000L - 1; //根据主时钟来计算位时间
while(--i);
}
//模拟串口发送
void Tx1Send(uchar dat) //9600,N,8,1 发送一个字节
{
uchar i;
EA = 0;
P_TXD1 = 0;
BitTime();
for(i=0; i<8; i++)
{
if(dat & 1)
P_TXD1 = 1;
else
P_TXD1 = 0;
dat >>= 1;
BitTime();
}
P_TXD1 = 1;
EA = 1;
BitTime();
BitTime();
}
|