2017-04-25 12:05:22 DoctorLDQ 阅读数 2705
  • 单片机到底是个什么东西-1.2.第1季第2部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第2个课程,用通俗易懂的语言讲了很多和单片机有关的技术概念,如CPU、ROM、RAM、外设、电路板、软件硬件工作的差别等。目的是希望大家在轻松愉悦的氛围中对单片机加深认识。

    3034 人正在学习 去看看 朱有鹏
最近学习到单片机,老师要求我们用单片机实现一个秒表。在求助了各种网上的资源后发现还是一脸mb,所以决定自己动手,丰衣足食。

以下就是具体的代码实现及运行结果。 

#include "reg52.h" 
#include <stdio.h>  

typedef unsigned int u16;  
typedef unsigned char u8;

sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;


sbit k2=P3^2; 


u8 code smgduan[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
     0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值

u8 code num[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

u8 ssec,sec,flag=0,wan=0;
u8  DisplayData[4];

u8 val0;   //最高位
u8 val1; //次高位
u8 val2;
u8 val3;



void delay(u16 i)
{
 while(i--); 
}


void Timer0Init()
{
 TMOD|=0X01;

 TH0=0Xd8; 
 TL0=0Xf0; 
 ET0=1;
 EA=1;
 TR0=0;   
}



void DigDisplay()
{
 u8 i;
 for(i=0;i<4;i++)
 {
   
  switch(i) 
  {
   case(0):
    LSA=1;LSB=1;LSC=1; break;//显示第0位
   case(1):
    LSA=0;LSB=1;LSC=1; break;//显示第1位
   case(2):
    LSA=1;LSB=0;LSC=1; break;//显示第2位
   case(3):
    LSA=0;LSB=0;LSC=1; break;//显示第3位
 
  }  
  P0=DisplayData[i];
  delay(100);
  P0=0x00;  
  
 }
}


void datapros()
{
 
 DisplayData[0]=smgduan[ssec%10];

 

 DisplayData[1]=smgduan[ssec%100/10];


 DisplayData[2]=smgduan[sec%10]+0x80;

 DisplayData[3]=smgduan[sec/10];
// val=smgduan[sec/10];
}
void trans(u8 x)
{
 u8 i;
 for(i=0;i<10;i++)
 {
  if(x==i)
  {
   SBUF=num[i];
  }
 }
 while(!TI);
 TI=0;  


}

void send()
{
 
 TI=0;
 if(TR0=1)
 {
  
  trans(val0);
  trans(val1);
   

  trans(val2);
  trans(val3);
  SBUF=0x0a;
  while(!TI);
  TI=0;
  
 }


}



void Timer0() interrupt 1
{
   u8 i;
 TH0=0Xd8; 
 TL0=0Xf0; 
 ssec++;
 i++;

 
 val2=i%100/10;
 val3=i%10;
  
 if(ssec==100) 
 {
  
  ssec=0;
  
  sec++;
  val0=sec/10;
  val1=sec%10;
  send();
  
  if(sec>=60)
  {
   sec=0;
  
  } 
  
 }
 
}



void keypros()
{
 if(k2==0)   
 { 
  delay(1000); 
  flag++;
  if(k2==0) 
  {
  // TR0=1;
   while(!k2);
   switch(flag)
   {
    case 1:TR0=1;break;
    case 2:TR0=0;break;
    case 3:ssec=0;sec=0;TR0=0;flag=0;break;
   }
   
  } 
 
 }

}
void UsartInit()
{
 SCON=0x50;  // SCON: 模式 1, 8-bit UART, 使能接收 
    TMOD |= 0x20;       // TMOD: timer 1, mode 2, 8-bit 重装
    TH1=0xFD;       // TH1:  重装值 9600 波特率 晶振 11.0592MHz 
 TL1=0xFD;

    TR1=1;          // TR1:  timer 1 打开    
}




void main()

 Timer0Init();
 UsartInit();
  


 
 while(1)
 {

  datapros();
  keypros(); 
    
  DigDisplay();
 
  
 }
 
}






   
2016-10-24 22:56:32 mengdewangzi 阅读数 589
  • 单片机到底是个什么东西-1.2.第1季第2部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第2个课程,用通俗易懂的语言讲了很多和单片机有关的技术概念,如CPU、ROM、RAM、外设、电路板、软件硬件工作的差别等。目的是希望大家在轻松愉悦的氛围中对单片机加深认识。

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

                 用单片机控制数码管实现秒表功能

要求:秒表跑到10s时停止,蜂鸣器响一声,秒表精度为0.01s


代码张贴:

#include <reg52.h>


#define SEGPORT P0

sbit dula=P1^1;

sbit wela=P1^0;

sbit deep = P1^2;

  

unsigned char code wei_table[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};

unsigned char  tempdata[4];

unsigned char  p_table[10] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

 

unsigned char miao,m_miao;

void display_seg()

{

static unsigned char i = 0; 

  

SEGPORT=0xff;

wela = 1;

wela = 0;

    

SEGPORT =0x0;

dula = 1;

dula = 0;

 

    SEGPORT=wei_table[i];

wela = 1;

wela = 0;

 

SEGPORT = tempdata[i];  

dula = 1;

dula = 0;

i++;

if(4 == i)

{

i = 0;

}

}

 

void timer0_init()

{

EA = 1;

TMOD = 0x01;

TH0 = (65536 - 3000)/256;

TL0 = (65536 - 3000)%256;

ET0 = 1;

TR0 = 1;    

}

void timer1_init()

{

EA = 1;

TMOD |= 0x10;

TH1 = (65536 - 10000)/256;

TL1 = (65536 - 10000)%256;

ET1 = 1;

TR1 = 1;     

}    

void  timer0_isr() interrupt 1

{

TH0 = (65536 - 3000)/256;

TL0 = (65536 - 3000)%256; 

display_seg(); 

}

void  timer1_isr() interrupt 3

{

unsigned char i,j;

TH1 = (65536 - 10000)/256;

TL1 = (65536 - 10000)%256; 

m_miao++;

if(100 == m_miao)

{

m_miao = 0;

miao++;

if(10 == miao)

{

ET1 = 0;

tempdata[0] = table[miao/10];

tempdata[1] = p_table[miao%10];

tempdata[2] = table[m_miao/10];

tempdata[3] = table[m_miao%10];

for(j=0;j<200;j++)

{

i=50;

deep = ~deep;

while(i--);

}

}

}

 

tempdata[0] = table[miao/10];

tempdata[1] = p_table[miao%10];

tempdata[2] = table[m_miao/10];

tempdata[3] = table[m_miao%10];

}

 

void main()

{

   timer0_init();

   timer1_init();

   while(1);

}


2019-12-15 20:20:06 qq_41948771 阅读数 412
  • 单片机到底是个什么东西-1.2.第1季第2部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第2个课程,用通俗易懂的语言讲了很多和单片机有关的技术概念,如CPU、ROM、RAM、外设、电路板、软件硬件工作的差别等。目的是希望大家在轻松愉悦的氛围中对单片机加深认识。

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

单片机实现秒表计数器

最近博主在学习单片机的课程,这快到期末考试了,老师让做个简单的课设,我看了看老师给的课题,感觉这个比较容易实现,今天下午花了两个小时左右的时间,把仿真程序电路图画好了,现在分享大家,希望大家批评改正。
实验器材:**单片机、按钮、电阻、PNP型三极管、有源蜂鸣器、共阴极数码管

实现的功能

  1. 通过按键实现倒计时

  2. 逐秒倒计时

  3. 使用4为一体数码管显示时间

  4. 时间到发出警报声,或者在数码管闪烁显示0000

仿真电路图:推荐使用网络标号连接电路图,这样作图较为专业,适合以后的大点的作图方式。网络标号相同的即为相连接的,图貌似不是很清晰,如果看不清,评论区留言,我发给你proteus仿真文件。
在这里插入图片描述

程序代码:148行程序,不是太长

//尽本人最大的努力,将程序中的每条语句较为详细的讲解
#include <reg51.h>
#include <stdio.h>
#define uint unsigned int
#define uchar unsigned char
uchar count=0,minute=0,second=3,flag=0,stop=0;
uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极
uchar disbuf[4]={0};//位选定义一个四位的数组,循环扫描显示相应的内容
sbit buzzer=P1^0;//定义单片机的相应引脚
sbit P1_1=P1^1;
sbit P1_2=P1^2;

void delay_ms(uint x) //延时消抖函数
{uint t; 
 while(x--) for(t = 0; t < 120; t++);
}

void display()//模块化书写函数,进行相应的调用,实现模块化编程
{
	uchar i,j;
	uchar sel;
	disbuf[0]=second%10; //disbuf[]每一个元素赋值,对秒赋值
	disbuf[1]=second/10;
	disbuf[2]=minute%10;//对分钟赋值
	disbuf[3]=minute/10;
	P2=0XFF;     //P2口接数码管的位选端,选择哪个数码管工作  共阴极数码管,位选0时有效  先置FF,使为选段为高电平,数码管不工作
	sel=0x01;//定义一个扫描的位选端
	for(i=0;i<4;i++)
		{
			j=disbuf[i];  //扫描依次显示四个数码管  上面的赋值已经将disbuf数值更改,也就是1~9
			P0=table[j]; //将字形码发送到P0端口,显示位的数据
			P2=(sel^0xff); // ^异或相异为1,保证每次都有一个数码管点亮
			delay_ms(1); // 延时后,防止程序运行太快,跑飞
			P2=0XFF;
			sel=sel<<1;  //  左移运算  0x01左移,1将依次在四位上循环
		}
}

void modify_time()//更改计时器时间的函数,修改初始定时时间
{
	if(flag==0)//修改秒
		{
			second++;
			if(second==60)//秒的最大为60,然后会发生进位
				{
					second=0;
					disbuf[0]=0;
					disbuf[1]=0;
				}
		}
	else//修改分钟
		{
			minute++;
			if(minute==60)//分钟最大为60,到60以后会发生进位
				{
					minute=0;
					disbuf[2]=0;
					disbuf[3]=0;
				}
		}

}
void main(void)//主函数
 { 
  TMOD=0x01;//定时器T0,工作方式1,为16位定时器
  TH0=(65536-50000)/256;//高8位赋值
  TL0=(65536-50000)%256;//低8位赋值
  TR0=0;//默认情况下,定时器不工作,在外部的触发情况下,定时器,工作,开始减1运算
  ET0=1;//打开定时器T0的中断
  IT0=1;//设置外部中断0的触发方式
  EX0=1;//打开外部中断的中断
  IT1=1;//设置外部中断0触发方式
  EX1=1;//打开外部中断1中断
  EA=1;//总中断
  while(1)
	{
		if(stop==1)//当计时倒计时完成以后,屏幕闪烁显示
			{
				while(1)
					{
						P2=~P2;
						delay_ms(150);
					}
			}
		else
			display();//调用显示函数,依次减一
		if(!P1_1)//判断更改时间按键是否按键  进行相应的消抖
       {
		   while(!P1_1)  
           delay_ms(10);  
           if(P1_1)
           modify_time();//调用调日期时间的函数
		}	
	}
 }

void inter1() interrupt 1//定时器T0的中断
{
	count++;
	TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
	if(count==20)//50ms   20次即为1s
		{	
			count=0;
			second--;
			if(second==0)//该处的程序结构应该仔细看下
				{
					if(minute!=0)//防止minute最后为0的时候,还执行minute--,使程序出错。
						{
							minute--;
							second=60;
							second--;
							if(second==0)
								{	
									if(minute==0)
										{
											second=0;
											minute=0;
											TR0=0;
											count=0;
											buzzer=0;
											stop=1;

										}
								}
						}
					else
						{
							second=0;
							minute=0;
							TR0=0;
							count=0;
							buzzer=0;
							stop=1;
						}
				}
		}
}
	
void inter0() interrupt 0//外部中断0
{
	flag=~flag;//flag参数的作用,是修改定时时间的时,确定是分钟位还是小时位。
	
}

void inter2() interrupt 2//外部中断1
{
	TR0=~TR0;//按键3,奇数次按下,定时器开始工作,偶数次关闭。
}

所用器材的介绍
PNP型三极管:判断的依据,可根据,箭头方向来判断,箭头向外NPN,箭头向内PNP
蜂鸣器:选择无源蜂鸣器 并且将电压设置为2V,如果不这样设置,可能蜂鸣器不发声。

2015-11-19 16:11:42 cjdsn 阅读数 1550
  • 单片机到底是个什么东西-1.2.第1季第2部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第2个课程,用通俗易懂的语言讲了很多和单片机有关的技术概念,如CPU、ROM、RAM、外设、电路板、软件硬件工作的差别等。目的是希望大家在轻松愉悦的氛围中对单片机加深认识。

    3034 人正在学习 去看看 朱有鹏
/* 
write by cjdsn
 时间计算
1/22.1184=0.0000005425
1/0.5425=1843317
1843317/40=46083
//我的是阳极显示,0开1关
*/


#include<reg52.h>  
unsigned char code Tab[12]=


{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xff}; 
 //数码管显示0~9的段码表
unsigned char int_time;        //记录中断次数
unsigned char second;        //储存秒
unsigned char t,h;
sbit pd=P2^0;
sbit pc=P2^1;
sbit pb=P2^2;
sbit pa=P2^3;
sbit p27=P2^7;
/******************************************************************


*****
函数功能:快速动态扫描延时,延时约0.6毫秒
*******************************************************************


*****/
void delay(void)
{
  unsigned char i;
  for(i=0;i<200;i++)
        ;
}
/******************************************************************


*****
函数功能:显示秒
入口参数:k
出口参数:无
*******************************************************************


*****/
 void DisplaySecond(unsigned char k)
{
   pb=0;        //P2.1引脚输出低电平
P0=Tab[k/10];          //显示十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
   pb=1;
   pa=0;      //P2.0引脚输出低电平
P0=Tab[k%10];         //显示个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
pd=0;
P0=Tab[t/10];  //分 十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pd=1;
pc=0;
P0=Tab[t%10];  //分 个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
///////////////////////////////////
pc=0;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
//====================================//
/*
P2=0xff;     //关闭所有数码管
P0=0xff;        //显示个位
*/
//====================================//
}


///////////////////////////////////////////////////////////////////


/////////////////


 void Displayh()
{
   pb=0;        //P2.1引脚输出低电平
P0=Tab[t/10];          //显示十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
   pb=1;
   pa=0;      //P2.0引脚输出低电平
P0=Tab[t%10];         //显示个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
pd=0;
P0=Tab[h/10];  //分 十位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pd=1;
pc=0;
P0=Tab[h%10];  //分 个位
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
///////////////////////////////////
pc=0;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
pc=1;
}


////////////////////////////////  显示小数点
displayms(void)
 {
P2=1;
p27=1;
pa=0;
pb=1;
P0=Tab[10];
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
delay();
pa=1;
 }


//==========================================================//


 
void main(void)     
   {
   P2=1;
   p27=1;
     TMOD=0x01;                 //使用定时器T0
    TH0=(-46083)/256;    //将定时器计时时间设定为


46083×1.085微秒
//=50000微秒=50毫秒
TL0=(-46083)%256;
EA=1;                 
      ET0=1;                 
          TR0=1;                   
  int_time=0;     //中断次数初始化
second=0;   //秒初始化
t=59;

while(1)
{       if(h<=0){
      DisplaySecond(second);//调用秒的显示子程序
  }
else Displayh();
}
 }  
//********************************************************
//函数功能:定时器T0的中断服务程序
//*******************************************************
  void interserve(void ) interrupt 1 using 1  
  {
    TR0=0;    //关闭定时器T0
    int_time ++;        //每来一次中断,中断次数int_time自加1


断次数清0  
if(int_time==40)   //够20次中断,即1秒钟进行一次检测结果采样
 {
        int_time=0;    //
second++;    //秒加1
if(h>0){displayms();}
if(second==60)
   {  second =0; //秒等于60就返回0
 t++;}
if(t==60){t=0;h++;
if(h==24)h=0;}
 }      
  TH0=(-46083)/256;   //重新给计数器T0赋初值
TL0=(-46083)%256;
TR0=1;     //启动定时器T0
 }  
2016-09-16 21:40:17 newcong0123 阅读数 881
  • 单片机到底是个什么东西-1.2.第1季第2部分

    本课程是《朱有鹏老师单片机完全学习系列课程》第1季第2个课程,用通俗易懂的语言讲了很多和单片机有关的技术概念,如CPU、ROM、RAM、外设、电路板、软件硬件工作的差别等。目的是希望大家在轻松愉悦的氛围中对单片机加深认识。

    3034 人正在学习 去看看 朱有鹏
#include <reg52.h>
#include "./delay/delay.h"

#define TIMEPORT P0

sbit bit_select = P2^0;
sbit seg_select = P2^1;
sbit key1 = P2^2;
sbit key2 = P2^3;

code unsigned char timedata[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
code unsigned char bitdata[8] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned disdata[8];

unsigned char ms = 0;
unsigned char sec = 0;
unsigned char min = 0;

void timer0_init();
void timer1_init();
void display();
void change_time();

void main()
{
    change_time();    //修改时间显示值
    timer0_init();
	timer1_init();
	
	while(1)
	{
	    if(0 == key1)            //key1按下
		{
		    delay_ms(10);
			
			if(0 == key1)        //key1确实按下
			{
			    while(!key1);    //key1抬起
				delay_ms(10);
				while(!key1);    //key1确实抬起
				TR0 = ~TR0;      //计时器取反
			}
		}
		
		if(0 == key2)            //key2按下
		{
		    delay_ms(10);
			
			if(0 == key2)        //key2确实按下
			{
			    while(!key2);    //key2抬起
				delay_ms(10);
				while(!key2);    //key2确实抬起
				TR0 = 0;
				ms = 0;
				sec = 0;
				min = 0;
                change_time();   //修改时间显示值				
			}
		}
	}
}

/*
===================
功能:初始化中断0
===================
*/
void timer0_init()
{
    EA = 1;
	TMOD |= 0x01;
	TH0 = (65536 - 1000) / 256;
	TL0 = (65536 - 1000) % 256;
	ET0 = 1;
	TR0 = 0;
}

/*
===================
功能:初始化中断1
===================
*/
void timer1_init()
{
    EA = 1;
	TMOD |= 0x10;
	TH1 = (65536 - 2000) / 256;
	TL1 = (65536 - 2000) % 256;
	ET1 = 1;
	TR1 = 1;
}

/*
==========================
功能:中断1服务函数,显示
==========================
*/
void timer1_isr() interrupt 3
{
	TH1 = (65536 - 2000) / 256;
	TL1 = (65536 - 2000) % 256;

    display();    
}

/*
==========================
功能:中断0服务函数,计数
==========================
*/
void timer0_isr() interrupt 1
{
    static unsigned char i = 0;
	
	TH0 = (65536 - 1000) / 256;
	TL0 = (65536 - 1000) % 256;

    i++;
	
    if(10 == i)
	{
	    i = 0;
        ms++;

        if(100 == ms)
        {
	        ms = 0;
		    sec++;
		
            if(60 == sec)
		    {
		        sec = 0;
			    min++;
			
			    if(60 == min)
			    {
			        min = 0;
			    }
		    }
		}
	}

    change_time();    //修改显示时间
}

/*
======================
功能:修改时间显示值
======================
*/
void change_time()
{
    disdata[0] = timedata[min / 10];
    disdata[1] = timedata[min % 10];
    disdata[2] = 0x40;
    disdata[3] = timedata[sec / 10];
    disdata[4] = timedata[sec % 10];
    disdata[5] = 0x40;
    disdata[6] = timedata[ms / 10];
    disdata[7] = timedata[ms % 10];  
}

/*
==========================
功能:动态扫描,显示数据
==========================
*/
void display()
{
    static unsigned char i = 0;
	
    TIMEPORT = 0x00;            //清空数据,防止重影
    seg_select = 1;
    seg_select = 0;

    TIMEPORT = 0xff;            //清空数据,防止重影
    bit_select = 1;
    bit_select = 0;

    TIMEPORT = disdata[i];      //取出显示值
    seg_select = 1;
    seg_select = 0;

    TIMEPORT = bitdata[i];      //取出位码
    bit_select = 1;
    bit_select = 0;	
	
	i++;
	if(8 == i)
	{
	    i = 0;
	}
}



51 单片机 秒表

阅读数 2081

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