PIstc单片机程序读取普通I/0口,如何读取一个固定脉冲的上升沿个数?

PIC单片机课程期末复习题_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
PIC单片机课程期末复习题
上传于|0|0|暂无简介
阅读已结束,如果下载本文需要使用0下载券
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩9页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢用PIC单片机普通I/O脚检测模拟信号
&&没有公告
&|&&|&&|&&|&&|&&|&&|&
您现在的位置:&&>>&&>>&&>>&正文
用PIC单片机普通I/O脚检测模拟信号
&&&&&&&&&&
【字体: 】
用PIC单片机普通I/O脚检测模拟信号
作者:佚名&&&&文章来源:&&&&点击数:&&&&更新时间:&&&&
用PIC单片机普通I/O脚检测模拟信号 微芯科技咨询(上海)有限公司张明峰 摘要利用PIC单片机输入、输出引脚的输入阻抗高、输出驱动能力强的特性,讲述用2个I/O引脚实现电压测量;用I/O引脚实现电阻测量;用模拟比较器实现A/D转换的方法。给出它们的实现电路图和软件流程图。可开阔解决问题的思路。 关键词单片机电压测量电阻测量A/D转换
微芯公司(Microchip)以生产基于RISC架构的8位嵌入式控制单片机为主。其PIC系列单片机具有执行速度快,指令简洁,功耗低,抗干扰能力强,品种齐全,不同品种间迁徙方便、灵活等特点,在国内各应用领域被广泛使用。 在很多应用场合都会接触到模拟量的检测问题,如温度、电压等。对于这些问题,一般设计工程师首先想到的就是选择1款单片机,其内部含有A/D转换器模块,或是选择1片独立的A/D转换芯片,把所要检测的模拟量直接转换成数字量,再在单片机内部作数值处理,以最终完成所需的控制任务。其实,很多工程师没有想到的是,在许多应用场合,用普通的单片机数字输入、输出引脚,即可实现测量模拟量的任务。这样做的结果是可以大大降低器件本身的成本。以下几个典型的应用实例,都利用了PIC单片机输入、输出引脚的特性:标准的输入、输出双向可控;输入时阻抗很高;输出时驱动能力很强,就如同1个小电源一样。 一、 用2个I/O引脚实现电压测量 任何一个PIC单片机的I/O引脚,只要其输入不是施密特触发型的,其输入电平的高低判别就基于一门限电平。输入电压高过此门限电平,读到“1”,低于此门限电平,读到“0”,而且其判别回差很小;当其作为输入、输出时,不管是拉出还是灌入,都有25mA的驱动能力。基于这一特点,可以设计图1所示电路,来实现模拟电压的比例测量。 图1用2个I/O引脚测量电压电路图1中,输入电压Ui通过电阻Ri对C1进行充放电,单片机由引脚Pf输出一高低电平脉冲序列,通过电阻Pf同样对电容C1进行充放电。C1在这里起着误差积分的作用。单片机通过从Pf引脚上输出的高低电平脉冲序列,去调制C1上的电压,使其维持在输入引脚Pi的高低电平判别的门限值上。当进行1次测量时,便可固定调制脉冲序列的长度,其中高电平“1”出现的个数,就可以作为测量结果。 具体的做法是:单片机按固定的时间间隔检测输入引脚Pi上的电平,如果读到高电平,就在Pf脚上输出低电平“0”,使电容通过电阻Rf放电,试图降低电压;反之,若读到的是低电平,就在Pf引脚上输出高电平“1”,对电容进行充电,同时对输出高电平的次数作累加。当1次检测过程结束后,就可以把输出“1”的累计次数作为转换结果。整个转换过程的长短按实际所需的转换结果位数来决定。若需8位的分辨率,就在1个过程中做256次这样的输入判别和输出调制。理论上讲,只要有足够长的转换时间,该种方式的A/D结果分辨率就可以做得很高。软件流程如图2所示。 图2电压测量流程图这样的1个模拟量检测方式,其能检测的输入电压范围取决于输入引脚的门限电平Us和输出引脚Pf上输出的高电平Uh和低电平Ul的数值。下面的公式可以用于计算输入检测电压的上下限: Umin=Us+(Us-Uh)(Ri/Pf) Umax=Us+(Us-Ul)(Ri/Pf) 可以预见,当Ui≤Umin时,Pf输出为全“1”;当Ui≥Umax时,Pf输出为全“0” 针对Microchip的PIC系列单片机,当其工作电压为5V时,典型的Us值为2~3V,输出高电平非常接近于电源电压Udd,输出低电平也接近地电平Us。理想情况下,Us=2.5V,Uh=5V,Ul=0V,Ri=Rf,则Umin=0V,Umax=5V。 整个A/D转换的结果是线性的,全量程的数字量正比对应的模拟量,介于Umin和Umax值之间。如果采样总数为N,其中“1”的输出次数为N1,则: Ui=(N1/N)(Umax-Umin)+Umin 电容C1的值在运算中并没有用到,因此,其值的精度确定并不重要。C1的主要用途是控制充放电的斜率和抑制噪声。当选用47kΩ的电阻时,C1一般可以选择0.01~0.1μF。为避免过多的算术运算,一般可以在单片机内用查表的方式快速获得所测的电压值。 该种方式中,A/D转换的精度取决于转换时间,可以很容易地做到较高精度。不足之处在于:一旦选用了某片芯片,其门限电平Us、输出高低电平Uh和Ul将不会发生随机变化,但每一片不同的芯片,这些值都有可能不一样,尤其是Us的值。一般在芯片的技术手册中没有具体的参数(最多只会有典型值给出),所以,若把此法用于产品开发,必须在开发时注意提供系统的现场标定能力:出厂前必须用标准信号标定其A/D转换结果,才能保证产品性能的一致性。在量大的产品开发时,可能会降低生产效率。 二、 用I/O引脚实现电阻测量 在很多应用场合,温度物理量的测量就是通过1个热敏电阻来实现的。这在一些家用电器的设计里随处可见。如果需要测量1或2路的温度信号,且测量精度要求不高(如±0.5℃),测温范围也不大(室温范围),就不一定非得选用带A/D的单片机来实现,因为用普通的I/O脚也能完成相同的功能。 在用普通I/O脚测量电阻值时,需要对引脚的输入、输出功能提出与测量电压时相同的要求,线路连接可参考图3。其中Rt1和Rt2为待测的热敏电阻,Rs为阻值已知的标准电阻,且具备良好的温度特性(阻值基本不随温度变化而变化),Rp为一用作限流保护的小电阻。 图3用I/O引脚测量电阻值电路整个电路是基于RC充电回路的工作原理:把电阻值转化成对电容充电的时间值,并通过单片机的计数功能得到该时间值。工作前先把P1,P2和Ps引脚置成高阻抗输入状态,Pi脚为低电平输出口,让电容C上的电压通过电阻Rp放电到0V。然后,置Pi脚为输入状态,让其检测电容C上的电压。这时,把Ps脚置成高电平输出,让输出电压作为参考电压,通过Rs对电容C充电。单片机用固定的时间间隔去采样Pi脚上的电平变化情况,若得到低电平,也就是说C上的电压还没有充到门限电压,就持续采样过程,并对采样次数作累计,一直到读回的信号为“1”就结束。此时得到的计数值ts的大小代表了参考电压通过Rs标准电阻对电容充电的时间长短。最后,再把电容上的电压放完,用同样的方法只让P1(或P2)脚通过待测电阻Rt1对C充电,得到一时间计数值tm。如果RC的时间常数足够大,可以认为图4所示充电曲线近似为线性。由此,可以得到: Rt1=(tm/ts)Rs 图4充电曲线下面来看一下电路阻容值的配置问题。电阻和电容值的选择很大程度上取决于整个测量过程所要求的速度和测量分辨率(位数)。标准电阻Rs的值一般为最大测量电阻的一半左右。电容可以通过如下公式计算: C=-t/\[(Rmln(1-Us/Ur)\] 式中:t为完成额定位数的转换所需的时间; Rm为最大可能的测量电阻; Us为高低电平判别门限; Ur为参考电压。 实际选用的电容值应比计算所得稍小,以确保在测量最大电阻阻值时的计数不会溢出。在PIC单片机的应用中,如果有Rm=200kΩ,Ur=5V,Us=3V,Rs=100kΩ,振荡频率为8MHz,每次采样计数用6个指令周期,需有8位的转换结果,则: t=256×(1/8)×4×6=768μs 可得C=4200pF,实际可选用3900pF。 完成1次测量的软件流程,如图5所示。由上面的原理分析可以看出,在真正的被测电阻的计算过程中并没有用到电容C的值,也没有用到门限电平Us和参考电压(芯片工作电压)Ur的值。每次测量时都通过先测已知标准电阻对电容的充电时间,再测出待测电阻的充电时间,利用时间和电阻的线性比例关系推算出待测电阻的阻值。和测量电压的情况相比,设计的一致性得到了充分保证。只要标准电阻是准的,短时间内单片机的振荡频率和工作电压不发生大的相对变化,计算时就不必关心绝对的工作电压高低。芯片运行速度的快慢、门限电平的变化等这些因素,都可以得到一个比较准确的测量结果。适合于大批量生产而无须做专门的参数标定。不足的地方是,由于RC的充电时间常数已经由器件的物理参数决定,若想得到高分辨率的A/D转换结果,单片机就需要工作于较高的工作频率。同时,在充电到门限电平的过程中,电容电压的上升必须具备较好的线性度。在实际应用中作测温时,数据无须经特殊处理,即可达到误差为1℃内的测量精度。同样,一般对单片机,可用查表的方式快速得到所需要的温度值。 图5电阻测量流程图图6多个按键输入的检测电路利用同样的电阻测量方法,在某些应用场合可以实现多个按键输入的检测(只有1个按键有效),电路如图6所示。和普通扫描方式相比,可以节省许多引脚。 三、 用模拟比较器实现A/D转换 很多单片机片内都含有1个或2个模拟比较器(如PIC单片机家族中的PIC16C62X系列,就内含2个模拟比较器)。利用这些片内(或片外独立)的模拟比较器,可以实现高精度的A/D转换。参看图7所示电路。 图7比较器实现A/D转换电路在图7电路里,被测信号Ui直接连在模拟比较器的一路模拟信号输入端,比较器的另一路信号输入端连到积分电容C上。单片机所要完成的任务,是定时检测Cout端的电平,每次检测后,由单片机引脚Po端输出高或低电平的控制信号,调整在RC积分器电容C上的电压,以使比较器2个输入端的电压保持相等。软件编制的流程如图8所示。 图8比较器实现A/D转换流程图PIC16C62X系列单片机内的2个模拟比较器共有8种内部配置方式,其中的1种配置方式可以用单片机内部产生的基准电压加到比较器的输入信号“+”端。如果通过软件把基准电压设定成2.5V,电路连接如图9所示,其实就是图1的一个翻版。但此时的电路就具备了很好的测量一致性(和器件本身的工艺偏差无关),且测量精度更高。 图9比较器实现A/D转换改进电路结论 以上3种模拟信号的检测方法都已经大量成功地运用在实际的电路设计中。希望通过对这些设计方法的介绍,可以开阔大家解决问题的思路,让大家体会到PIC单片机普通I/O脚的一些特殊应用。这些应用在传统51系列单片机内是不容易实现的。因为标准51系列单片机的I/O脚的驱动能力微弱,且又是准双向的I/O(输入时非高阻),不适合用来实现上面介绍的测量方式。作为产品的设计者,若能充分发挥器件已有的功能和特性,必将使最终的产品具有更高的性能价格比。 若大家针对上面的介绍还需进一步和笔者探讨,请联系paul.或访问中文网站的技术论坛:.cnMES
文章录入:admin&&&&责任编辑:admin&
上一篇文章: 下一篇文章:
【】【】【】【】【】
  网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
杭州晶控电子有限公司 版权所有 COPYRIGHT2003――2009 HANGZHOU KinCony ELECTRONICS CO.,LTD All rights reserved 站长:查看: 3814|回复: 2
PIC16F684 对输入脉冲进行计数和脉冲宽度测量
使用cnnt 对脉冲计数,TMR1对上升沿计时,TMR2对下降沿计时,TMR1设定为100MS的定时器,TMR2 设定为40MS的定时器。& & & &
& & & & 脉冲周期 为50HZ到300HZ的变化,脉冲宽度为2MS到20MS的变化,检测脉冲的个数以及宽度。& & & & 按下RA0(UP)电机正转,开始对RA2外部脉冲计数判断宽度。cnnt=380时。停止电机转动
& & & & 按下RA5(DN)电机反转,开始对RA2外部脉冲计数判断宽度。cnnt==0时。 停止电机转动
& & & & 程序里边用了RA1对是否进入中断进行判断。目前程序检测不到RA1的变化。是否我的设计架构方案不对。
#include &pic.h&
__CONFIG(0x3004);//(0X30C4);
#define T0_40MS 100& & // 定义 TMR0 延时10MS 的时间常数
#define T1_100MS 40536
#define& & & & DN& & & & & & & & & & & & RA5& & & & //Motor rise & & & & & & & & 2& & & & DN
#define& & & & UP& & & & & & & & & & & & RA0& & & & //Motor decline& & & & & & & & 13&&UP
#define& & & & MOTA& & & & & & & & RC5& & & & //Motor Forward& & & & & & & & 5
#define& & & & MOTB& & & & & & & & RC4& & & & //Motor Reversal& & & & 6
& & & & //正反转标志位
& & & & //正反转标志位
& & & & //正反转标志位
&&//脉冲总个数
//脉冲计数
//TMR1脉冲上升沿时间
//TMR1脉冲下降沿时间
unsigned int cnnt_//TMR1脉冲总时间
unsigned int cnnt_tmr2;& & & & //TMR2脉冲总时间
unsigned int signal_key();
unsigned int getkey() ;
void Delay_MS(unsigned int t);
void initial()
& & & & TRISA=0x3D;//3D;RA2=1,
& & & & TRISC=0X0E;
& & & & OPTION=0x87;//RA2内部中断时源
& & & & INTCON=0xF0;//外围中断允许
& & & & CMCON0 = 0X07;
& & & & ANSEL = 0;
//& & & & TMR0=T0_40MS;//启动TMR0自带振荡器,分频比为1:256
& & & & T1CON=0X22;//2启动TMR1自带振荡器,分频比为1:4关闭TRM1ON=0;
& & & & TMR1H=T1_100MS&&8;//0X80;& & & &&&//设初值
& & & & TMR1L==T1_100MS;//0X00;
& & & & TMR1IE=1;& & & &&&//TMR1中断允许
& & & & T2CON=0x63;&&//TMR2 预分频系数为1:16 ,后分频系数为1:13,开始工作&&关闭TRM2ON=0;
& & & & PR2=239;& &//TMR2的溢出值,当 TMR2 为此值+1时溢出
& & & & TMR2IE=1;& & & &&&//TMR1中断允许&&50MS
& & & & cnnt=0;
& & & & cnnt_timer=0;
& & & & num=10;
void Delay_MS(unsigned int t)
& & & & unsigned int a,b;
& & & & for(a=t;a&0;a--)
& & & & for(b=110;b&0;b--);
void Forward()
& & & & rise=1;
& & MOTB=1;& & & &
& & & & MOTA=0;
& & & & signal_key();
void Reversal()
& & & & rise=0;
& & & & MOTB=0;
& & & & MOTA=1;
& & & & signal_key();
void Stop()
& & & & MOTA=0;
& & & & MOTB=0;
unsigned int getkey()
& & & & if(!UP)
& & & & & & & & while(!UP)
& & & & & & & & {
& & & & & & & & & & & & if(cnnt==num){Stop();}
& & & & & & & & & & & & Forward();
& & & & & & & & }
& & & & }& & & &
& & & & if(!DN)
& & & & & & & & while(!DN)
& & & & & & & & {& & & & & & & &
& & & & & & & & & & & & if(cnnt==0){Stop();}
& & & & & & & & & & & & Reversal();& & & & & & & & & & & &
& & & & & & & & }
& & & & while(DN&&UP)
& & & & & & & & tmrh=0;
& & & & & & & & tmrl=0;
& & & & & & & &
unsigned int signal_key()
//----------------------&&信号下降沿检测&&--------------------------//
& &&&& & & & while(!RA2)& & & & & & & & & & & & & & & & & &&&//再次确认信号,没有按下信号则退出
& & & & & & & & & & & & tmrh=0;
& & & & & & & & & & & & if(tmrl)
& & & & & & & & & & & & tmrl=1;
& & & & & & & & & & & & RA1=0;
& & & & & & & & & & & & INTF=0;& & & &
& & & & & & & & & & & & TMR1ON=0;
& & & & & & & & & & & & TMR2ON=1;
& & & & & & & & & & & & if(TMR2IF==1)//检测是否50MS错误信号,停止运行
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & TMR2ON=0;
& & & & & & & & & & & & & & & & TMR2IF=0;
& & & & & & & & & & & & & & & & PR2=239;& & & &&&//设初值
& & & & & & & & & & & & & & & & Stop(); //停止电机运行
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & }
& & & & & & & & & & & & & & & & & & & &
& & & & & & & & }
//----------------------&&信号上升沿检测&&--------------------------//
& & & & & & & & while(RA2)
& & & & & & & & {& &
& & & & & & & & & & & & tmrl=0;& & & & & & & & & & & &
& & & & & & & & & & & & if(tmrh)
& & & & & & & & & & & & tmrh=1;
& & & & & & & & & & & & TMR2ON=0;
& & & & & & & & & & & & INTF=1;
& & & & & & & & & & & &
& & & & & & & & & & & & if(TMR1IF==1)//检测是否100MS错误信号,停止运行
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & TMR1ON=0;
& & & & & & & & & & & & & & & & TMR1IF=0;
& & & & & & & & & & & & & & & & TMR1H=T1_100MS&&8;//0X80;& & & &&&//设初值
& & & & & & & & & & & & & & & & TMR1L=T1_100MS;//0X00;
& & & & & & & & & & & & & & & & Stop(); //停止电机运行
& & & & & & & & & & & & & & & &
& & & & & & & & & & & & }
& & & & & & & & & & & &
& & & & & & & & }
//----------------------& &取出上升沿脉冲信号时间&&--------------------------//
& & & & & & & & if(TMR1ON==0)
& & & & & & & & {
& & & & & & & & & & & & timerh=TMR1H;
& & & & & & & & & & & & timerl=TMR1L;
& & & & & & & & & & & & cnnt_timer = timerh&&8;
& & & & & & & & & & & & cnnt_timer +=
& & & & & & & & & & & & TMR1IF=0;
& & & & & & & & & & & & TMR1H=T1_100MS&&8;//0X80;& & & &&&//设初值
& & & & & & & & & & & & TMR1L=T1_100MS;//0X00;& & & & & & & &
& & & & & & & & }
//----------------------&&取出下降沿脉冲信号时间&&--------------------------//
& & & & & & & & if(TMR2ON==0)
& & & & & & & & {
& & & & & & & & & & & & cnnt_tmr2 = TMR2;
& & & & & & & & & & & & TMR2IF=0;
& & & & & & & & & & & & PR2=239;& & & &&&//设初值& & & &
& & & & & & & & }
void interrupt ISR(void)
& & & & if(INTF==1)& & & & //脉冲开始计数,同时开启TMR1上升降计时
& & & & & & & & INTF=0;
& & & & & & & & RA1=1;
& & & & & & & & if(rise) cnnt++;
& & & & & & & & else cnnt--;& & & &
& & & & & & & & TMR1ON=1;
& & & & if(& & & & TMR1IF==1)
& & & & & & & & TMR1IF=0;
& & & & & & & & TMR1H=T1_100MS&&8;//0X80;& & & &&&//设初值
& & & & & & & & TMR1L=T1_100MS;//0X00;
& & & & if(& & & & TMR2IF==1)
& & & & & & & & TMR2IF=0;& & & &
& & & & & & & & PR2=239;& & & &&&//设初值& & & &
void main()
& & & & initial();
& & while (1)
& & & & & & & & getkey();& &&&
& & & & }& & & &
 哈哈哈&&PIC16F684-I/SL&&我们正在做, 很好的优势。这款大伙用得还比较多。原装新货,稳定库存,价格优势, 相互了解就知道。& && &&&Q,Q:
 辛苦了!向楼主致敬!
Powered by

我要回帖

更多关于 单片机读取串口数据 的文章

 

随机推荐