单片机计数器C语言练习

发布者:EtherealGaze最新更新时间:2013-02-18 来源: dzsc关键字:单片机  计数器  C语言练习 手机看文章 扫描二维码
随时随地手机看文章
    要求:编写一个计数器程序,将T0作为计数器来使用,对外部信号计数,将所计数字显示在数码管上。

  该部分的硬件电路如图所示,U1的P0口和P2口的部份引脚构成了6位LED数码管驱动电路,数码管采用共阳型,使用PNP型三极管作为片选端的驱动,所有三极管的发射极连在一起,接到正电源端,它们的基极则分别连到P2.0…P2.5,当P2.0…P2.5中某引脚输是低电平时,三极管导通,给相应的数码管供电,该位数码管点亮哪些笔段,则取决于笔段引脚是高或低电平。图中看出,所有6位数码管的笔段连在一起,通过限流电阻后接到P0口,因此,哪些笔段亮就取决于P0口的8根线的状态。


  编写程序时,首先根据硬件连线写出LED数码管的字形码、位驱动码,然后编写程序如下:

  #include "reg51.h"

  #define uchar unsigned char

  #define uint  unsigned int

  uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB}; //位驱动码

  uchar code DispTab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,

0x83,0xC6,0xA1,0x86,0x8E,0xFF}; //字形码

  uchar DispBuf[6]; //显示缓冲区

  void Timer1() interrupt 3

  { uchar tmp;

  uchar Count; //计数器,显示程序通过它得知现正显示哪个数码管

  TH1=(65536-3000)/256;

  TL1=(65536-3000)%256; //重置初值

  tmp=BitTab[Count]; //取位值

  P2=P2|0xfc; //P2与11111100B相或

  P2=P2&tmp; //P2与取出的位值相与

  tmp=DispBuf[Count];//取出待显示的数

  tmp=DispTab[tmp]; //取字形码

  P0=tmp;

  Count++;

  if(Count==6)

  Count=0;

  }

  void main()

  { uint tmp;

  P1=0xff;

  P0=0xff;

  TMOD=0x15; //定时器0工作于计数方式1,定时器1工作于定时方式1

  TH1=(65536-3000)/256;[page]

  TL1=(65536-3000)%256; //定时时间为3000个周期

  TR0=1; //计数器0开始运行

  TR1=1;

  EA=1;

  ET1=1;

  for(;;)

  { tmp=TL0|(TH0<<8); //取T0中的数值

  DispBuf[5]=tmp%10;

  tmp/=10;

  DispBuf[4]=tmp%10;

  tmp/=10;

  DispBuf[3]=tmp%10;

  tmp/=10;

  DispBuf[2]=tmp%10;

  DispBuf[1]=tmp/10;

  DispBuf[0]=0;

  }}

  这个程序中用到了一个新的知识点,即数组,首先作一个介绍。

  数组是C51的一种构造数据类型,数组必须由具有相同数据类型的元素构成,这些数据的类型就是数组的基本类型,如:数组中的所有元素都是整型,则该数组称为整型数组,如所有元素都是字符型,则该数组称为字符型数组。

  数组必须要先定义,后使用,这里仅介绍一维数组的定义,其方式为:

  类型说明符 数组名[整型表达式]

  定义好数组后,可以通过:数组名[整型表达式]来使用数组元素。

  在定义数组时,可以对数组进行初始化,即给其赋予初值,这可用以下的一些方法实现:

  1.在定义数组时对数组的全部元素赋予初值:

  例:int a[5]={1,2,3,4,5};

  2.只对数组的部分元素初始化;

  例:int  a[5]={1,2};

  上面定义的a数组共有5个元素,但只对前两个赋初值,因此a[0]和a[1]的值是1、2,而后面3个元素的值全是0。

  3.在定义数组时对数组元素的全部元素不赋初值,则数组元素值均被初始化为0

  4.可以在定义时不指明数组元素的个数,而根据赋值部分由编译器自动确定

  例:uchar  BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};则相当于定义了一个BitTab[6]这样一个数组。

  5.可以为数组指定存储空间,这个例子中,未指定空间时,将数组定义在内部RAM中,可以用code关键字将数组元素定义在ROM空间中。

  uchar code BitTab[]={0x7F,0xBF,0xDF,0xEF,0xF7,0xFB};

  用这两种定义分别编译,可以看出使用了code关键字后系统占用的RAM数减少了,这种方式用于编程中不需要改变内容的场合,如显示数码管的字形码等是很合适的。

  6.C语言并不对越界使用数组进行检测,例如上例中数组的长度是6,其元素应该是从BitTab[0]~BitTab[5],但是如果你在程序中写上BitTab[6],编译器并不会认为这有语法错误,也不会给出警告(其他语言如BASCI等则有严格的规定,这种情况将视为语法错误),因此,编程者必须自己小心确认这是否是你需要的结果。

  程序分析:程序中将定时器T1用作数码管显示,通过interrupt 3关键字定义函数Timer1()为定时器1中断服务程序,在这个中断服务程序中,使用

  TH1=(65536-3000)/256;

  TL1=(65536-3000)%256;

  来重置定时器初值,这其中3000即为定时周期,这样的写法可以直观地看到定时周期数,是常用的一种写法。其余程序段分别完成取位码以选择数码管、从显示缓冲区获得待显示数值、根据该数值取段码以点亮相应笔段等任务。其中使用了一个计数器,该计数器的值从0~5对应第1到第6位的数码管。

  主程序的第一部分是做一些初始化的操作,设置定时器工作模式、开启定时器T1、开启计数器T0、开启T1中断及总中断,随后进入主循环,主循环首先用unsigned int型变量tmp取出T0中的数值,这里使用了“tmp=TL0|(TH0<<8);”这样的形式,这相当于tmp=TH0*256+TL0,但比之于后一种形式,该方式可以得到更高的效,其后就是将tmp值不断地除10取整,这样将int型数据的各位分离并送入相应的显示缓冲区。

关键字:单片机  计数器  C语言练习 引用地址:单片机计数器C语言练习

上一篇:基于单片机多中断处理技术的应用与研究
下一篇:电能计量IC配合闪存单片机实现灵活创新的电表设计

推荐阅读最新更新时间:2024-03-16 13:18

单片机测量三相电网功率因数角的接口电路
  为了测量时间r,又为使测量的φ角的精度不受电网频率(或周期T)的影响,采用图所示的接口电路。      由变压器TR取得的UCA线电压信号和由电流互感器取得的线电流iB信号均由检查器转换成相应的方波信号。电压方波信号经G1门反相后,作为测量T/2脉宽的门控脉冲加至G3门输入端,由“或非”门G2得到UCA与iB同时为负的正极性方波脉冲,作为测量时间r的门控脉冲加至G4门输入端。计数脉冲是用8031的ALE脉冲四分频后获得的。因ALE脉冲频率在8031执行非MOVX类指令时是稳定的,且为1/6×晶振频率。因而可用8031内部定时器/计数器T0和Tl对G3与G4门输出脉冲进行计数。上述各点的波形及对应关系已经表示于图1中。     
[单片机]
用<font color='red'>单片机</font>测量三相电网功率因数角的接口电路
51单片机学习:ADC模数转换实验--光敏电阻AD采集
实验名称:ADC模数转换实验--光敏电阻AD采集 接线说明: 实验现象:下载程序后,数码管上显示AD模块采集光敏电阻的AD值 注意事项: ***************************************************************************************/ #include public.h #include smg.h #include xpt2046.h /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数
[单片机]
NXP:微控制器在边缘人工智能中扮演着越来越重要的角色
就在几年前,人们还认为机器学习(ML)甚至深度学习(DL)只能在高端硬件上执行,在边缘侧需要通过网关、边缘服务器或数据中心执行训练和推理,这在当时是一个主流观念,因为在云和边缘之间研究如何分配计算资源还处于早期阶段。但由于工业界和学术界的深入研究和开发努力,这种情况已经发生了巨大的变化。 如今,最新的微控制器(其中一些带有嵌入式ML加速器)可以将ML带到边缘设备中,性能也很强大,已经可以达到数TOPS了。 这些设备不仅可以执行ML,而且还可以以低成本、低功耗、仅在绝对必要时才连接到云端的特性。简言之,集成了ML加速器的微控制器代表了下一步,将计算应用到麦克风、摄像头和监控环境条件的传感器上,这些传感器产生的数据将在模块中就
[单片机]
NXP:<font color='red'>微控制器</font>在边缘人工智能中扮演着越来越重要的角色
基于AVR单片机的数控移相信号发生器设计
1 前 言 移相信号发生器属于信号源的一个重要组成部分,但传统的模拟移相有许多不足,如移相输出波形易受输入波形的影响,移相角度与负载的大小和性质有关,移相精度不高,分辨率较低等。而且,传统的模拟移相不能实现任意波形的移相,这主要是因为传统的模拟移相由移相电路的幅相特性所决定,对于方波、三角波、锯齿波等非正弦信号各次谐波的相移、幅值衰减不一致,从而导致输出波形发生畸变。目前利用DDS技术产生信号源的方法得到了广泛的应用,但是专用DDS芯片由于采用特定的集成工艺,内部数字信号抖动很小,不可以输出高质量的模拟信号。随着现代电子技术的发展,特别是随单片机和可编程技术的发展而兴起的数字移相技术却很好地解决了这一问题。在众多的单片机之中,AV
[单片机]
基于AVR<font color='red'>单片机</font>的数控移相信号发生器设计
PIC单片机是一个小的计算机
PIC单片机有计算功能和记忆内存像CPU并由软件控制允行。然而,处理能力—存储器容量却很有限,这取决于PIC的类型。但是它们的最高操纵频率大约都在20MHz左右,存储器容量用做写程序的大约1K—4K字节。 时钟频率与扫描程序的时间和执行程序指令的时间有关系。但不能仅以时钟频率来判定程序处理能力,它还随处理装置的体系结构改变(1*)。假如是同样的体系结构,时钟频率较高的处理能力会较强。 这里用字来解释程序容量。用一个指令(2*)表示一个字。通常用字节(3*)来表示存储器(4*)容量。一个字节有8位,每位由1或0组成。 PIC16F84A单片机 的指令由14位构成。当把1K个子转换成位为:1 x 1,024 x 14 = 14,33
[单片机]
医用低成本自动示波法血压测量仪解决方案
  示波法血压测量仪必须能够采用3V电池工作,而且需要提供足够的内存和处理能力,以运行血压算法,因为这些血压计是面向消费市场的,低成本很重要。采用哪些器件能够达到低成本要求?本文将给你这方面的指导。   利用自动示波法血压测量仪可以在办公室或家庭测量血压。腕部血压低于心脏收缩压,当血液开始流经动脉时,动脉管壁开始振动,这些振动引起腕部血压的微小变化或波动。这个血压波动显示的是心脏收缩压。心脏舒张压测量涉及复杂的、通常是具有自主知识产权的算法,该算法可以确定血压波动幅度的斜率变化。示波法血压测量仪必须能够采用3V电池工作,而且需要提供足够的内存和处理能力,以运行血压算法,因为这些血压计是面向消费市场的,低成本很重要。   解决方
[医疗电子]
医用低成本自动示波法血压测量仪解决方案
LINUX下使用简单的中断程序使单片机精确计时
在程序开始时需要对定时器及中断寄存器做初始化设置: 对TMOD——定时器/计数器工作方式寄存器赋值,以确定T0和T1的工作方式。 计算初值,并将初值写入TH0,TL0或TH1,TL1。 对IE——中断允许寄存器的EA和ET0或ET1赋值,打开T0或T1。 使TR0或TR1置位,启动定时器/计数器定时或计数。 详细说明如下 一、TMOD是工作方式寄存器,D0~D3是定时器T0,D4~D7是定时器T1。D0~D3含义如下: D0:M0。 D1:M1——M0和M1的四种组合方式决定了定时器/计数器的4种工作方式。当M1=0,M0=1时是16位定时器/计数器。 D2:C/T——定时器模式和计时器模式选择位,1为计数器模式,
[单片机]
单片机上实现动态加载功能
本项目是一个在单片机(如:STM32)上实现动态加载功能的函数库,与Windows中的dll,Linux中的so类似,可以将代码动态地从其他的存储介质,动态加载到RAM中。 软件架构 本项目文件夹有三个,其中common存储了用于生成可重定位的.axf文件的工程与动态加载器工程交互用的函数,src提供动态加载器的源码,rel_axf_project_template提供了一个简单的可重定位的.axf文件的工程示例,example.c是一个简单的使用示例,所有文件的主要功能如下: /common/dl_extern_lib.h 描述了app程序用于调用host程序的函数向量表的基地址,以及相关的一些宏定义 /common/dl_
[单片机]
热门资源推荐
热门放大器推荐
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

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

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