EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
对于没有ADC的mcu,而又要测量外部的一个电压时,使用RC充放电的方式是比较容易实现并且低成本的方法。 STC15F系列是1T的MCU,其IO口有OPEN-DRAIN模式,此模式可以很容易用一个IO口配合一个定时器实现RC充放电来测量外部未知电压。如果没有空余的定时器,也可以使用指令循环的方式实现。本例使用定时器。
3 o2 d9 Y# W8 A& X0 r8 ~
# g, Y6 L8 V/ w" r) }0 M4 m* i' ^ 本范例使用P3.2(INT0)来做RC测量
/ j( I3 I, v: h1 O电路原理图如下:$ I/ H( [1 `: L8 H8 V3 V& E8 x+ n0 ~7 X
( d/ [" g' ?, M5 l/ x% U6 @
( h1 `$ c0 _& D, d& x# K" `7 |
单片机源程序如下:" L% `- l9 Y: f) i0 Q8 B+ U
- /*
- 功能描述: 使用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 port
- uchar SampleCnt; //发送结果的采样间隔计数
- uchar LineCnt; //每行显示结果计数
- bit B_Over; //超时标志
- bit B_ADC_OK; //检测完成标志
- uint adc; //RC做的ADC值
- void RC_start(void);
- void Tx1Send(uchar dat);
- void InitTimer(void);
- void delay_ms(unsigned char ms);
- ///////////////////////////////////////////////////////////
- void main(void)
- {
- InitTimer(); //初始化Timer
- P3M1 |= 1 << 2; //P3.2 config as Open-Drain
- P3M0 |= 1 << 2;
- P_RC = 0; //Clear RC port to 0
- // TMOD |= 0x00; //T0 as 16 bits timer, auto reload
- while (1)
- {
- delay_ms(5); //放电时间
- B_ADC_OK = 0; //清除ADC结束标志
- B_Over = 0; //清除超量程标志
- RC_start(); //RC charge-decharge
- while(!B_ADC_OK && !B_Over) ; //等待ADC结束或超时
- if(B_ADC_OK)
- {
- 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(unsigned char ms)
- // 描述: 延时函数。
- // 参数: ms,要延时的ms数.
- // 返回: none.
- // 版本: VER1.0
- // 日期: 2010-12-15
- // 备注:
- //============================================================
- void delay_ms(unsigned char ms)
- {
- unsigned int i;
- do
- {
- i = MAIN_Fosc / 14000L; //1T
- while(--i) ; //13T per loop
- }while(--ms);
- }
- /**************** RC启动函数 ******************************/
- void RC_start(void)
- {
- //使用Timer 0 计时
- TH0 = 0; //clear Timer 0
- TL0 = 0;
- B_Over = 0; //Clear Over flag
- P_RC = 1; //RC charge
- TR0 = 1; //enable Timer 0
- IE0 = 0; //Clear INT0 flag
- EX0 = 1; //INT0 Enable
- IT0 = 0; //INT0 上升,下降沿中断
- }
- /********************* INT0中断函数 *************************/
- void INT0_int (void) interrupt 0 //
- {
- if(INT0 && !B_Over) //上升沿中断,无超时
- {
- TR0 = 0; //deable Timer 0
- P_RC = 0; //decharge
- adc = TH0; //read the RC time
- adc = (adc << 8) + TL0;
- B_ADC_OK = 1; //标志ADC结束
- }
- }
- /**************** Timer初始化函数 ******************************/
- void InitTimer(void)
- {
- TMOD = 0; //for STC15Fxxx系列 Timer0 as 16bit reload timer.
- TH0 = 0;
- TL0 = 0;
- ET0 = 1; //允许Timer0中断
- TR0 = 0;
- EA = 1; //允许总中断
- }
- /********************** Timer0中断函数************************/
- void timer0 (void) interrupt 1
- {
- TR0 = 0; //超量程关闭
- B_Over = 1; //标志超量程
- }
- /********************** 模拟串口相关函数************************/
- 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();
- }
! U8 n" E/ D. @
" h6 V# J, a' Z& K( x" p. D; X$ z& @: R( v
/ c1 p; N/ ]8 P& F8 v |