51单片机测量占空比

发布者:荣耀使者最新更新时间:2016-12-10 来源: eefocus关键字:51单片机  测量占空比 手机看文章 扫描二维码
随时随地手机看文章

在《CAP功能测频率》一文中,我们讲了利用STC12C5608AD的CAP功能测量频率,这一节,我们讲利用CAP功能测量频率的占空比,下面的程序,是我在做一个显示汽车发动机点火喷油脉宽项目时做的程序。现在分享给大家:

/**************************************************************************
功能:测量频率的低电平保持时间,用来测量汽车喷油嘴喷油的时间,单位ms
硬件:STC12C5608AD+3位LED+TM1620+12M晶振+LM358+74HC14
****************************************************************************/
#include // 调用头文件,可以上官方下载STC12C5608AD下载头文件
#include 
#include        //因为本例中,有用到modf;所以必须调用该头文件  

#define uint  unsigned int     // 宏定义uint (0~65535)
#define uchar unsigned char  // 

#define WAIT_TIME  0x01    //mcu clock <24mhz // 定义Flash 操作等待时间
#define OPENUART 0 // 0 关闭串口, 1 打开串口

sbit STB =P3^2;        // 定义片选通讯口
sbit CLK =P3^3;        // 定义时钟通讯口
sbit DIO =P3^4;        // 定义数据输入/输出通讯口

sbit CheSu1 = P3^5;    // 测试速度的引脚
sbit KEY1 = P1^7;

uchar bai_num,shi_num,ge_num;
uint CheSu;//表示低电平的时间,单位10us
//uint CS_F=0; // 上一个车速寄存器
uchar CheSu_Clr=0;

unsigned int cap_tmp;
//float xielv=1.0; // 车速与车速频率的斜率
//float chesu_f;
//uchar CheSu_error[5]={0};
//uchar cse_cnt=0;
//uchar jiao=0; // 车速校正开关

static uchar code LED_tab[12]={  // 定义数码管0~9数字码表
0x3f,    //0B00111111,       //0
0x06,    //0B00000110,       //1
0x5b,    //0B01011011,         //2
0x4f,    //0B01001111,         //3
0x66,    //0B01100110,         //4
0x6d,    //0B01101101,         //5
0x7d,    //0B01111101,         //6
0x07,    //0B00000111,         //7
0x7f,    //0B01111111,         //8
0x6f,    //0B01101111,         //9
0x40,                         //-   
0x00    
};

unsigned char out_data[2]={0x00};

void delay_ms(uint cyc)
{
    //当将=1的时候,延时1ms
    uint ii,jj;

    for(jj=1;jj<=cyc;jj++)
    {
        for(ii=0;ii<940;ii++)
        {
            _nop_();
        }
    }
}

void TM1620_Write(uchar wr_data)
{
    uchar i;

    for(i=0;i<8;i++)
    {
        CLK = 0;
        if(wr_data&0x01)DIO = 1;
        else DIO = 0;
        CLK = 1;
        wr_data>>=1;
    }                 
}

void Write_COM(unsigned char cmd)        //发送命令字
{
    STB = 0;
    TM1620_Write(cmd);
    STB = 1;
}

void init_TM1620(void)
{
    Write_COM(0x44);  // 01000000准备写数据到显示寄存器,普通模式,自动地址增加
    STB=0;
    TM1620_Write(0xc0);     // 11000000 设置显示地址从0开始
    TM1620_Write(0x00);      // 所有显示为灭
    STB=1;
    STB=0;
    TM1620_Write(0xc2);
    TM1620_Write(0x00);
    STB=1;
    STB=0;
    TM1620_Write(0xc4);
    TM1620_Write(0x00);
    STB=1;
    Write_COM(0x8a);  // 最亮    10001111 设置消光脉冲14/16 显示开
}

void led_show()
{
//    Write_COM(0x44);  // 01000000准备写数据到显示寄存器,普通模式,自动地址增加
    STB=0;
    TM1620_Write(0xc0);     // 11000000 设置显示地址从0开始
    TM1620_Write(LED_tab[bai_num]);      // 所有显示为灭
    STB=1;
    STB=0;
    TM1620_Write(0xc2);     // 11000000 设置显示地址从0开始
    TM1620_Write(LED_tab[shi_num]);      // 所有显示为灭
    STB=1;    
    STB=0;
    TM1620_Write(0xc4);     // 11000000 设置显示地址从0开始
    TM1620_Write(LED_tab[ge_num]);      // 所有显示为灭
    STB=1;
}

void CAP_Init(void)
{
    // T0、T1打开,T0做PCA时钟,T1做定时器,在中断里喂狗和给CheSu清零
    TMOD=0x12;  // T0工作在8位自动重载模式,T1工作在16位模式
    TH0=0XF6;         //12M下的值,10us
    TL0=0XF6;
    TR0=1;
    TH1=0X00;
    TL1=0X00;
    ET1=1;
    TR1=1;

    // PCA计数器打开
    CMOD = 0X04;   // 选择T0的溢出为PCA计数时钟
    CCAPM1 = 0X11; // CAPN0 = 1; 下降沿捕获。ECCF0 = 1; 开捕获中断。
    CL = 0;
    CH = 0; // PCA计数器清零
    CCAP1L = 0;
    CCAP1H = 0; // 捕获寄存器清零
    EPCA_LVD = 1; // 开PCA中断
//    CR = 1;
}

/********************************************************************/
/**********************  T1中断服务函数  ****************************/
/********************************************************************/
// 65.536毫秒进一次中断
void T1_SER() interrupt 3
{
    CheSu_Clr++;
    WDT_CONTR=0x3C; // 1.1377s不喂狗复位
    if(CheSu_Clr>=17) // 1秒钟没有进PCA中断函数清CheSu_Clr,车速归0
    {
        out_data[0]=0;
        out_data[1]=0;
        CheSu_Clr=0;  // 车速为0标志
        CheSu=0;
    }    
}

// PCA中断服务函数
void PCAIRQ(void) interrupt 6
{    
    if(CCF1==1)  // 如果是PCA1捕获产生的中断
    {
        CCF1=0;
        if(CCAPM1==0X11)
        {
            CR = 1; // 打开PCA计数器
            CCAPM1 = 0X21;// 配置为上升沿触发中断
        }
        else
        {
            CR = 0;// 关闭PCA计数器
            CCAPM1 = 0X11; // 配置为下降沿触发中断
            out_data[0]=CCAP1L;
            out_data[1]=CCAP1H;
            CH=0;
            CL=0;
            // 获取当前低电平保持时间数据
            cap_tmp=out_data[1]<<8;
            cap_tmp+=out_data[0];    
            CheSu = cap_tmp;
        }
  } 
    else if(CF==1) // 如果是PCA溢出产生的中断
    {
        CF = 0;
    }
    CheSu_Clr=0;
}

void led_xian(uint led_val)
{
    if(led_val<1000) // 小于1000,显示为0.00格式,单位毫秒
    {
        bai_num=(led_val/100);
        shi_num=(led_val%100)/10;
        ge_num=(led_val%100)%10;
        STB=0;
        TM1620_Write(0xc0);     // 11000000 设置显示地址从0开始
        TM1620_Write(LED_tab[bai_num]|0x80);      // 所有显示为灭
        STB=1;
        STB=0;
        TM1620_Write(0xc2);     // 11000000 设置显示地址从0开始
        TM1620_Write(LED_tab[shi_num]);      // 所有显示为灭
        STB=1;    
        STB=0;
        TM1620_Write(0xc4);     // 11000000 设置显示地址从0开始
        TM1620_Write(LED_tab[ge_num]);      // 所有显示为灭
        STB=1;
    }
    else // 大于等于1000,显示为00格式,单位毫秒
    {
        bai_num = 11;
        shi_num = (led_val/100)/10;
        ge_num = (led_val/100)%10;
        led_show();
    }
}

void main()
{
    unsigned int ms_cnt=0;

    CLK = 1;            // 上拉TM1629B通信时钟引脚
    STB = 1;            // 上拉TM1629B通信片选引脚
    DIO = 1;            // 上拉TM1629B通信数据引脚

    init_TM1620();      // 初始化LED控制芯片
    bai_num=11;
    shi_num=11;
    ge_num=0;
    led_show();

    delay_ms(1200);
    CAP_Init();
    EA = 1;

    while(1)
    {
        ms_cnt++;
        delay_ms(1);
        if(ms_cnt>300) // 300毫秒显示一次数据
        {
            ms_cnt=0;        
            if(CheSu<1000)
            {    
                led_xian(CheSu);
            }
        }
    }
}


关键字:51单片机  测量占空比 引用地址:51单片机测量占空比

上一篇:stc51单片机硬件SPI驱动nrf24l01程序
下一篇:51单片机驱动1602程序

推荐阅读最新更新时间:2024-03-16 15:24

51单片机 基于LED点阵的9~0倒计数
#include reg52.h sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4; unsigned char code image = { {0xC3, 0x81, 0x99, 0x99, 0x99, 0x99, 0x81, 0xC3}, //数字0 {0xEF, 0xE7, 0xE3, 0xE7, 0xE7, 0xE7, 0xE7, 0xC3}, //数字1 {0xC3, 0x81, 0x9D, 0x87, 0xC3, 0xF9, 0xC1, 0x81}, //数字2 {0xC3
[单片机]
51单片机实现贪食蛇的子程序
这是从 http://www.51hei.com/bbs/dpj-20623-1.html 这个 制作 里面截取的一段子程序,调用函数请下载里面的附件. 下面是mysanke.h文件: #ifndef _MYSNAKE_H_ #define _MYSNAKE_H_ /*--------------------------------------------------------- 函数功能:检测随机落食是否压在已存在的亮点上 调用形式:Check_Food(*node); 参数:结构体指针 返回值:返回食物是否可以放置1- 可以 0- 不可以 备注:食物产生函数调用此函数用于 检测 -----------------
[单片机]
<font color='red'>51单片机</font>实现贪食蛇的子程序
51单片机~DS18B20温度传感器
(一)简介说明: (二)接线: 1. 内部结构: 正温度前五位是0. 负温度前五位是1. 由LS,MS组成的四位十六进制数,和16位二进制数。(先MS后LS) 结合上下图直到温度计算:1乘2 ^ 6 + 0乘2 ^ 5 +1乘2^ 4 +0乘2^ 3 +……2^0 ==85 (二)使用流程,按照时序图编写程序(判断应用): 粗黑线是总线控制的电平 灰线表示DS18B20控制的; 电阻上拉是由于上图接线有一个上拉电阻 读时重复七次直到读完为止 测试温度代码: temp.h #ifndef __TEMP_H_ #define __TEMP_H_ #include reg52.h
[单片机]
<font color='red'>51单片机</font>~DS18B20温度传感器
51单片机红外遥控旋转LED数字电子钟一
  在网上看到不少老外做的各种旋转LED显示屏,非常COOL,我也动手用洞洞板试做了一个类似的显示屏,结果感觉还不错。于是再接再励继续努力,将作品进一步改进,完善后制成如今这个样子。   由于刚学51单片机,加上制作电路板软件也是从零开始,的确花了我不少的时间和精力。不过也就是在这艰难的独立制作中,真正学到了不少实在的东西。   本项目的关键是如何解决高速旋转的电路板如何供电,如何调时的问题。我采用电机电刷的原理,将旋转轴钻空,通过一只插头将电源的从反面引到前面的电路板上,而这个旋转的插头又与固定在背板上的两个铜片接触的。调时的问题有些困难,一是让电路板在旋转前与PC机相接,由电脑传送调时数据,这虽然可行但不方便。还有就是
[模拟电子]
<font color='red'>51单片机</font>红外遥控旋转LED数字电子钟一
两种方法教你如何有效地利用51单片机产生PWM波
89C51芯片没有自带PWM发生器,如果要用51来产生PWM波就必须要用软件编程的方法来模拟。方法大概可以分为软件延时和定时器产生两种方法。下面将逐一介绍。 1 软件延时法 利用软件延时函数,控制电平持续的时间,达到模拟pwm的效果。 程序如下: #include sbit pwm=P1^0; main() { while(1) { pwm=1; delayus(60);//置高电平后延时60us,占空比60% pwm=0; delayus(40); } } void delayus(uint x) { while(x--); } proteus软件仿真结果如下: 可见,用这种延时函数的方法就能简单地模拟出pwm输出。
[单片机]
两种方法教你如何有效地利用<font color='red'>51单片机</font>产生PWM波
51单片机C语言调用汇编子程序的简便方法
1、在汇编文件中,程序前边加上如下三句话就可以: PUBLIC _delay, _binrlc ;定义公用子程序名,这里定义了两个子程序(有下划线) LUOYUAN SEGMENT CODE ;程序段命名,LUOYUAN,叫啥名都可以 RSEG LUOYUAN 下边放子程序(程序名要下划线,其它标号不要下划线) ;汇编语言文件 PUBLIC _delay, _binrlc;定义子程序名 LUOYUAN SEGMENT CODE ;命名LUOYUAN的程序段 RSEG LUOYUAN _delay: MOV P1,#55H MOV R2,#30H DJNZ R2,$ RET
[单片机]
51单片机特殊功能寄存器和位定义
接下来的几节,我们会带着大家编写第一个单片机程序。在此之前,我们先来了解一些 51 单片机特有的程序语法以及 Keil 软件的基本操作步骤,请大家一定要有耐心。 我们主要是用 C 语言来对单片机编程,而有的单片机有那么几条很特殊的独有的编程语句,51 单片机就有,先介绍 2 条。 第一条语句是:sfr P0 = 0x80; sfr 这个关键字,是 51 单片机特有的,他的作用是定义一个单片机特殊功能寄存器(special function register)。51 单片机内部有很多个小模块,每个模块居住在拥有唯一房间号的房间内,同时每个模块都有 8 个控制开关。P0 就是一个功能模块,就住在了 0x80 这个房间里,我们就是通过设
[单片机]
<font color='red'>51单片机</font>特殊功能寄存器和位定义
什么是51单片机最小系统
1.什么是51单片机 51 内核单片机是 指兼容Intel 的8051指令系统的单片机统称;从诞生到现在的几十年时间,已成为一款经过市场考验、成熟的芯片产品。目前国内也众多51单片机厂家,且还有众多带51内核,用于各种不同场景的专用类单片机。 51单片机内部框架: 以下以STC89C52单片机为例,其内部总体结构其基本特性如下: 8位CPU、4-8k 字节 ROM、128 字节 RAM、21 个特殊功能寄存器32根I/0线、可寻址的 64 字节外部数据、程序存贮空间、2个 16 位定时器计数器中断结构:具有二个优先级、五个中断源、一个全双工串行口、位寻址(即可对寄存器进行位操作)功能,能按位进行逻辑运算的位处理器。 除 1
[单片机]
什么是<font color='red'>51单片机</font>最小系统
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved