2017-06-26 10:04:53 little_white__ 阅读数 5271
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

要求:测量脉冲的周期
思想:用定时器和外部中断(下降沿触发中断),当第一个下降沿时,触发外部中断,此时开始计时。当第二个下降沿时,此时停止计时,此时的时间就是脉冲的周期。
程序:

#include <reg51.h>
#include <intrins.h>

#define uLint unsigned long int

uLint cycle_t = 0 ;//脉冲周期时间
sbit in = P3^2 ;
bit start = 0 ;
void Int0 (void) interrupt 0
{ 
	if(start == 0)//第一次下降沿开始计时
	{
		cycle_t = 0 ;
		TL0 = 0 ;	
	}
	if(start == 1)		 //第二次下降沿结束计时
	{
		 cycle_t += TL0 ;
		 TL0 = 0 ;
	}
	start = ~start ;
}

void Time0(void) interrupt 1
{
	cycle_t += 256 ;
}

int main()
{
	//初始化
	TMOD = 0x2 ; //定时器0,模式2
	TH0 = 0 ;
	TL0 = 0 ;
	TR0 = 1 ;
	ET0 = 1 ;
	
	IT0 = 1 ;
	EX0 = 1 ;
	EA = 1 ;
	
	while(1)
	{
			
	}		
}

信号函数:


signal void test() 
{
	int i ;
	for(i = 0 ; i < 10 ; i++)
	{
		port3 &= ~(0x1<<2)  ;
		swatch(0.5) ;
		port3 |= (0x1<<2) ;	
		swatch(0.7) ;
		port3 &= ~(0x1<<2)  ;
	}

	_break_ = 1 ;
	  
}

这里写图片描述
这里写图片描述

2016-10-02 22:16:58 zhengqijun_ 阅读数 1867
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

    3997 人正在学习 去看看 朱有鹏
一、时钟周期

1.时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。

2.在一个时钟周期内,CPU仅完成一个最基本的动作。对于某种单片机,若采用了1MHZ的时钟频率,则时钟周期为1us;若采用4MHZ的时钟频率,则时钟周期为250us。

3.由于时钟脉冲是计算机的基本工作脉冲,它控制着计算机的工作节奏(使计算机的每一步都统一到它的步调上来)。

4.显然,对同一种机型的计算机,时钟频率越高,计算机的工作速度就越快。但是,由于不同的计算机硬件电路和器件的不完全相同,所以其所需要的时钟周频率范围也不一定相同。

5.我们学习的8051单片机的时钟范围是1.2MHz-12MHz。在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。


二、机器周期
1.在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。
  例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。
2.一般情况下,一个机器周期由若干个S周期(状态周期)组成。8051系列单片机的一个机器周期同6个S周期(状态周期)组成。
  前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。

三、指令周期
1.指令周期是执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期数也不同。
2.对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。
3.对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。

4.通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。


四、补充

1. 利用外部电路的驱动能力,减少IC内部的驱动。当IC内部MOSFET导通时,驱动电流是从外部的VCC流经R pull-up ,MOSFET到GND。IC内部仅需很下的栅极驱动电流。
2. 一般来说,开漏是用来连接不同电平的器件,匹配电平用的,因为开漏引脚不连接外部的上拉电阻时,只能输出低电平,
   如果需要同时具备输出高电平的功能,则需要接上拉电阻,很好的一个优点是通过改变上拉电源的电压,便可以改变传输电平。比如加上上拉电阻就可以提供TTL/CMOS电平输出等。(上拉电阻的阻值决定了逻辑电平转换的沿的速度 。阻值越大,速度越低功耗越小,所以负载电阻的选择要兼顾功耗和速度。)
3. OPEN-DRAIN提供了灵活的输出方式,但是也有其弱点,就是带来上升沿的延时。因为上升沿是通过外接上拉无源电阻对负载充电,所以当电阻选择小时延时就小,但功耗大;
反之延时大功耗小。所以如果对延时有要求,则建议用下降沿输出。



2019-10-20 15:52:41 qq_42705035 阅读数 25
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

51单片机测量脉宽,数码管显示@[TOC]单片机

#include<REGX51.H>
#include<intrins.h>
typedef unsigned int uint16_t;
typedef unsigned char uint8_t;

uint8_t code seg_cc_table [] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c};//0-9
uint8_t code dig_cc_table [] = {0xfe,0xfd,0xfb,0xf7};

uint16_t high = 0;
uint16_t period = 0;

sbit pulse = P3^2;

uint8_t total_num[] = {0,0,0,0};

void delay_ms(uint16_t xms)
{
uint16_t i = 0;
uint8_t j = 0;

for(i = 0; i < xms; i++)
{
	for(j = 0; j < 75; j++)
	_nop_();
}

}

void main()
{

	uint16_t total =0;
	uint16_t i = 1;
  P2 = 0Xf0;
	P1 = 0x3f;

// TMOD&= 0xf0;
// TMOD|= 0x0d; // 0000 1001
TMOD = 0x09;
TH0 = 0;
TL0 = 0;
ET0 = 1;
EA = 1;
while(pulse1);
TR0=1;
while(pulse
0);
while(pulse==1);
TR0=0;
while(1)
{

			high = (uint16_t)TH0*256+TL0;
			total = high;
			total_num[0]= total %10;
			total_num[1]= total/10 %10;
			total_num[2]= total /100%10;
			total_num[3]= total /1000;
			
		for(i=0;i<4;i++)
		{
				P2 = dig_cc_table[i];
				P1 = seg_cc_table[total_num[i]];
				delay_ms(1);
				P1 = 0x00;
		}		
	}	
}

200HZ

2017-11-04 20:33:44 HopesunIce 阅读数 4333
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

声明:

以下内容均来自各个网站上的搜索  如有冒犯各位大哥大姐大仙们的地方 请立刻联系我  马上删除   纯粹为了学习 嘿嘿  还有一点是为了装个X

因为最近在学80c51单片机  虽然以前学过一点 但是理论知识还是很不扎实 这次学的时候顺带扎实一下细节的理论吧 毕竟将来还想做一个人民教师呢 哈哈哈 
说一下单片机中最基本的几个周期之间的关系 以及对他们的定义理解吧 


名词:  振荡周期  时钟周期  状态周期  机器周期  指令周期

     1:先来说一下振荡周期和时钟周期 其实呢 时钟周期在51单片机里面来说 就是振荡周期但是在其他单片机里面来说不是!!!(如果单片机晶振出来的频率没有经过分频就直接作为CPU的频率  那么这时候 晶振周期=振荡周期=时钟周期) 对单片机来说  时钟周期是其基本的时间单位!ok吧  不过我在网上也看到有人说一个时钟周期等于两个振荡周期 不知道是什么鬼 我觉得这样理解就挺好的  管他对不对 哈哈哈 

振荡周期(oscillating period)

  在衰减振荡中,两个相邻同方向峰值之间的时间称为振荡周期Tp,振荡频率2π/Tp。在相同衰减比下,振荡周期越短或振荡频率越高,则回复时间越短,因此振荡周期(频率)反映系统响应快慢的指标。


    2:状态周期   在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。即两个时钟周期=状态周期

   3:机器周期  机器周期,一般也叫CPU周期。在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段(如,取指令、存储器读、存储器写等),每一阶段完成一项工作(称为一个基本操作)。完成一个基本操作所需要的时间称为机器周期。一般情况下,一个机器周期由若干个S周期(状态周期)组成。 在51单片机中 一个机器周期=6状态周期=12时钟周期

    4:指令周期    指令周期是执行一条指令所需要的时间,即CPU从内存取出一条指令并执行这条指令的时间总和。一般由若干个机器周期组成,从取指令、分析指令到执行完所需的全部时间。指令不同,所需的机器周期数也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。

最后 在学中断的时候   在INT0中的触发方式的时候  说CPU在每个机器周期的S5P2的时候对INT0引脚采样   这里的S5P2 是什么呢  嘿嘿 容我把百度的答案拿过来

1、每个状态周期有P1和P2两个相,每个相占一个振荡周期,故一个机器周期为12个振荡周期.
2、在每个时钟周期(即机器状态时间S)的前半周期,相位1(即P1信号)有效,在每个时钟周期的后半周期,相位2(即P2信号)有效。
3、每个时钟周期(S)有两个节拍即相位P1和P2(可理解为P1:高电平,P2:低电平),CPU以两相时钟P1和P2为基本节拍指挥8051各们部件协调工作。
PS:因此,S5P2: 第5个时钟周期的相位2(后半拍)。




2019-10-26 16:58:33 crazy_kismet 阅读数 587
  • 单片机控制第一个外设-LED灯-第1季第6部分

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

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

单片机测量PWM占空比的三种方法

PWM(Pulse Width Modulation),一般指脉冲宽度调节,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中,比如LED亮度调节、电机转速控制等。
而在某些特殊应用中,我们也需要通过测量输入PWM的占空比,来实现不同的输出控制,这就需要使用到PWM占空比的测量方法。这里介绍三种不同的测量方法:阻塞方式、中断方式以及定时器捕获功能。

1. 阻塞方式

MCU阻塞方式测量PWM占空比的原理比较简单,也只需要使用到一个普通的IO端口(设置为输入模式,对于51而言那就是一个普通的双向口)。具体实现流程为:

  • 等待上升沿到来,然后开启定时器,开始计时;
  • 等待下降沿到来,记录下定时器的计数值,即得到PWM的高电平时间H
  • 同时,清零定时器,重新开始计数;
  • 等待上升沿到来,记录下定时器的计数值,即得到PWM的低电平时间L
  • 计算得出占空比:duty = H / (H + L);

阻塞方式原理简单,而且只需要MCU有一个定时器的资源即可实现;但采集时阻塞CPU运行,阻塞的时间和输入PWM的周期相关,只适用于实时性较低的系统。

另外,上述流程中存在着一个严重的BUG,即当输入的PWM占空比为0%或者100%时,程序会被一直阻塞,等待上升沿/下降沿的到来。所以解决方法是,在等待上升沿/下降沿的过程中,实时提取定时器的值,一旦定时时间超过1个周期的限定(一般可定义为2-3个周期时间),即退出等待,并根据端口电平判断此时占空比为0%(低电平)或100%(高电平)

示例代码,仅供参考:

//获取PWM输入脚的电平
#define PWM_IN()   xxxxxx
//定义超时时间(如2-3倍PWM周期)
#define T1_TIMEOUT  xxxxxx

uint8_t PWM_Analyse(void)
{
    uint8_t duty = 0xFF;
    uint16_t pwm_H = 0;
    uint16_t pwm_L = 0;

    if (PWM_IN())   //初始为高电平,则开始等待低电平
    {
        TH1 = 0;
        while (PWM_IN()) //等待下降沿
        {
            if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
            {
                duty = 100;
                return duty;
            }
        }

        TH1 = 0;
        TL1 = 0;
        while (!PWM_IN()) //等待上升沿
        {
            if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
            {
                duty = 0;
                return duty;
            }
        }
        pwm_L = (TH1 << 8) | TL1;

        TH1 = 0;
        TL1 = 0;
        while (PWM_IN()) //等待下降沿
        {
            if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
            {
                duty = 100;
                return duty;
            }
        }
        pwm_H = (TH1 << 8) | TL1;

        duty = pwm_H * 100 / (pwm_H + pwm_L);
        return duty;
    }
    else    //当前为低电平,则开始等待高电平
    {
        TH1 = 0;
        while (!PWM_IN()) //等待上升沿
        {
            if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
            {
                duty = 0;
                return duty;
            }
        }

        TH1 = 0;
        TL1 = 0;
        while (PWM_IN()) //等待下降沿
        {
            if (TH1 >= T1_TIMEOUT)  //下降沿没有到来,判定为100%占空比
            {
                duty = 100;
                return duty;
            }
        }
        pwm_H = (TH1 << 8) | TL1;

        TH1 = 0;
        TL1 = 0;
        while (!PWM_IN()) //等待上升沿
        {
            if (TH1 >= T1_TIMEOUT)  //上升沿没有到来,判定为0%占空比
            {
                duty = 0;
                return duty;
            }
        }
        pwm_L = (TH1 << 8) | TL1;

        duty = pwm_H * 100 / (pwm_H + pwm_L);
        return duty;
    }

    return 0xFF;
}

2. 中断方式

中断方式的PWM采集原理与阻塞方式相同,只是将判定移动至外部中断中。开启MCU端口的外部中断(上升沿和下降沿中断);如果MCU外部中断触发不支持上升和下降沿中断,则先开启上升沿中断,在中断处理中切换中断触发条件。

处理方法:在中断处理函数中,根据当前电平状态,记录下定时器的值,并清零定时器的值,重新开始下一轮计时。

0%和100%的处理:设定一个定时递增的变量,同时在外部中断中执行清零操作。若该变量超过一定值(说明外部中断有较长时间没有触发),则判定为0%或100%。

uint16_t pwm_H = 0;
uint16_t pwm_L = 0;
uint16_t pwm_time_out = 0;
void EXT1_ISR(void) interrupt EXTI1_VECTOR
{
    if (PWM_IN())
    {
        pwm_L = (TH1 << 8) | TL1;    //记录低电平时间
        TH1 = 0;
        TL1 = 0;
    }
    else
    {
        pwm_H = (TH1 << 8) | TL1;    //记录高电平时间
        TH1 = 0;
        TL1 = 0;
    }

    //该变量定时递增(如1ms递增1),在外部中断中清零
    //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
    pwm_time_out = 0;

    return;
}

注:使用中断方式,则占空比计算不建议放在中断中处理;同时,为了保证占空比的准确性,可以连续2-3次计算结果一致时,再确定当前占空比的结果。

3. MCU捕获方式

采用捕获方式的前提是MCU支持捕获功能。当前部分厂家推出的51内核单片机,会包含一个定时器2,其拥有捕获功能;或者采用32位单片机,一般都带有捕获功能。捕获的原理很简单,当上升沿或下降沿来临时,MCU硬件将定时器/计数器的值保存在一个影子寄存器中,并产生捕获中断。
通过固定每次上升/下降沿的计数器值,相减即可分别得出高电平值和低电平值,从而计算出占空比。
pwm占空比捕获原理
下面以某颗51内核的MCU为例,提供示例代码:

unsigned int pwm_fall = 0, pwm_rise = 0;

volatile unsigned int pwm_H;
volatile unsigned int pwm_L;

volatile unsigned char pwm_time_out;
//------------------------------------------------------------
void T2_interrupt(void) interrupt 5          //定时器2中断;
{

    if (CCCON & 0x02) //CC1中断标志位
    {
        CCCON  &= 0xFD; //清除中断标志

        if (PWM_IN())   //上升沿触发
        {
            pwm_rise = CC1;     //获取捕获寄存器中的值
            pwm_L = pwm_rise - pwm_fall;
        }
        else
        {
            pwm_fall = CC1;     //获取捕获寄存器中的值
            pwm_H = pwm_fall - pwm_rise;
        }

        //该变量定时递增(如1ms递增1),在外部中断中清零
        //在主程序中判断,超过一定值时认为PWM占空比为0%或100%
        pwm_time_out = 0;
    }
}

注: pwm_rise/pwm_fall/pwm_L/pwm_H都必须使用无符号数,否则相减时可能得到错误的值。

总结

方式一任何单片机都可以实现,但是阻塞方式会使系统的实时性变差;
方式二在使用时,需要保证外部中断的最高优先级,不可以被其他中断打断,以保证其准确性;
方式三的稳定性和准确性都较高,但是需要MCU硬件支持。

单片机周期的概念

阅读数 4704

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