51日更 2

51日更 2
1.c中!和~区别
!是逻辑符号,对一个数据进行!运算时,必须先把该数据强制转换为Bool型,即0或1,再进行运算。(Bool型非0就是1)
而~是位运算,对任何数据都不需要强制转换,起作用是将数据在内存中的每一位(当然是二进制)取反。
两种运算的结果一般不相等。
2.KEIL警告
*** WARNING L1: UNRESOLVED EXTERNAL SYMBOL
SYMBOL: _DELAY
MODULE: .\Objects\9.18.obj (9_18)
*** WARNING L2: REFERENCE MADE TO UNRESOLVED EXTERNAL
原因:没把C文件添加到项目中!
另外,还有可能是因为存在没有被调用的已经定义的函数,或者相关的已经定义的变量没有使用。
9.18.c(8): error C100: unprintable character 0xA3 skipped
原因:符号用的全角字符,改成半角的,一般是‘;’打错了
9.18.c(8): error C202: ‘LED_Init0x01’: undefined identifier
检测‘()’是不是格式错误
*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
SEGMENT: ?PR?_LED_RIGHT?LED
原因:该函数没有调用,屏蔽就好了

3.继电器控制
在这里插入图片描述

电路分析:开漏输出(降低功耗),当PNP导通DK亮(指示灯),并联反向接一个IN4148,目的在于稳压,防止反向电流击穿三极管和单片机,有两个接线端,NC1(normal close 1)常闭,NO1(normal open)常开,其余两个是COM端,将MP或NO串连到电路即可控制电路,当开关用,切记,该电路没有保护电路,不要尝试接高压。

5.51单片机的精确延时(软件延时)
电子中将脉冲信号之间的时间间隔称为周期,单位个;单位时间(如1秒)内所产生的脉冲个数称为频率,它的标准计量单位是Hz(赫)。
指令周期:CPU执行一条指令所需要的时间称为指令周期,它以机器周期为单位,不同的指令之间,所需要的机器周期也不同。如,取指令需要一个机器周期,转移指令2个打不住。
时钟周期:也称为振荡周期,一个时钟周期 = 晶振的倒数。它是单片机的基本时间单位,两个组成一个状态周期。
机器周期:单片机的基本操作周期,在一个操作周期内,单片机完成一项基本操作,如取指令、存储器读/写等。

一个机器周期=6个状态周期=12个时钟周期。

一个单周期指令包含一个机器周期,即12个时钟周期,所以一条单周期指令被执行所占时间为12*(1/ 晶振频率)= x μs。

TM1637芯片手册解读
意图:手上有个4位一体的时钟显示模块,利用的TM1637驱动。
TM1637 是一种带键盘扫描接口的LED(发光二极管显示器)驱动控制专用电路。
特性:显示模式(8 段×6 位),支持共阳数码管输出,两线串行接口(CLK,DIO)内置上电复位电路、内置自动消隐电路、振荡方式:内置RC 振荡(450KHz+)、辉度调节电路(占空比 8 级可调)
2)管脚说明:
在这里插入图片描述

功能定义:
DIO数据输入/输出17串行数据输入/输出
CLK时钟输入 18 在上升沿输入/输出数据
SG1~SG8 输出(段) 2-9 N 管开漏输出
GRID6~GRID1 输出(位) 10-15 P 管开漏输出
3)电路原理图:
在这里插入图片描述
在这里插入图片描述

GRID位选:选择控制哪个数码管
SEG 段选:控制数码管显示数字几
该寄存器存储通过串行接口从外部器件传送到TM1637 的数据,地址00H-05h共6个字节单元,分别与芯片SGE和GRID管脚所接的LED灯对应。
写LED显示数据的时候,按照从显示地址从低位到高位,从数据字节的低位到高位操作。
4)接口说明
通过两线总线接口和 TM1637 通信,在输入数据时当 CLK 是高电平时,DIO 上的信号必须保持不变;只有 CLK 上的时钟信号为低电平时,DIO 上的信号才能改变。数据输入的开始条件是 CLK 为高电平时,DIO 由高变低;结束条件是 CLK 为高时,DIO 由低电平变为高电平。

在这里插入图片描述
在这里插入图片描述

主要看PWCLK,时钟周期(振荡周期)最小400ns,两个时钟周期=一个状态周期

写SRAM两种模式
在这里插入图片描述

5)数据指令说明
指令用来设置显示模式和LED 驱动器的状态。
在CLK下降沿后由DIO输入的第一个字节作为一条指令。经过译码,取最高B7、B6两位比特位以区别不同的指令。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6)代码部分
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可知有两种编程方式,下面是官方给的程序流程图

51下的代码解读:
参考http://m.elecfans.com/article/605149.html
感谢大神的整理分享!!!

//延时1ms
void Delay_1ms(unsigned int i)
{
    unsigned char x,j;
    for(j=0;j<i;j++)
for(x=0;x<=120;x++); 
// 晶振为12MHZ时 把 x=120,晶振为11.0592MHZ时 把 x=110
		
}


//倒计时时间算法,检测是否到了一分钟相应的位减一
void time_judge( void )
{
 if(++sec == 60)    //60秒
 { 
  sec = 0;
  if((Hour.shi || Hour.ge || Min.shi || Min.ge) && (--Min.ge <= -1))
  {
   Min.ge = 9;
   if((Hour.shi) ||(Hour.ge) && (--Min.shi <= -1))
   {
    Min.shi = 5;
    if(Hour.shi && (--Hour.ge <= -1))
    {
     Hour.ge = 9;
     if(--Hour.shi <= -1)
     {
      Hour.shi = 0; 
     }
    }
    else
    if((!Hour.shi) && (--Hour.ge <= -1))
    {
     Hour.ge = 0;
    }
   }
   else
   if((!Hour.shi) && (!Hour.ge) && (--Min.shi <= -1))
   {
    Min.shi = 0;
   }
  }
  else if(((!Hour.shi) && (!Hour.ge) && (!Min.shi) ) && (Min.ge <= -1))
  {
   Min.ge = 0;
  }
 } 
}

//主函数:定时器0初始化
//循环部分:显示时间,半秒切换一次数码管第二位,用于判断/控制第二//个数码管的dp的显示,1s调用一次倒计时时间算法

void main( void )
{
 timer0_init();
 time_set(1, 0);  //设置5小时倒计时
 while(1)
 {
  time_display();  //显示时间
	 //1个countTime=0.005s    ,
  if(countTime <= 10)   //10个countTime=0.5s
  {
   dpFlag = 0;   
  }
  else if(countTime <= 20)//20个countTime1s=1s
  {
   dpFlag = 1; 
  }
  else
  {
   countTime = 0;		//countTime1s复位
   time_judge();
  }
 }
}

//显示时间
void time_display( void )
{
 TM1637_writeCammand(0x44);//0  1  数据命令设置,设置为固定模式,写数据到显示寄存器
 TM1637_writeData(0xc0, SEGData[Hour.shi]);
	//1  1  地址命令设置
 if(dpFlag)
  TM1637_writeData(0xc1, SEGDataDp[Hour.ge]); //小数点标志为1则用小数点那个数组
 else
  TM1637_writeData(0xc1, SEGData[Hour.ge]);
 TM1637_writeData(0xc2, SEGData[Min.shi]);
 TM1637_writeData(0xc3, SEGData[Min.ge]);
 TM1637_writeCammand(0x8a); //1  0  显示控制命令设置  ,显示开,脉冲宽度1/4 
}

//写指令
void TM1637_writeCammand(unsigned char mData)
{
 TM1637_start();
 TM1637_write1Byte(mData);  //数据
 TM1637_stop(); //结束函数,看时序图写的
}

//开始函数,看时序图写的
void TM1637_start( void )
{
 CLK = 1;
 DIO = 1;
 delay_140us();
 DIO = 0;
 delay_140us();
 CLK = 0;
 delay_140us();
}
//写1byte
void TM1637_write1Byte(unsigned char mByte)
{
 char loop = 0;
 for(loop = 0; loop < 8; loop++)
 {
  TM1637_write1Bit((mByte>>loop)&0x01); //取得最低位 
 }
 CLK = 0;
 delay_140us();
 DIO = 1;
 delay_140us();
 CLK = 1;
 delay_140us();
 while(DIO == 1);  //获得应答位 
}

//写一位
void TM1637_write1Bit(unsigned char mBit )
{
 CLK = 0;
 delay_140us();
 if(mBit)
  DIO = 1;
 else
  DIO = 0;
 delay_140us(); 
 CLK = 1;
 delay_140us();
}

// 固定地址写数据1byte
void TM1637_writeData(unsigned char addr, unsigned char mData)
{
 TM1637_start();
 TM1637_write1Byte(addr);  //地址   ,1  1  地址命令设置
 TM1637_write1Byte(mData);  //数据
 TM1637_stop(); 
}
//以上代码编写需看懂时序图
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值