2011-02-11 21:20:00 somethingma 阅读数 743
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4006 人正在学习 去看看 朱有鹏

以下为使用汇编代码产生的0.2s延时。

关于汇编与C语言的延时计算问题,推荐一篇好文章——彭老师的“51系列单片机延时程序运行时间的计算”。

 

2018-10-18 23:31:02 weixin_42625444 阅读数 40
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4006 人正在学习 去看看 朱有鹏

本文介绍了一种基于单片机控制的数控开关电源,以89C51单片机作为控制核心,对开关变换电路进行脉宽调制,构成一个智能闭环控制系统。单片机控制的开关电源具备更加完善的功能,更人性化、智能化,便于实时监控。其功能主要包括对开关电源输出电压进行检测,并显示实时电压值;通过按键进行编程预置期望输出的电压;通过A/D转换器采样输出电压,根据PID算法计算控制量修改占空比,以得到期望的输出电压,并通过PID算法控制输出电压稳定在设定的电压值上;拥有可靠的过流保护功能以及辅助电源可同时作为电源输入和给单片机提供工作电压,并可以通过键盘不断改变PID参数,可以进行实时调整。

假设基准电压为5v,由于电网波动导致输入电压减小,那么输出电压也将会减少,此时,所采样的电压将减小,假设为4.9v,误差为0.1v,经过比较放大后,脉冲调制电路根据这个误差,提高占空比使输出电压增大,同理,当由于电网波动导致输出电压增大时,脉冲调制电路降低占空比使输出电压减小,以此来控制输出电压的稳定。

市电经过整流滤波后,一路电压经过7805稳压得到一个+5v电压,该电压作为单片机的工作电源,另外一路电压直接作为开关变换电路的输入电压。单片机根据键盘输入值和取样值之间的差值,修改脉冲占空比,并输出控制功率开关管,以便得到期望的输出电压值,并根据模/数转换器所采样的电压和键盘输入比较,根据差值调用PID算法再次修改脉宽使输出电压稳定。

开关变换器采用磁铁心电感作为储能元件,在功率开关管导通时,电感储能,在开关管截止时,电感释放能量给负载。单片机定时采样输出端的电压,通过ADC0832送进单片机进行处理,单片机根据处理结果输出更新的控制信号,经过光电耦合器滤除干扰后输出控制信号控制功率开关管工作状态。

在本系统中,用户可以根据需要从键盘输入期望的电压,单片机会根据键盘输入与采样电压的差值,更新脉宽,使电源输出相应电压,更新脉宽后,单片机会马上调用PID控制算法,对输出电压进行稳定控制。

闭环时,电源自动进行脉宽调制,当系统读取到键盘预置的电压变化时,先将键盘输入值和从输出端的取样值相比较,假设当前键盘输入为10v,从输出端取样的值为6v,差值为4v,则系统会根据这个差值,更新脉宽使得输出端电压上升为10v;同样,当键盘输入为6v,输出端取样值为10v,差值为-4v,系统会根据算法,将占空比减小以使输出电压变小,这就是系统脉宽调制过程。

同时,电源可以自动稳压,假定在某一正常状态下,输出为V0,反馈电压问Vf(Vf=V0),用户设定电压为Vs,当V0=Vs时,偏差为0,单片机不进行脉宽更新,当电网波动导致输出增加时,即V0>Vs时,单片机采样的电压也增加,单片机根据偏差修改占空比使导通时间变小,从而使电压下降,同样当电网波动使输出电压下降时,即V0<Vs时,单片机修改脉宽使导通时间变长,从而使输出电压上升,如此循环来进行稳压。

1.整流滤波电路

市电经过变压器降压后,变为12v,对该电压整流后一部分电压直接作为开关变换电路的输入电压,另外将其通过7805得到5v的电压,给开关电源控制电路部分的单片机提供工作电源。

电路中采用发光二极管作为电源指示灯,交流220v降压后经过整流桥整流输出直流电压作为开关变换电路的输入电压,7805稳压输出5v给单片机提供电源。

 

2.开关变换电路

功率开关管采用达林顿管,由于它采用两个三极管进行级联,其放大倍数是两个管子放大倍数的乘积,因而具有很高的放大倍数,通过级联,可获取大的电流输出,对于提高电源的输出功率,有一定的作用。该开关管选择为PNP型,当控制脉冲的低电平时,开关导通,电感存储能量,开关把电路的输入电压变成高频脉冲,当控制脉冲为高电平时,开关截止,电感把所存储的能量释放给负载。为了确保电感电流能在开关转换过程中保持连续,选用肖特基二极管作为续流二极管选用,这种二极管具有较快的导通截止恢复时间,在开关导通变为截止时,能够很快的由截止转换到导通,所以能够确保电感电流连续。

3.保护电路

在电源输出端,设置负载电流检测电阻R0,通过R0将负载电流Io变成过流检测电压,三极管作为过流控制管,当开关电源负载电流时,过流控制三极管导通,电源输出电压由过流控制管集电极输出,触发晶闸管导通,将开关电源负载短路,实现保护。该电路有自锁功能,一旦负载电流增大的持续时间超过C1的充电时间,电路触发后,即使负载电流恢复正常,也不能解除保护状态,必须关断电源,排除过流因素,晶闸管才能复位。电路中Ro阻值的选择根据负载电流保护阈值而定,一般Ro取电阻值极小,在开关电源正常负载电流时其压降不足0.3v。R1和C1构成保护启动延时电路,以免开机瞬间负载电流冲击造成误动作。下图中,电感和输出端电容之间的部分是保护电路。

4. 软件设计思想

系统扫描键盘输入,当键盘有输入,系统立即会做出响应,根据采样电压与键盘输入之间的差值,更新脉宽,输出用户期望的电压,随后系统仍扫描键盘,当没有再次输入时,系统调用PID控制算法,控制输出电压稳定。电源额定电压为12v,初始化把设定值设为12.00v,系统扫描键盘时,若与该电压相等,系统调用PID算法,在系统每次调用PID控制算法前,若有键盘输入,系统优先响应键盘输入,更新脉宽。

软件子程序包括:(1)键盘和数码管扫描子程序,(2)ADC0832转换子程序,(3)定时器0中断产生方波子程序,(4)PID控制子程序,(5)定时器1中断修改占空比、进行PID控制、数码显示子程序。


【篇幅较大,获取原文及代码首页发送开关电源


电子开发圈

  FPGA | 单片机 | 嵌入式 | PCB

  入门教程 | 开发经验 | 科技资讯

  长按二维码,开启技术之旅吧!

获取海量学习资料阅读原文

2010-11-15 01:35:00 HNSD983704669 阅读数 1342
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4006 人正在学习 去看看 朱有鹏

前几天上单片机课时,老师给我们讲了 单片机 延时子程序,我也发现延时  程序 在单片机中 是非常 常用的,很重要

做作业 写延时程序的时候,感觉根本就不会写,写出来了也是套出来 的,而且 根本就不精确   于是 我就想  我要想一个通用的算法出来,写一个 51单片机 汇编 延时程序 源码生成器,以后 广大的 同学们 或者 单片机 开发者 没 就不用 去套就可以 得到 精确到 一个机器周期的 延时程序了,这个东西也已经做出来了,好了废话少说,现在 开始 和大家分享 我想出来的 算法

 

看几个例子:

一重循环:

   MOV  R0, #3
   DJNZ  R0,$

  

二重循环:

延时时间:T1=2*R0+1

 DELAY:      MOV    R1,#2
LOOP_2:   MOV    R0,#197
                 DJNZ   R0,$
                 DJNZ   R1,LOOP_2

                

 延时: T2=(2*R0+1+2)*R1+1

 

三重循环:

                 MOV      R2,#8
LOOP_3:   MOV    R1,#244
LOOP_4:   MOV    R0,#254
                 DJNZ   R0,$
                 DJNZ   R1,LOOP_4
                 DJNZ   R2,LOOP_3

延时:T3=(  (  (2*R0+1+2)*R1+1)  )+2)*R2+1

 

四重循环:

                 MOV    R3,#18
LOOP_5:   MOV    R2,#255
LOOP_6:   MOV    R1,#255
LOOP_7:   MOV    R0,#255
                DJNZ   R0,$
                DJNZ   R1,LOOP_7
                DJNZ   R2,LOOP_6
                DJNZ   R3,LOOP_5

可以归纳出:

 T2=(T1+2)*R1+1

 T3=(T2+2)*R2+1

 T4=(T3+2)*R3+1

 

仔细看一个  自己也可以再写一个 相信你一定能和我一样 发现这个规律

 

下变进行数学变换一下

将T1 代入T2 表达式

T2=1+3*R2+2*R0*R1

T3=1+3*(R2*R3+R3)+2*R0*R1*R2

T4=1+3*(R2*R3*R4+R3*R4+R4)+2*R0*R1*R2*R3

 

再进行一次归纳,或者说是抽象成一个通式:

 

这个公式是我总结出来的,接下来对公式进行说明:

 

这个是一个K元K次方程     表达式的单位是 机器周期 的个数

 

变量K:循环的次数 R 代表寄存器,下标代表 哪一个寄存器,如 R1

 

假设k=3   则会有 三个未知数 R1  R2  R3

 

大家看到最后加了一个2,原因是 我考虑到 一个子程序 结束时 会有一个返回指令 RET 占用两个机器周期

 

这个东西有什么用呢,很有用 一个未知数 就代表  一个 寄存器的 值 ,表达示结果 就是  用这几个 寄存器 写来来的 K重循环 所延时的机

 

器 周期数,即如果你要 延时 某个 时长(机器周期的整数倍时)  你只要解这个方程就 OK了, 不幸的是 这一个 方程 K个未知数,从数

 

学角度来说就无法解出来,也可能这个方程 根本 就找不到 K 个0—255的数 满足方程的,怎么办呢,是不是放弃呢,大家可以想一想,我

 

们现在是要做什么:

 

我要的是: 输入 要延时的   时长,和晶振   输出: 延时 汇编 源代码

 

你或许会想,也应该明白,如果这个方程 有解,并且你能解出来 那么这个问题就解 决了,而且 就用一个 汇编 循环(不是指一重循环)

 

就能够 达到延时 指定时间的效果,可是我们解不出来,(就算是用穷举法,由于方程可能无满足条件(0—255)的解,所以穷举不一定

 

行,而且很费时间,我已试过 晶振:12MHz  延时:60s  很久 都 穷举不完,下面就说我的方法

 

整体思想:象叠方块样的,大的  上面 叠 小的, 最上面叠  最小的,  当然 不能叠  太多了 ,要不然  汇编 代码 太多了不好 ,占用存储

 

空间

 

具体方法很简单

1、要据上面推导的公式,确定用机重循环可以搞定  即确定K

 

2、个寄存器全部置为255  从最高R8  开始  用二分法  确定  是一个  当R8=R8+1 时 T(k)>要延时时间  

R8=R8-1     T(k)<要延时的时间  且保证  R8=R8时 T(k)<要延时的时间

 直到  R0确定完毕

 

一次近似完毕

3 、 算去 误差 T

 

重复  上面三步  只到 K=0 即 最后 小于一重循环最小值  的机器周期数  的用 NOP 来延迟(也可能不需要,这个由你输入的 晶振 和

延时决定的)

 

从问题的 抽象 到 确定 算法 整个思 路 讲完了,很好的一个东东,可以精确到  每一个机器都期,如:晶振12MHz  就可以精确到 1us

 

 

 

 

 

2016-02-06 14:01:08 sinat_33031415 阅读数 640
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4006 人正在学习 去看看 朱有鹏

51单片机延时计算


时钟周期

若时钟晶振的振荡频率为fosc,则振荡周期 Tosc=(1/fosc)。

如:晶振频率为12MHZ,则振荡周期 Tosc=(1/12us)。

机器周期

对于不同的芯片采用的机器周期各不相同,主要分为:12T、6T、4T、1T等等。

如51系列单片机常见的12T机器周期,每个机器周期占用时间为(12 * 时钟周期)。

依此类推,6T占用的时间为(6 * 时钟周期)。

延时计算

对于语句:
    for(a=n;a>0;a--); 
其延时的大小计算如下:

     delay_time = [(a*2)+3] * 机器周期

但准确的说要加上延时程序调用时间:

    delay_time = ([(a*2)+3] + 5) * 机器周期

例如 :晶振为12MHz、时钟周期为12T的单片机,下面for循环语句:
       for(a=50;a>0;a--)
           for(b=10;b>0;b--);
其延时为:

    delay_time = [(10*2 +3)*50+3]*(1/12)*12 us = 1153us

最后 再加上 5us * 12/12us 程序调用延时的时间

其中 1/12 为晶振决定的机器周期,最后面的 12 是指时钟周期为 12T。
// 部分常用的延时程序
#define u8 unsigned char
/*
    小于4us的延时直接使用_nop_();实现
*/

void delay_1ms()
{
    u8 a,b;
    for(a=142;a>0;a--)
        for(b=2;b>0;b--);
    _nop_();

}

void delay_10us()
{
    u8 a,b;
    for(a=1;a>0;a--)
        for(b=1;b>0;b--);

}


void delay_1s()
{
   u8 a,b,c;
   for(c=46;c>0;c--)
    for(b=152;b>0;b--)
      for(a=70;a>0;a--);
   _nop_(); 

}

2019-01-20 09:47:25 weixin_44212493 阅读数 2222
  • 单片机控制第一个外设-LED灯-第1季第6部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第6个课程,主要讲解LED的工作原理和开发板原理图、实践编程等,通过学习目的是让大家学会给单片机编程控制LED灯,并且为进一步学习其他外设打好基础。

    4006 人正在学习 去看看 朱有鹏

上一次课中,我们已经知道,程序中的符号R7、R6是代表了一个个的RAM单元,是用来放一些数据的,下面我们再来看一下其它符号的含义。
DELAY: MOV R7,#250   ;(6)

D1: MOV R6,#250    ;(7)

D2: DJNZ R6,D2     ;(8)

DJNZ R7,D1    ;(9)

RET         ;(10)在这里插入图片描述
〈单片机延时程序〉

MOV:这是一条指令,意思是传递数据。说到传递,我们都很清楚,传东西要从一本人的手上传到另一本人的手上,也就是说要有一个接受者,一个传递者和一样东西。从指令MOV R7,#250中来分析,R7是一个接受者,250是被传递的数,传递者在这条指令中被省略了(注意:并不是每一条传递指令都会省的,事实上大部份数据传递指令都会有传递者)。它的意义也很明显:将数据250送到R7中去,因此执行完这条指令后,R7单元中的值就应当是250。在250前面有个#号,这又是什么意思呢?这个#就是用来说明250就是一个被传递的东西本身,而不是传递者。那么MOV R6,#250是什么意思,应当不用分析了吧。

DJNZ:这是另一条指令,我们来看一下这条指令后面跟着的两个东西,一个是R6,一个是D2,R6我们当然已知是什么了,查一下D2是什么。D2在本行的前面,我们已学过,这称之为标号。标号的用途是什么呢?就是给本行起一个名字。DJNZ指令的执行过程是这样的,它将其后面的第一个参数中的值减1,然后看一下,这个值是否等于0,如果等于0,就往下执行,如果不等于0,就转移,转到什么地方去呢?可能大家已猜到了,转到第二个参数所指定的地方去(请大家用自已的话讲一下这条语句是怎样执行的)。本条指令的最终执行结果就是,在原地转圈250次。

执行完了DJNZ R6,D2之后(也就是R6的值等于0之后),就会去执行下面一行,也就是DJNZ R7,D1,请大家自行分析一下这句话执行的结果。(转去执行MOV R6,#250,同时R7中的值减1),最终DJNZ R6,D2这句话将被执行250*250=62500次,执行这么多次同一条指令干吗?就是为了延时。

一个问题:如果在R6中放入0,会有什么样的结果。

二、时序分析:

前面我们介绍了延时程序,但这还不完善,因为,我们只知道DJNZ R6,D2这句话会被执行62500次,但是执行这么多次需要多长时间呢?是否满足我们的要求呢?我们还不知道,所以下面要来解决这个问题。

先提一个问题:我们学校里什么是最重要的。(铃声)校长能出差,老师能休息,但学校一日无铃声必定大乱。整个学校就是在铃声的统一指挥下,步调一致,统一协调地工作着。这个铃是按一定的时间安排来响的,我们能称之为“时序��时间的次序”。一个由人组成的单位尚且要有一定的时序,计算机当然更要有严格的时序。事实上,计算机更象一个大钟,什么时候分针动,什么时候秒针动,什么时候时针动,都有严格的规定,一点也不能乱。计算机要完成的事更复杂,所以它的时序也更复杂。

我们已知,计算机工作时,是一条一条地从ROM中取指令,然后一步一步地执行,我们规定:计算机访问一次存储器的时间,称之为一个机器周期。这是一个时间基准,好象我们人用“秒”作为我们的时间基准一样,为什么不干脆用“秒”,多好,很习惯,学下去我们就会知道用“秒”反而不习惯。

一个机器周期包括12个时钟周期。下面让我们算一下一个机器周期是多长时间吧。设一个单片机工作于12M晶体震荡器,它的时钟周期是1/12(微秒)。它的一个机器周期是12*(1/12)也就是1微秒。(请计算一个工作于6M晶体震荡器的单片机,它的机器周期是多少)。

MCS-51单片机的所有指令中,有一些完成得比较快,只要一个机器周期就行了,有一些完成得比较慢,得要2个机器周期,还有两条指令要4个机器周期才行。这也不难再解,不是吗?我让你扫地的执行要完成总得比要你完成擦黑板的指令时间要长。为了恒量指令执行时间的长短,又引入一个新的概念:指令周期。所谓指令周期就是指执行一条指令的时间。INTEL对每一条指令都给出了它的指令周期数,这些数据,大部份不需要我们去记忆,但是有一些指令是需要记住的,如DJNZ指令是双周期指令。

下面让我们来计算刚才的延时。首先必须要知道晶体震荡器的频率,我们设所用晶体震荡器为12M,则一个机器周期就是1微秒。而DJNZ指令是双周期指令,所以执行一次要2个微秒。一共执行62500次,正好125000微秒,也就是125毫秒。

如果你对上面几句还是不懂请看这里的详解:http://www.51hei.com/mcu/1247.html

关于用C语言写延时函数的详解请看这:http://www.51hei.com/mcu/710.html

练习:设计一个延时100毫秒的延时程序。

要点分析:1、一个单元中的数是否能超过255。2、如何分配两个数。

三、复位电路

一、复位方式

⒈ 复位条件
RST引脚保持2个机器周期以上的高电平。

⒉ 复位电路
在这里插入图片描述
〈单片机复位电路〉

⒊ 复位后CPU状态

   PC:  0000H         TMOD: 00H

   Acc: 00H           TCON: 00H

   B:   00H           TH0:  00H

   PSW: 00H           TL0:  00H

   SP:  07H           TH1:  00H

   DPTR:0000H         TL1:  00H

   P0~P3:FFH         SCON: 00H

   IP:×××00000B    SBUF: 不定

   IE:0××00000B     PCON: 0×××0000B

任何单片机在工作之前都要有个复位的过程,复位是什么意思呢?它就象是我们上课之前打的预备铃。预备铃一响,大家就自动地从操场、其它地方进入教室了,在这一段时间里,是没有老师干预的,对单片机来说,是程序还没有开始执行,是在做准备工作。显然,准备工作不需要太长的时间,复位只需要5ms的时间就能了。如何进行复位呢?只要在单片机的RST管脚上加上高电平,就能了,按上面所说,时间不少于5ms。为了达到这个要求,能用很多种办法,这里供给一种供参考,见图1。实际上,我们在上一次实验的图中已见到过了。

这种复位电路的工作原理是:通电时,电容两端相当于是短路,于是RST管脚上为高电平,然后电源通过电阻对电容充电,RST端电压慢慢下降,降到一定程序,即为低电平,单片机开始正常工作。

附送郭天祥十天学会51单片机精品教程

下载地址: https://pan.baidu.com/s/17sSfQEnpbv6U0xpFb_4Ddg

51单片机延时程序

阅读数 2718

没有更多推荐了,返回首页