月亮雨小组 YLY Studio

51单片机电波钟源程序

 代码当时只是简单的调出了校时功能,没加奇偶校验。

要修改的地方还不少。

#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint  unsigned int

sbit BPC=P3^2;
bit BPC_add;
uchar BPC_temp,Dat_add,Dat_su,Dat_num;
uchar data BPC_dat[3][19];
bit Get_time,As_time;
uchar Time;
uchar data Times[6];

#include"LCD1602.h"

void Init_T(void)
{
  EA=1;     //总中断允许
  IT0=1;    //IT0=1时下降沿触发,IT0=0时低电平触发,
  EX0=1;    //允许中断0
  TMOD=0x01;  //16计数器
  TH0=(65536-10000)/256;//装初值
  TL0=(65536-10000)%256;
  ET0=1;
  TR0=1;
}

void main(void)
{
  Init_T();//中断初始化
  Init_LCD();//LCD初始化
  while(1)
     {
       if(As_time)//帧结束,两帧对比
         {
           As_time=0;//清零对比标志位
           if(//对比相邻接收到的三帧数据
               (BPC_dat[0][1]==BPC_dat[1][1])&&(BPC_dat[0][1]==BPC_dat[2][1])
               &&(BPC_dat[0][2]==BPC_dat[1][2])&&(BPC_dat[0][2]==BPC_dat[2][2])
               &&(BPC_dat[0][3]==BPC_dat[1][3])&&(BPC_dat[0][3]==BPC_dat[2][3])
               &&(BPC_dat[0][4]==BPC_dat[1][4])&&(BPC_dat[0][4]==BPC_dat[2][4])
               &&(BPC_dat[0][5]==BPC_dat[1][5])&&(BPC_dat[0][5]==BPC_dat[2][5])
               &&(BPC_dat[0][6]==BPC_dat[1][6])&&(BPC_dat[0][6]==BPC_dat[2][6])
               &&(BPC_dat[0][7]==BPC_dat[1][7])&&(BPC_dat[0][7]==BPC_dat[2][7])
               &&(BPC_dat[0][8]==BPC_dat[1][8])&&(BPC_dat[0][8]==BPC_dat[2][8])
               &&(BPC_dat[0][10]==BPC_dat[1][10])&&(BPC_dat[0][10]==BPC_dat[2][10])
               &&(BPC_dat[0][11]==BPC_dat[1][11])&&(BPC_dat[0][11]==BPC_dat[2][11])
               &&(BPC_dat[0][12]==BPC_dat[1][12])&&(BPC_dat[0][12]==BPC_dat[2][12])
               &&(BPC_dat[0][13]==BPC_dat[1][13])&&(BPC_dat[0][13]==BPC_dat[2][13])
               &&(BPC_dat[0][14]==BPC_dat[1][14])&&(BPC_dat[0][14]==BPC_dat[2][14])
               &&(BPC_dat[0][15]==BPC_dat[1][15])&&(BPC_dat[0][15]==BPC_dat[2][15])
               &&(BPC_dat[0][16]==BPC_dat[1][16])&&(BPC_dat[0][16]==BPC_dat[2][16])
               &&(BPC_dat[0][17]==BPC_dat[1][17])&&(BPC_dat[0][17]==BPC_dat[2][17])
             )Get_time=1;//接收成功,较正时钟标志位
         }
       if(Get_time)//判断是否要较正时钟
         {
           Get_time=0;//清零时钟较正标志位
           Times[0]=((BPC_dat[0][15]*16)+(BPC_dat[0][16]*4)+(BPC_dat[0][17]));//年
           Times[1]=((BPC_dat[0][13]*4)+(BPC_dat[0][14]));//月
           Times[2]=((BPC_dat[0][10]*16)+(BPC_dat[0][11]*4)+(BPC_dat[0][12]));//日
           Times[3]=((BPC_dat[0][2]*4)+(BPC_dat[0][3]));//时
           Times[4]=((BPC_dat[0][4]*16)+(BPC_dat[0][5]*4)+(BPC_dat[0][6])+1);//分
           if(Times[4]>59){Times[4]=0;Times[3]++;if(Times[3]>12)Times[3]=0;}
           Times[5]=0;//秒
         }
       display();//液晶显示
     }
}

void Time_EX0(void)interrupt 0
{
  BPC_add=1;//使能计数标志位置1
  Dat_add=0;//起始帧判断清零
}

void Time_T0(void)interrupt 1//中断计数器,每秒100
{
  TH0=(65536-10000)/256;
  TL0=(65536-10000)%256;
  Time++;//时间计数
  if(Time>100)
    {
      Time=0;
      Times[5]++;
      if(Times[5]>59)
        {
          Times[5]=0;
          Times[4]++;
          if(Times[4]>59)
            {
              Times[4]=0;
              Times[3]++;
              if(Times[3]>12)Times[3]=0;
            }
        }
    }
  Dat_add++;//起始帧计数
  if(Dat_add>150)Dat_num=0;//判断帧起始,在一秒内没清零Dat_add就大于100
  if(BPC_add)//计数标志,能计数
    {
      if(!BPC)BPC_temp++;//脉宽计数加加
      else
        {
          BPC_add=0;//一个脉冲结束,清零计数标志
          if((BPC_temp>5)&&(BPC_temp<15))BPC_dat[Dat_su][Dat_num]=0;//0.1秒   按脉宽换算成4进制
          else if((BPC_temp>15)&&(BPC_temp<25))BPC_dat[Dat_su][Dat_num]=1;//0.2秒
          else if((BPC_temp>25)&&(BPC_temp<35))BPC_dat[Dat_su][Dat_num]=2;//0.3秒
          else if((BPC_temp>35)&&(BPC_temp<45))BPC_dat[Dat_su][Dat_num]=3;//0.4秒
          else Dat_num=0;
          
          Dat_num++;//位计数
          if(Dat_num>18)//位满,帧结束
            {
              Dat_num=0;//位重计
              As_time=1;//帧接收完成,两帧对比标志位置1
              Dat_su++;if(Dat_su>2)Dat_su=0;//帧记录,换数组再记
            }
          BPC_temp=0;//脉宽计数器清零
        }
    }
}



#ifndef __LCD1602_H_
#define __LCD1602_H_

/*uchar code number[10]={0x30,0x31,0x32,
0x33,0x34,0x35,0x36,0x37,0x38,0x39};*/
                                
#define DataPort P0
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;

//LCD专用延时
void delay_LCD(uint k)
{
  uchar i;
  while(k--)
     for(i=0;i<121;i++);
}

//写指令
void Write_com(uchar com)
{
  RS=0;
  RW=0;
  DataPort=com;
  EN=1;
  delay_LCD(2);
  EN=0;
}

//写数据
void Write_dat(uchar dat)
{
  RS=1;
  RW=0;
  DataPort=dat;
  EN=1;
  delay_LCD(2);
  EN=0;                      
}

//初始化
void Init_LCD(void)
{
  DataPort=0x00;     //IO口初始化
  RS=1;
  RW=1;
  EN=1;
  Write_com(0x38);     //8位数据口,两行显示
  Write_com(0x06);     //完成一个字符码传送后,光标右移,AC自动加1
  Write_com(0x01);     //清屏
  Write_com(0x0c);     //开显示
}
//Write_com(0x80);//第一行起始地址
//Write_com(0xc0);//第二行起始地址

void display(void)
{
  Write_com(0x80);
  Write_dat('Y');
  Write_dat('e');
  Write_dat('a');
  Write_dat('r');
  Write_dat(':');
  Write_dat('2');
  Write_dat('0');
  Write_dat(0x30+Times[0]/10);
  Write_dat(0x30+Times[0]%10);
  Write_dat('-');
  Write_dat(0x30+Times[1]/10);
  Write_dat(0x30+Times[1]%10);
  Write_dat('-');
  Write_dat(0x30+Times[2]/10);
  Write_dat(0x30+Times[2]%10);
    
  Write_com(0xc0);
  Write_dat('T');
  Write_dat('i');
  Write_dat('m');
  Write_dat('e');
  Write_dat(':');
  Write_dat(0x30+Times[3]/10);
  Write_dat(0x30+Times[3]%10);
  Write_dat('-');
  Write_dat(0x30+Times[4]/10);
  Write_dat(0x30+Times[4]%10);
  Write_dat('-');
  Write_dat(0x30+Times[5]/10);
  Write_dat(0x30+Times[5]%10);
}

#endif



这都是在学校时写的,现在看了,自己都看不下去了。

给想要的朋友个参考吧。

作者:mysy 分类:软件与编程 浏览:54 评论:0

单片机控制2004A液晶屏之模块化编程

学习单片机已经有一段时间了,但是很多程序都缺少模块化的思想,之前以为只要把单个的功能封装在一个函数里面就是模块化,经过了十多天实习,才真正开始有了模块化的编程思想,这里将我编写的STC12C5A60S2单片机控制2004液晶屏的程序共享一下,一是希望没有模块化编程思想的后来者看看,二是希望前辈们给予斧正。

(补充:以下代码只需要修改.h文件中含有 “选择” 字样的部分,就可以达到复用的效果,只需要注意中文注释部分)      

作者:mysy 分类:软件与编程 浏览:58 评论:0

单片机c语言教程

 

c语言是很好用的结构化语言,80年代后,c也能用在单片机上了。本站为了方便大家学习制作了一个单片机c语言教程,如果你是新手先看下下面的c51介绍吧,过去长期困扰人们的所谓“高级语言产生代码太长,运行速度太慢,运行效率不高,所以不适合单片机使用”keil公司出品的单片机c语言集成开发环境成功的解决了这个难题,使得单片机c语言的效率大大的提高,而且在关键部位还能嵌入汇编语言代码,从而挖掘程序的最高潜力。目前,8051上的C语言的代码长度,已经做到了汇编水平的1.2~1.5倍。4K字节以上的程度,C语言的优势更能得到发挥。至于运行速度的问题,只要有好的仿真器,找出关键的代码,再进一步做一下人工优化,就可很容易达到美满。单片机c语言是高效的单片机开发语言,本站提供的单片机c语言教程共17课时,由浅入深,看完了这些教程你就基本了解了c51,能进行一般的单片机c语言程序设计了,现在让我们开始学习吧

作者:mysy 分类:软件与编程 浏览:36 评论:0

用proteus绘画51单片机最小系统

 

  单片机的最小系统是单片机系统的核心,最小系统都包括电源、晶振、复位电路这三部分组成,怎么用proteus绘画最小系统?接下来一步一步教大家。

作者:mysy 分类:软件与编程 浏览:62 评论:0

解决罗技G930 无线游戏耳机的不定期断线、断开连接的方法

 解决罗技G930 无线游戏耳机的不定期断线、断开连接的方法


g930_100364b_x64.exe


安装完后, 手动在设备列表更新一下G930的驱动(前提是你有装罗技的新版本键盘/鼠标驱动软件)

 


作者:mysy 分类:软件与编程 浏览:177 评论:0

21课:单片机串行口介绍

 

介绍:串行口是单片机与外界进行信息交换的工具。

8051单片机的通信方式有两种:

并行通信:数据的各位同时发送或接收。  串行通信:数据一位一位次序发送或接收。参看下图:

作者:mysy 分类:软件与编程 浏览:41 评论:0

21课:单片机串行口介绍

 

介绍:串行口是单片机与外界进行信息交换的工具。

8051单片机的通信方式有两种:

并行通信:数据的各位同时发送或接收。  串行通信:数据一位一位次序发送或接收。参看下图:

作者:mysy 分类:软件与编程 浏览:36 评论:0

20课:单片机定时/计数器实验

   前面我们做了定时器的实验,现在来看一看计数实验,在工作中计数常常会有两种要求:第一、将计数的值显示出来,第二、计数值到一定程度即中断报警。第一种如各种计数器、里程表,第二种如前面例中讲到的生产线上的计数。先看第一种吧。我们的硬件中是这样连线的:324组成的振荡器连到定时/计数器1的外部管脚T1上面,我们就利用这个来做一个计数实验,要将计数的值显示出来,当然最好用数码管了,可我们还没讲到这一部份,为了避免把问题复杂化,我们用P1口的8个LED来显示计到的数据。

作者:mysy 分类:软件与编程 浏览:44 评论:0

19课:单片机定时器、中断试验

 

   我们在学单片机时我们第一个例程就是灯的闪烁,那是用延时程序做的,现在回想起来,这样做不很恰当,为什么呢?我们的主程序做了灯的闪烁,就不能再干其它的事了,难道单片机只能这样工作吗?当然不是,我们能用定时器来实现灯的闪烁的功能。

例1:查询方式

ORG 0000H

AJMP START

ORG 30H

START:

作者:mysy 分类:软件与编程 浏览:48 评论:0