51单片机矩阵键盘与八位共阴数码管问题求指点

目标是实现根据矩阵键盘输入内容显示对应的数字(0到f),如按下S1->S8会显示0->7八个数字,在上述情况下按下S9后会显示1->8八位数,再按下S10后会显示2->9;按S16清除数码管显示内容;

出现问题:当八位数码管都有数字时按下下一个按键后会覆盖最后一位,但第一位不会被移出显示屏;图片说明图片说明图片说明


//  内容:如计算器输入数据形式相同 从右至左 使用行列扫描方法
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <intrins.h>

#define KeyPort  P2

sbit LATCH = P1^2;   //SER 串行数据
sbit SRCLK= P1^1;    //SCK 串行时钟信号
sbit SER  = P1^0;    //ST 锁存输出信号

unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
                                     0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
unsigned char TempData[10]; //存储显示值的全局变量

void DelayUs2x(unsigned char t);//us级延时函数声明 
void DelayMs(unsigned char t); //ms级延时
void Display(unsigned char FirstBit,unsigned char Num);//数码管显示函数
unsigned char KeyScan(void);//键盘扫描
unsigned char KeyPro(void);
void Init_Timer0(void);//定时器初始化
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{
unsigned char num,i,j;                  
unsigned char temp[8];
Init_Timer0();

while (1)         //主循环
  {


 num=KeyPro();
 if(num!=0xff)
   {
    if(i<8)
      {
       temp[i]=dofly_DuanMa[num];
       for(j=0;j<=i;j++)
          TempData[7-i+j]=temp[j];
       }
    i++;
    if(i==8)//多出一个按键输入为了清屏 原本应该为8
      {
     i=0;
    if(j==500)
    {
        j=0;
        num++;
        if(num==9)
            num=0;
    }
       }

  }
}
/*------------------------------------------------
 uS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编,大致延时
 长度如下 T=tx2+5 uS 
------------------------------------------------*/
void DelayUs2x(unsigned char t)
{   
 while(--t);
}
/*------------------------------------------------
 mS延时函数,含有输入参数 unsigned char t,无返回值
 unsigned char 是定义无符号字符变量,其值的范围是
 0~255 这里使用晶振12M,精确延时请使用汇编
------------------------------------------------*/
void DelayMs(unsigned char t)
{

 while(t--)
 {
     //大致延时1mS
     DelayUs2x(245);
     DelayUs2x(245);
 }
}
/*------------------------------------------------
                发送字节程序
------------------------------------------------*/
void hc595SendByte(unsigned char dat)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SRCLK=0;
        SER=dat&0x80;
        dat<<=1;
        SRCLK=1;
    }

}
/*------------------------------------------------
                发送双字节程序
     595级联,n个595,就需要发送n字节后锁存
------------------------------------------------*/
void Send2Byte(unsigned char dat1,unsigned char dat2)
{
    hc595SendByte(dat1);
    hc595SendByte(dat2);
}
/*------------------------------------------------
                   595锁存程序
          595级联发送数据后,锁存有效
------------------------------------------------*/
void Out595(void)
{
    LATCH=1;
    _nop_();
    LATCH=0;
}

/*------------------------------------------------
 显示函数,用于动态扫描数码管
 输入参数 FirstBit 表示需要显示的第一位,如赋值2表示从第三个数码管开始显示
 如输入0表示从第一个显示。
 Num表示需要显示的位数,如需要显示99两位数值则该值输入2
------------------------------------------------*/
void Display(unsigned char FirstBit,unsigned char Num)
{
      static unsigned char i=0;



       Send2Byte(dofly_WeiMa[i+FirstBit],TempData[i]);
       Out595();       

       i++;
       if(i==Num)
          i=0;


}
/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
 TMOD |= 0x01;    //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响            
 //TH0=0x00;          //给定初值
 //TL0=0x00;
 EA=1;            //总中断打开
 ET0=1;           //定时器中断打开
 TR0=1;           //定时器开关打开
}
/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 
{
 TH0=(65536-2000)/256;        //重新赋值 2ms
 TL0=(65536-2000)%256;

 Display(0,8);       // 调用数码管扫描

}

/*------------------------------------------------
        按键扫描函数,返回扫描键值
------------------------------------------------*/
unsigned char KeyScan(void)  //键盘扫描函数,使用行列逐级扫描法
{
 unsigned char Val;
 KeyPort=0xf0;//高四位置高,低四位拉低
 if(KeyPort!=0xf0)//表示有按键按下
   {
    DelayMs(10);  //去抖
    if(KeyPort!=0xf0)
      {           //表示有按键按下
        KeyPort=0xfe; //检测第一行
        if(KeyPort!=0xfe)
            {
              Val=KeyPort&0xf0;
              Val+=0x0e;
              while(KeyPort!=0xfe);
              DelayMs(10); //去抖
              while(KeyPort!=0xfe);
              return Val;
            }
        KeyPort=0xfd; //检测第二行
        if(KeyPort!=0xfd)
            {
              Val=KeyPort&0xf0;
              Val+=0x0d;
              while(KeyPort!=0xfd);
              DelayMs(10); //去抖
              while(KeyPort!=0xfd);
              return Val;
            }
        KeyPort=0xfb; //检测第三行
        if(KeyPort!=0xfb)
            {
              Val=KeyPort&0xf0;
              Val+=0x0b;
              while(KeyPort!=0xfb);
              DelayMs(10); //去抖
              while(KeyPort!=0xfb);
              return Val;
            }
        KeyPort=0xf7; //检测第四行
        if(KeyPort!=0xf7)
            {
              Val=KeyPort&0xf0;
              Val+=0x07;
              while(KeyPort!=0xf7);
              DelayMs(10); //去抖
              while(KeyPort!=0xf7);
              return Val;
            }
     }
   }
  return 0xff;
}
/*------------------------------------------------
         按键值处理函数,返回扫键值
------------------------------------------------*/
unsigned char KeyPro(void)
{
 switch(KeyScan())
 {
  case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
  case 0x7d:return 1;break;//1
  case 0x7b:return 2;break;//2
  case 0x77:return 3;break;//3
  case 0xbe:return 4;break;//4
  case 0xbd:return 5;break;//5
  case 0xbb:return 6;break;//6
  case 0xb7:return 7;break;//7
  case 0xde:return 8;break;//8
  case 0xdd:return 9;break;//9
  case 0xdb:return 10;break;//a
  case 0xd7:return 11;break;//b
  case 0xee:return 12;break;//c
  case 0xed:return 13;break;//d
  case 0xeb:return 14;break;//e
  case 0xe7:return 15;break;//f
  default:return 0xff;break;
 }
}

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
51单片机矩阵键盘扫描问题
51单片机矩阵键盘动态扫描,我就看见例程编的程序都有个把io口值赋给一个temp,例如P3=temp然后再位与,然后再判断temp。。。。。。我的问题就是为毛不直接判断P3口的值,多此一举干什么,直接用P3来判断按键按下不可以吗,大神门们求解
小白关于51单片机矩阵键盘的疑惑
不理解为什么矩阵键盘一定要通过扫描的方式才能判断哪个键被按下,直接判断P3的值不可以吗
51单片机矩阵键盘的扫描结果返回给主函数的问题
主程序是一个交通灯,现在加了个检测功能。就是4个路口,每个路口用10位的拨码开关检测车辆数量,然后判断是否该减少该路口的红灯时间。 现在问题是:我检测了四个路口的按键信息并返回给主程序,但是四个路口的返回数据发生错乱。 例如:假设初始红灯时间设为10s,东西南北按键信息分别是 1,2,3,4。那接下来东西方向红灯应该只有8s(东西两个数据里取最大的),南北红灯应该只有6s。 但实际上东西红灯时间也减少为6s了。 下面是所有程序:[交通灯程序](http://pan.baidu.com/s/1c1RcjKk "") 谢谢大家
新手,给51单片机接数码管问题
给51单片机接一个数码管,共阳的,共阳的管脚直接接电源VCC,剩下的八个管脚都通过1K的电阻接到一组IO口上,如果是P0口,每个管脚要接上10K的上拉电阻,P1,2,3,不用上拉。为什么
关于C51单片机的矩阵键盘程序问题
程序目的:对4x4的矩阵键盘进行控制, 按下16个按键分别使第一个数码管显示0~F。 以下为我编写的程序,程序无错但烧写后的结果很奇怪,不明白是哪里错了。 #include "reg52.h" sfr P4=0xc0; unsigned char code keynum[18]= {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80,0xc6,0xc0,0x86,0x8e,0xbf,0x70}; sbit R1=P3^0; sbit R2=P3^1; sbit R3=P3^2; sbit R4=P3^3; sbit C1=P4^4; sbit C2=P4^2; sbit C3=P3^5; sbit C4=P3^4; void HC138(unsigned int k) { switch (k) { case 4: P2=0x80; break; case 5: P2=0xa0; break; case 6: P2=0xc0; break; case 7: P2=0xe0; break; } } void delay(unsigned char t) { while(t--); } void DisplaySMG(unsigned int i) { HC138(7); P0=keynum[i]; delay(6000); } int value=0; void Scankey() { R1=0; R2=R3=R4=1; if(C1 == 0) { while(C1 == 0); value=1; DisplaySMG(value); } else if(C2==0) { while(C2==0); value=2; DisplaySMG(value); } else if(C3==0) { while(C3==0); value=3; DisplaySMG(value); } else if(C4==0) { while(C4==1); value=4; DisplaySMG(value); } R2=0; R1=R3=R4=1; if(C1==0) { while(C1==0); value=5; DisplaySMG(value); } else if(C2==0) { while(C2==0); value=6; DisplaySMG(value); } else if(C3==0) { while(C3==0); value=7; DisplaySMG(value); } else if(C4==0); { while(C4==0); value=8; DisplaySMG(value); } R3=0; R2=R1=R4=1; if(C1==0) { while(C1==0); value=9; DisplaySMG(value); } else if(C2==0) { while(C2==0); value=10; DisplaySMG(value); } else if(C3==0) { while(C3==0); value=11; DisplaySMG(value); } else if(C4==0); { while(C4==0); value=12; DisplaySMG(value); } R4=0; R2=R3=R1=1; if(C1==0) { while(C1==0); value=13; DisplaySMG(value); } else if(C2==0) { while(C2==0); value=14; DisplaySMG(value); } else if(C3==0) { while(C3==0); value=15; DisplaySMG(value); } else if(C4==0); { while(C4==0); value=16; DisplaySMG(value); } } void main() { HC138(4); P0=0xff; HC138(5); P0=0x00; HC138(6); P0=0x01; HC138(7); P0=0x00; C1=1;C2=1;C3=1;C4=1; while(1) { Scankey(); } }
求51单片机可以1602LCD显示时间并可以用矩阵按钮控制修改时间的代码(C语言)
求51单片机可以1602LCD显示时间并可以用矩阵按钮控制修改时间的代码(C语言) 有没有大佬有C语言代码?我实验要用到,谢谢!
51单片机如何在8*8双色点阵上显示数字(使用矩阵键盘输入)
希望大神们给出完整的,能在51单片机上运行的程序,使用C语言编写。
51单片机数码管动态显示的问题
我想比如在数码管输出5201314的话,采用动态刷新,用delay函数,但是现在发现一个问题,我把delay的时间设置的越短越不抖动,但为什么不加delay却显示不对了呢?我认为不加delay就是delay的时间无限短,那不应该显示的更清楚更不抖动么?好疑惑 #include<reg52.h> sbit duan=P2^6; sbit wei=P2^7; //#define a 200 void delay(unsigned int i) { while(--i); } void main() { while(1) { P0=0xfe; wei=1; wei=0; P0=0x6D; duan=1; duan=0; //delay(a); P0=0xfd; wei=1; wei=0; P0=0x5B; duan=1; duan=0; //delay(a); P0=0xfb; wei=1; wei=0; P0=0x3f; duan=1; duan=0; //delay(a); P0=0xf7; wei=1; wei=0; P0=0x06; duan=1; duan=0; //delay(a); P0=0xef; wei=1; wei=0; P0=0x4f; duan=1; duan=0; //delay(a); P0=0xdf; wei=1; wei=0; P0=0x06; duan=1; duan=0; //delay(a); P0=0xbf; wei=1; wei=0; P0=0x66; duan=1; duan=0; //delay(a); } }
如何用延迟函数倒计时60s
如何使用delay函数让共阳极数码管从60倒数当按下矩阵键盘是蜂鸣器响并暂停倒数再次按下时继续。 51单片机 跪求da'lao
关于51单片机的独立键盘检测
在51单片机中,怎么用中断的方式检测按键是否按下?希望最好能有代码。谢谢。
51单片机如何做出科学计算器
AT89C51单片机 LCD1602 4*4矩阵键盘 8个独立按键 如何做出科学计算器
51单片机之间电信号的相互作用
有51单片机A,和51单片机B; 用一根杜邦线连接A的P1.0引脚和B的P1.0引脚; 单片机A中,令P1.0 = 1;单片机B中,令P1.0 = 0; 问,单片机B的P1.0引脚为高电平还是低电平 x
Protues仿真51单片机地址总线为什么会自动输出高?(汇编)
用Protues做51仿真用汇编写的程序,想要驱动共阴极数码管用373地址锁存,273作输出到数码管,原理图如下![图片说明](https://img-ask.csdn.net/upload/201912/23/1577078636_936634.png) 汇编代码如下 ``` ORG 0000H LJMP MAIN MAIN: MOV DPTR,#00FEH MOV A,#60H MOVX @DPTR,A AJMP $ END ``` 代码中地址00FEH对应273输出使能和8号(最右边)的数码管选中,代码运行后地址线为00FEH,但是实际仿真之后发现被选中的数码管并没有显示数字“1” 下图为仿真图,程序执行后地址线输出了高电平导致数码管没有显示 ![图片说明](https://img-ask.csdn.net/upload/201912/23/1577079211_10 8978.png) 原因是数码管的共阴极端连接的地址线在最后输出了高电平而不是一直保持00FEH,想问一下是什么原因导致的这个问题应该怎么解决?
51单片机sbit位定义问题
![图片说明](https://img-ask.csdn.net/upload/201912/14/1576310692_677516.png) ![图片说明](https://img-ask.csdn.net/upload/201912/14/1576311911_329331.png) 1、请问sbit位定义中,^符号是异或操作么 2、我这里用的|和^等价出来的现象是一致的。 3、sbit是位定义,但是地质不可能是一个位,它存储的是最低位比如 sbit led =P2^1 P2为0xA0 那么led只会存储最低位1,请各位指教
单片机51矩阵按键控制步进电机正反转,停,具体看下面
步进电机正反转运行控制,电机按照正转、停、反转的规律运动,要求正反转圈数、停留时间分别可设定,电机完成上述运动后,运行过程中可以暂停,八段数码管闪烁显示,要求系统要使用矩阵按键,同时在八段数码管上具有相应的功能。
小白关于单片机数码管动态显示的问题
数码管的动态显示是利用人眼的暂留效应产生动态效果的,那让正在动态显示的数码管,比如在倒计时,突然停下来,是只显示一位数吗?
51单片机开发板的数码管显示
不知道为什么数码管把0 6 9这3个数字都显示成0xff的样子 就全亮 与代码无关 求解
帮我改C语言代码(51单片机LCD1602显示时间从k1这些按键控制变成矩阵按键控制)
帮我改C语言代码,51单片机LCD1602显示时间从k1这些按键控制变成矩阵按键控制(现在是可以用k1这些按键来修改了) 原理图: ![图片说明](https://img-ask.csdn.net/upload/201912/22/1577010044_884857.png) ![图片说明](https://img-ask.csdn.net/upload/201912/22/1577010062_997331.png) 下面是代码: ``` //下面是main.c代码 /******************************************************************************* * 实验名 : 万年历实验 * 使用的IO : * 实验效果 :1602显示时钟,按K3进入时钟设置,按K1选择设置的时分秒日月,按K2选择 *选择设置加1。 * 注意 : *******************************************************************************/ #include<reg51.h> #include"lcd.h" #include"ds1302.h" sbit K1=P3^1; sbit K2=P3^0; sbit K3=P3^2; sbit K4=P3^3; //管脚接线 void Int0Configuration(); void LcdDisplay(); unsigned char SetState,SetPlace; void Delay10ms(void); //误差 0us /******************************************************************************* * 函数名 : main * 函数功能 : 主函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void main() { unsigned char i; Int0Configuration(); LcdInit(); Ds1302Init(); while(1) { if(SetState==0) { Ds1302ReadTime(); } else { if(K1==0) //检测按键K1是否按下 { Delay10ms(); //消除抖动 if(K1==0) { SetPlace++; if(SetPlace>=7) SetPlace=0; } while((i<50)&&(K1==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } if(K2==0) //检测按键K2是否按下 { Delay10ms(); //消除抖动 if(K2==0) { TIME[SetPlace]++; if((TIME[SetPlace]&0x0f)>9) //换成BCD码。 { TIME[SetPlace]=TIME[SetPlace]+6; } if((TIME[SetPlace]>=0x60)&&(SetPlace<2)) //分秒只能到59 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x24)&&(SetPlace==2)) //小时只能到23 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x32)&&(SetPlace==3)) //日只能到31 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x13)&&(SetPlace==4)) //月只能到12 { TIME[SetPlace]=0; } if((TIME[SetPlace]>=0x7)&&(SetPlace==5)) //周只能到7 { TIME[SetPlace]=1; } // if(SetPlace==5) //月只能到12 // { // TIME[SetPlace]=; // } } while((i<50)&&(K2==0)) //检测按键是否松开 { Delay10ms(); i++; } i=0; } } LcdDisplay(); } } /******************************************************************************* * 函数名 : LcdDisplay() * 函数功能 : 显示函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void LcdDisplay() { LcdWriteCom(0x80+0X40); LcdWriteData('0'+TIME[2]/16); //时 LcdWriteData('0'+(TIME[2]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[1]/16); //分 LcdWriteData('0'+(TIME[1]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[0]/16); //秒 LcdWriteData('0'+(TIME[0]&0x0f)); LcdWriteCom(0x80); LcdWriteData('2'); LcdWriteData('0'); LcdWriteData('0'+TIME[6]/16); //年 LcdWriteData('0'+(TIME[6]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[4]/16); //月 LcdWriteData('0'+(TIME[4]&0x0f)); LcdWriteData('-'); LcdWriteData('0'+TIME[3]/16); //日 LcdWriteData('0'+(TIME[3]&0x0f)); LcdWriteCom(0x8D); LcdWriteData('0'+(TIME[5]&0x07)); //星期 } /******************************************************************************* * 函数名 : Int0Configuration() * 函数功能 : 配置外部中断0 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Int0Configuration() { //设置INT0 IT0=1;//跳变沿出发方式(下降沿) EX0=1;//打开INT0的中断允许。 EA=1;//打开总中断 } /******************************************************************************* * 函数名 : Int0() * 函数功能 : 外部中断0 中断函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Int0() interrupt 0 { Delay10ms(); if(K3==0) { SetState=~SetState; SetPlace=0; Ds1302Init(); } } /******************************************************************************* * 函数名 : Delay10ms * 函数功能 : 延时函数,延时10ms * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Delay10ms(void) //误差 0us { unsigned char a,b,c; for(c=1;c>0;c--) for(b=38;b>0;b--) for(a=130;a>0;a--); } //下面为ds1302.c代码 #include"ds1302.h" //---DS1302写入和读取时分秒的地址命令---// //---秒分时日月周年 最低位读写位;-------// uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---// //---存储顺序是秒分时日月周年,存储格式是用BCD码---// uchar TIME[7] = {0, 0, 0x12, 0x01, 0x01, 0x02, 0x13}; /******************************************************************************* * 函 数 名 : Ds1302Write * 函数功能 : 向DS1302命令(地址+数据) * 输 入 : addr,dat * 输 出 : 无 *******************************************************************************/ void Ds1302Write(uchar addr, uchar dat) { uchar n; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1; //然后将RST(CE)置高电平。 _nop_(); for (n=0; n<8; n++)//开始传送八位地址命令 { DSIO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } for (n=0; n<8; n++)//写入8位数据 { DSIO = dat & 0x01; dat >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0; _nop_(); } RST = 0;//传送数据结束 _nop_(); } /******************************************************************************* * 函 数 名 : Ds1302Read * 函数功能 : 读取一个地址的数据 * 输 入 : addr * 输 出 : dat *******************************************************************************/ uchar Ds1302Read(uchar addr) { uchar n,dat,dat1; RST = 0; _nop_(); SCLK = 0;//先将SCLK置低电平。 _nop_(); RST = 1;//然后将RST(CE)置高电平。 _nop_(); for(n=0; n<8; n++)//开始传送八位地址命令 { DSIO = addr & 0x01;//数据从低位开始传送 addr >>= 1; SCLK = 1;//数据在上升沿时,DS1302读取数据 _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } _nop_(); for(n=0; n<8; n++)//读取8位数据 { dat1 = DSIO;//从最低位开始接收 dat = (dat>>1) | (dat1<<7); SCLK = 1; _nop_(); SCLK = 0;//DS1302下降沿时,放置数据 _nop_(); } RST = 0; _nop_(); //以下为DS1302复位的稳定时间,必须的。 SCLK = 1; _nop_(); DSIO = 0; _nop_(); DSIO = 1; _nop_(); return dat; } /******************************************************************************* * 函 数 名 : Ds1302Init * 函数功能 : 初始化DS1302. * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Ds1302Init() { uchar n; Ds1302Write(0x8E,0X00); //禁止写保护,就是关闭写保护功能 for (n=0; n<7; n++)//写入7个字节的时钟信号:分秒时日月周年 { Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]); } Ds1302Write(0x8E,0x80); //打开写保护功能 } /******************************************************************************* * 函 数 名 : Ds1302ReadTime * 函数功能 : 读取时钟信息 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void Ds1302ReadTime() { uchar n; for (n=0; n<7; n++)//读取7个字节的时钟信号:分秒时日月周年 { TIME[n] = Ds1302Read(READ_RTC_ADDR[n]); } } //下面是lcd.c代码 #include"lcd.h" /******************************************************************************* * 函 数 名 : Lcd1602_Delay1ms * 函数功能 : 延时函数,延时1ms * 输 入 : c * 输 出 : 无 * 说 名 : 该函数是在12MHZ晶振下,12分频单片机的延时。 *******************************************************************************/ void Lcd1602_Delay1ms(uint c) //误差 0us { uchar a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } /******************************************************************************* * 函 数 名 : LcdWriteCom * 函数功能 : 向LCD写入一个字节的命令 * 输 入 : com * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS //当没有定义这个LCD1602_4PINS时 void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } #else void LcdWriteCom(uchar com) //写入命令 { LCD1602_E = 0; //使能清零 LCD1602_RS = 0; //选择写入命令 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = com; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; // Lcd1602_Delay1ms(1); LCD1602_DATAPINS = com << 4; //发送低四位 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; } #endif /******************************************************************************* * 函 数 名 : LcdWriteData * 函数功能 : 向LCD写入一个字节的数据 * 输 入 : dat * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS void LcdWriteData(uchar dat) //写入数据 { LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择输入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //写入数据 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } #else void LcdWriteData(uchar dat) //写入数据 { LCD1602_E = 0; //使能清零 LCD1602_RS = 1; //选择写入数据 LCD1602_RW = 0; //选择写入 LCD1602_DATAPINS = dat; //由于4位的接线是接到P0口的高四位,所以传送高四位不用改 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; LCD1602_DATAPINS = dat << 4; //写入低四位 Lcd1602_Delay1ms(1); LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); LCD1602_E = 0; } #endif /******************************************************************************* * 函 数 名 : LcdInit() * 函数功能 : 初始化LCD屏 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ #ifndef LCD1602_4PINS void LcdInit() //LCD初始化子程序 { LcdWriteCom(0x38); //开显示 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点 } #else void LcdInit() //LCD初始化子程序 { LcdWriteCom(0x32); //将8位总线转为4位总线 LcdWriteCom(0x28); //在四位线下的初始化 LcdWriteCom(0x0c); //开显示不显示光标 LcdWriteCom(0x06); //写一个指针加1 LcdWriteCom(0x01); //清屏 LcdWriteCom(0x80); //设置数据指针起点 } #endif ```
单片机串口通信与矩阵按钮冲突
``` #include<AT89X52.H> #define uchar unsigned char #define uint unsigned int void chuansonghangshu(); void jieshouhangshu(); uchar d=0; unsigned char code a[]= {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; unsigned char b; unsigned char c; unsigned char i,j; sbit P14=P1^4; sbit P15=P1^5; sbit P16=P1^6; sbit P17=P1^7; void delay() {for(i=0;i<=50;i++); } void main(void) { TMOD=0X20; TH1=0XE8; TL1=0XE8; SCON=0X50; TR1=d; P1=0XFF; while(1) { P1=0xff; P14=0; b=P1; b=b&0x0f; if(b!=0x0f) { delay(); b=P1; b=b&0x0f; if(b!=0x0f) { b=P1; b=b&0x0f; switch(b) { case 0x0e:c=3;break; case 0x0d:c=2;break; case 0x0b:c=1;break; case 0x07:c=0;break; } b=P1; P2=a[c]; b=b&0x0f; while(b!=0x0f) { b=P1; b=b&0x0f; } } } P1=0xff; P15=0; b=P1; b=b&0x0f; if(b!=0x0f) { delay(); b=P1; b=b&0x0f; if(b!=0x0f) { b=P1; b=b&0x0f; switch(b) { case 0x0e:c=7;break; case 0x0d:c=6;break; case 0x0b:c=5;break; case 0x07:c=4;break; } b=P1; P2=a[c]; b=b&0x0f; while(b!=0x0f) { b=P1; b=b&0x0f; } } } P1=0xff; P16=0; b=P1; b=b&0x0f; if(b!=0x0f) { delay(); b=P1; b=b&0x0f; if(b!=0x0f) { b=P1; b=b&0x0f; switch(b) { case 0x0e:c=11;break; case 0x0d:c=10;break; case 0x0b:c=9;break; case 0x07:c=8;break; } b=P1; P2=a[c]; b=b&0x0f; while(b!=0x0f) { b=P1; b=b&0x0f; } } } P1=0xff; P17=0; b=P1; b=b&0x0f; if(b!=0x0f) { delay(); b=P1; b=b&0x0f; if(b!=0x0f) { b=P1; b=b&0x0f; switch(b) { case 0x0e:c=15;break; case 0x0d:c=14;break; case 0x0b:c=13;break; case 0x07:c=12;break; } b=P1; P2=a[c]; b=b&0x0f; while(b!=0x0f) { b=P1; b=b&0x0f; } } } d=P2; SBUF=d; while(T1==0); T1=0; while(RI==0) RI=0; d=SBUF; P2=d; } } ``` ```![图片说明](https://img-ask.csdn.net/upload/201912/04/1575461378_540005.png)
相见恨晚的超实用网站
搞学习 知乎:www.zhihu.com 简答题:http://www.jiandati.com/ 网易公开课:https://open.163.com/ted/ 网易云课堂:https://study.163.com/ 中国大学MOOC:www.icourse163.org 网易云课堂:study.163.com 哔哩哔哩弹幕网:www.bilibili.com 我要自学网:www.51zxw
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
字节跳动视频编解码面经
引言 本文主要是记录一下面试字节跳动的经历。 三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时
开源一个功能完整的SpringBoot项目框架
福利来了,给大家带来一个福利。 最近想了解一下有关Spring Boot的开源项目,看了很多开源的框架,大多是一些demo或者是一个未成形的项目,基本功能都不完整,尤其是用户权限和菜单方面几乎没有完整的。 想到我之前做的框架,里面通用模块有:用户模块,权限模块,菜单模块,功能模块也齐全了,每一个功能都是完整的。 打算把这个框架分享出来,供大家使用和学习。 为什么用框架? 框架可以学习整体
源码阅读(19):Java中主要的Map结构——HashMap容器(下1)
(接上文《源码阅读(18):Java中主要的Map结构——HashMap容器(中)》) 3.4.4、HashMap添加K-V键值对(红黑树方式) 上文我们介绍了在HashMap中table数组的某个索引位上,基于单向链表添加新的K-V键值对对象(HashMap.Node&lt;K, V&gt;类的实例),但是我们同时知道在某些的场景下,HashMap中table数据的某个索引位上,数据是按照红黑树
c++制作的植物大战僵尸,开源,一代二代结合游戏
    此游戏全部由本人自己制作完成。游戏大部分的素材来源于原版游戏素材,少部分搜集于网络,以及自己制作。 此游戏为同人游戏而且仅供学习交流使用,任何人未经授权,不得对本游戏进行更改、盗用等,否则后果自负。 目前有六种僵尸和六种植物,植物和僵尸的动画都是本人做的。qq:2117610943 开源代码下载 提取码:3vzm 点击下载--&gt; 11月28日 新增四种植物 统一植物画风,全部修
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
Python——画一棵漂亮的樱花树(不同种樱花+玫瑰+圣诞树喔)
最近翻到一篇知乎,上面有不少用Python(大多是turtle库)绘制的树图,感觉很漂亮,我整理了一下,挑了一些我觉得不错的代码分享给大家(这些我都测试过,确实可以生成喔~) one 樱花树 动态生成樱花 效果图(这个是动态的): 实现代码 import turtle as T import random import time # 画樱花的躯干(60,t) def Tree(branch
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
Python 基础(一):入门必备知识
目录1 标识符2 关键字3 引号4 编码5 输入输出6 缩进7 多行8 注释9 数据类型10 运算符10.1 常用运算符10.2 运算符优先级 1 标识符 标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。 以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx ,表示不能直接访问的类属性,需通过类提供
深度学习图像算法在内容安全领域的应用
互联网给人们生活带来便利的同时也隐含了大量不良信息,防范互联网平台有害内容传播引起了多方面的高度关注。本次演讲从技术层面分享网易易盾在内容安全领域的算法实践经验,包括深度学习图
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
Python 编程实用技巧
Python是一门很灵活的语言,也有很多实用的方法,有时候实现一个功能可以用多种方法实现,我这里总结了一些常用的方法,并会持续更新。
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
"狗屁不通文章生成器"登顶GitHub热榜,分分钟写出万字形式主义大作
GitHub 被誉为全球最大的同性交友网站,……,陪伴我们已经走过 10+ 年时间,它托管了大量的软件代码,同时也承载了程序员无尽的欢乐。 万字申请,废话报告,魔幻形式主义大作怎么写?兄dei,狗屁不通文章生成器了解一下。这个富有灵魂的项目名吸引了众人的目光。项目仅仅诞生一周,便冲上了GitHub趋势榜榜首(Js中文网 -前端进阶资源教程)、是榜首哦
推荐几款比较实用的工具,网站
1.盘百度PanDownload 这个云盘工具是免费的,可以进行资源搜索,提速(偶尔会抽风????) 不要去某站买付费的???? PanDownload下载地址 2.BeJSON 这是一款拥有各种在线工具的网站,推荐它的主要原因是网站简洁,功能齐全,广告相比其他广告好太多了 bejson网站 3.二维码美化 这个网站的二维码美化很好看,网站界面也很...
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
相关热词 c#选择结构应用基本算法 c# 收到udp包后回包 c#oracle 头文件 c# 序列化对象 自定义 c# tcp 心跳 c# ice连接服务端 c# md5 解密 c# 文字导航控件 c#注册dll文件 c#安装.net
立即提问