题目

在这里插入图片描述

要点

几个注意的点:

  1. 倒计时以及倒计时的停止的写法。
  2. 注意状态在什么时候被改变了,这次的改变可能导致你本来在这里变化进入程序,但是下一瞬间就被切换到另外的状态了
  3. 蜂鸣器和继电器一定要同时操作,否则会相互影响(1开启,0关闭)
  4. 可用^取反操作
uchar LedChange(uchar _data, uchar _dig, uchar _en)
{
 if(_en == 1)
 {
  _data &= ~(1 << _dig);
 }
 else if(_en == 0)
 {
  _data |= (1 << _dig);
 }
 else
 {
  _data ^= (1 << _dig);
 }
 SL(4, _data);
 return(_data);
}

文档树结构

在这里插入图片描述

程序

main.c

#include "init.h"

enum{LED = 4, EXT, SEL, CODE};

//display
uchar curDig;
uchar code CA[] = {0xc0, 0xf9, 0xa4, 0xb0, 0x99, 
                   0x92, 0x82, 0xf8, 0x80, 0x90,
                   0xff};
uchar buf[] = {0, 1, 2, 3, 4, 5, 6, 7};
//按键
enum{KS_GT, KS_AS, KS_WA}keyState=KS_GT;
uchar keyCnt, key, tmpKey;
//时间
t_delay delay_200 = {200, 0, 0};
t_delay delay_250 = {250, 0, 0};
t_delay delay_300 = {300, 0, 0};
t_delay delay_transform = {300, 0, 0};
//变量
float distance;
float adcVal;
uchar time_Transform[2] = {2, 4};
enum{D_KZ, D_FK, D_GZ, D_TF}Detect = D_KZ;
uchar ledData = 0xff;
uchar relayData = 0;
uchar digCnt = 0;
void Timer1Handle() interrupt 3
{
 //显示
 SL(CODE, 0xff); SL(SEL, 1 << curDig); SL(CODE, CA[buf[curDig]]);
 curDig = (curDig + 1)%8;
 //按键
 switch(keyState)
 {
  case KS_GT:
       keyCnt = 0; keyState = KS_AS; tmpKey = GetKey();
  break;
  case KS_AS:
       if(keyCnt++ < 10);
       else if(tmpKey == GetKey())
       {
        if(key != tmpKey)
        {
         keyState = KS_WA;
         key = tmpKey;
        }
        else
         keyState = KS_GT;
       }
       else
        keyState = KS_GT;
  break;
 }
 //时间
 TimeRun(&delay_200);
 TimeRun(&delay_250);
 TimeRun(&delay_300);
 //如果开始计时才计时
 if(delay_transform.ok == 2)
 {
  TimeBack(&delay_transform);
 }
}
void SensorProcess()
{
 if(delay_200.ok == 1)
 {
  delay_200.ok = 0;
  Sonic_R();
  //ADC检测
  adcVal = Adc_Read(0x43, 200);
  //如果在没有传送的时候才允许换状态
  if(Detect != D_TF)
  {
   if(adcVal >= 4.0)
     Detect = D_GZ;
   else if(adcVal >=1)
    Detect = D_FK;
   else
    Detect = D_KZ;
  }
 }
}
void EventProcess()
{
 if(delay_300.ok == 1)
 {
  delay_300.ok = 0;
  if(digCnt == 1)
  {
   if(buf[3] != F_C)
    BF(3, F_C, F_C, F_C, 
       F_C, F_C, FR(time_Transform[1], 1),
       FR(time_Transform[1], 0));
   else
    BF(3, F_C, F_C, FR(time_Transform[0], 1), 
       FR(time_Transform[0], 0), F_C, FR(time_Transform[1], 1),
       FR(time_Transform[1], 0));
  }
  else if(digCnt == 2)
  {
   if(buf[6] != F_C)
    BF(3, F_C, F_C, FR(time_Transform[0], 1), 
       FR(time_Transform[0], 0), F_C, F_C,
       F_C);
   else
    BF(3, F_C, F_C, FR(time_Transform[0], 1), 
       FR(time_Transform[0], 0), F_C, FR(time_Transform[1], 1),
       FR(time_Transform[1], 0));
  }
 }
 //超声波
 if(Detect == D_FK)
 {
  uchar leixing = 0;
  if(distance > 30)
   leixing = 2;
  else
   leixing = 1;
  BF(1, F_C, F_C, FR(distance, 1), FR(distance, 0), F_C, F_C, leixing);
 }
 //开启传送
 if(Detect == D_TF)
 {
  if(delay_transform.ok == 1)
  {
   delay_transform.ok = 0;
   RLOFF;
   Detect = D_KZ;//随便给个状态,它会在sensor中刷新的 
  }
  else
  {
   BF(2, F_C, F_C, F_C, F_C, F_C, FR(delay_transform.max/500.0,1), FR(delay_transform.max/500.0,0));  
  }
 }
 //空载关闭数码管(注意要digCnt == 0保证没有设置传送时间)
  if(Detect == D_KZ && (digCnt == 0))
 {
  if(buf[0] != F_C)
  {
   memset(buf, F_C, 8);
  }
 }
}
void LedProcess()
{
 static uchar s_Detect = 255;
 if((s_Detect != Detect) || Detect == D_GZ)
 {
  switch(Detect)
  {
   case D_KZ:
        ledData = LedChange(ledData, 0, 1);
        ledData = LedChange(ledData, 1, 0);
        ledData = LedChange(ledData, 2, 0);
        BPOFF;
        if(relayData == 1) 
        {
         RLON;
        }
        else 
        {
         RLOFF;
        }
   break;
   case D_FK:
        ledData = LedChange(ledData, 1, 1);
        ledData = LedChange(ledData, 0, 0);
        ledData = LedChange(ledData, 2, 0);
        BPOFF;
        if(relayData == 1) 
        {
         RLON;
        }
        else 
        {
         RLOFF;
        }
   break;
   case D_GZ:
        if(s_Detect != Detect)
        {
         ledData = LedChange(ledData, 0, 0);
         ledData = LedChange(ledData, 1, 0);
         BPON;RLOFF;
        }
        if(delay_250.ok == 1)
        {
         delay_250.ok = 0;
         ledData = LedChange(ledData, 2, 2);
        } 
   break;
  }
    s_Detect = Detect;
 }
 //如果传送开启,但是计时没有开启
 if((Detect == D_TF) && (delay_transform.ok == 0))
 {
  if(delay_250.ok == 1)
  {
   delay_250.ok = 0;
   ledData = LedChange(ledData, 3, 2);
  }
 }
}

void KeyProcess()
{
 if(Detect == D_KZ)
 {
  if(key == 6)
  {     
   if(digCnt == 0)
   {
    BF(3, F_C, F_C, FR(time_Transform[0], 1), 
       FR(time_Transform[0], 0), F_C, FR(time_Transform[1], 1),
       FR(time_Transform[1], 0));
    digCnt++;
   }
   else
    digCnt++;
   if(digCnt == 3)
   {
    Code_Write(0,time_Transform,2);
    digCnt = 0;
    memset(buf, F_C, 8);
   }
  }
  if(key == 7)
  {
   if(digCnt != 0)
   {
    if(digCnt == 1)
    {
     if(time_Transform[0]++ < 10);
     else 
      time_Transform[0] = 1;
    }
    if(digCnt == 2)
    {
     if(time_Transform[1]++ < 10);
     else 
      time_Transform[1] = 1;
    }
    BF(3, F_C, F_C, FR(time_Transform[0], 1), 
       FR(time_Transform[0], 0), F_C, FR(time_Transform[1], 1),
       FR(time_Transform[1], 0));
   }
  }
 }
 //如果在非空情况下,按下启动传送
 if(Detect == D_FK)
 {
   if(key == 4)
   {
    Detect = D_TF;
    delay_transform.max = 500*(time_Transform[buf[7] - 1] + 1);
    //开启计时
    delay_transform.ok = 2;
    BF(2, F_C, F_C, Fuu_C, 
       F_C, F_C, FR(time_Transform[buf[7] - 1], 1),
       FR(time_Transform[buf[7] - 1], 0));
    RLON;BPOFF;
   }
 }
 if(Detect == D_TF)
 {
  if(key == 5)
  {
   //停止计时传送
   if(delay_transform.ok == 2)
   {
    delay_transform.ok = 0;
    BPOFF;RLOFF;
   }
   //打开传送
   else
   {
    delay_transform.ok = 2;
    BPOFF;RLON;
    ledData = LedChange(ledData, 3, 0);
   }
  }
 }
}
void main()
{
 //初始化
 BPOFF; RLOFF;
 SL(LED, 0xff);
 Timer1Init();
 memset(buf, F_C, 8);
 Code_Read(0,time_Transform,2);
 //超声波初始化
  CMOD |= 0x08;
  while(1)
  {
   SensorProcess();
   EventProcess();
   LedProcess();
   if(keyState == KS_WA)
   {
    KeyProcess();
    keyState=KS_GT;
   }    
  }
}

init.c

#include "init.h"



void SL(uchar _dev, uchar _data)
{
 P0 = _data; SEL(_dev);
}


void Timer1Init(void)		//2毫秒@12.000MHz
{
	AUXR |= 0x40;		//定时器时钟1T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x40;		//设置定时初值
	TH1 = 0xA2;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
 ET1= 1;
 EA = 1;
}

uchar GetKey()
{
 if(!K1) return 7;
 if(!K2) return 6;
 if(!K3) return 5;
 if(!K4) return 4;
 return 0;
}

uchar FR(float _data, uchar _dig)
{
 uint i = 1;
 while(_dig--)
 {
  i = i * 10;
 }
 return((uint)_data/i%10);
}


void BF(uchar _0, uchar _1, uchar _2, uchar _3,
         uchar _4, uchar _5, uchar _6, uchar _7)
{
 buf[0] = _0; buf[1] = _1; buf[2] = _2; buf[3] = _3; 
 buf[4] = _4; buf[5] = _5; buf[6] = _6; buf[7] = _7;
}

void TimeRun(t_delay* time)
{
 if(time->cnt++ < time->max);
 else
 {
  time->cnt = 0;
  time->ok = 1;
 }
}

void TimeBack(t_delay* time)
{
 if(time->max-- > 1 );
 else
 {
  time->cnt = 0;
  time->ok = 1;
 }
}

void Delay14us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 39;
	while (--i);
}

void Sonic_T()
{
 uchar i = 10;
 while(i--)
 {
  P10 = 1;
  Delay14us();
  P10 = 0;
  Delay14us(); 
 }
}
void Sonic_R()
{
 Sonic_T();
 CL = 0; CH = 0;CR = 1;
 while((!CF) && P11);
 CR = 0;
 if(CF)
 {
  CF = 0; distance = 9999;
 }
 else
 {
  uint tmpVal = ((uint)CH << 8) | CL;
  distance = tmpVal*0.017/12;
 }
}

uchar LedChange(uchar _data, uchar _dig, uchar _en)
{
 if(_en == 1)
 {
  _data &= ~(1 << _dig);
 }
 else if(_en == 0)
 {
  _data |= (1 << _dig);
 }
 else
 {
  _data ^= (1 << _dig);
 }
 SL(4, _data);
 return(_data);
}

iic.c

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台 8051,12MHz
  日    期: 2011-8-9
*/

#include "reg52.h"
#include "intrins.h"
#include "type.h"
#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
uint IICVal;
//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
					SCL = 1;
					IIC_Delay(DELAY_TIME);
					da <<= 1;
					if(SDA) da |= 1;
					SCL = 0;
					IIC_Delay(DELAY_TIME);
    }
    return da;    
}

//void IIC_Write(uchar _addr, uint _data){
//	IIC_Start();
//	IIC_SendByte(0xA0);
//	IIC_WaitAck();
//	IIC_SendByte(_addr*2);
//	IIC_WaitAck();
//	IIC_SendByte(_data >> 8);
//	IIC_WaitAck();
//	IIC_SendByte(_data);
//	IIC_WaitAck();
//	IIC_Stop();
//}
//void IIC_Read(uchar _addr){
//	uint tempVal;
//	IIC_Start();
//	IIC_SendByte(0xA0);
//	IIC_WaitAck();
//	IIC_SendByte(_addr*2);
//	IIC_WaitAck();
//	IIC_Start();
//	IIC_SendByte(0xA1);
//	IIC_WaitAck();
//	tempVal = (uint)IIC_RecByte() << 8;
//	IIC_SendAck(0);
//	tempVal |= IIC_RecByte();
//	IIC_Stop();
//	IICVal = tempVal;
//}
void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 47;
	j = 174;
	do
	{
		while (--j);
	} while (--i);
}
void Code_Write(uchar _addr, uchar* _data, uchar _dig)
{
 IIC_Start();
 IIC_SendByte(0xa0);
 IIC_WaitAck();
 IIC_SendByte(_addr);
 IIC_WaitAck();
 while(_dig--)
 {
  IIC_SendByte(*_data++);
  IIC_WaitAck();
 }
 IIC_Stop();
}
void Code_Read(uchar _addr, uchar* _data, uchar _dig)
{
 IIC_Start();
 IIC_SendByte(0xa0);
 IIC_WaitAck();
 IIC_SendByte(_addr);
 IIC_WaitAck();
 IIC_Start();
 IIC_SendByte(0xa1);
 IIC_WaitAck();
 _dig--;
 while(_dig--)
 {
  *_data++ = IIC_RecByte();
  IIC_SendAck(0);
 }
  *_data++ = IIC_RecByte();
 IIC_Stop();
}


float Adc_Read(uchar _addr, uchar _data)
{
 uchar tmpVal;
 IIC_Start();
 IIC_SendByte(0x90);
 IIC_WaitAck();
 IIC_SendByte(_addr);
 IIC_WaitAck();
 IIC_SendByte(_data);
 IIC_WaitAck();
 IIC_Stop();
 IIC_Start();
 IIC_SendByte(0x91);
 IIC_WaitAck();
 tmpVal = IIC_RecByte();
 IIC_SendAck(0);
 return(IIC_RecByte()/51.0); 
}

init.h

#ifndef _INIT_H
#define _INIT_H
#include "stc15f2k60s2.h"
#include "intrins.h"
#include "stdio.h"
#include "string.h"
#include "type.h"

#define SEL(x) P2=P2&0x1f|x<<5;P2=P2&0x1f
sbit BP = P0^6; sbit RL = P0^4;
#define BPON BP = 1; SEL(5)
#define BPOFF BP = 0; SEL(5)
#define RLON RL = 1; SEL(5)
#define RLOFF RL = 0; SEL(5)

sbit K1=P3^0; sbit K2=P3^1; sbit K3=P3^2; sbit K4=P3^3;
extern uchar buf[8];
extern float distance;
#define F_C 10
typedef struct delay
{
 uint max;
 uint cnt;
 uchar ok;
}t_delay;

//函数
void SL(uchar _dev, uchar _data);
void Timer1Init(void);
uchar GetKey();
void BF(uchar _0, uchar _1, uchar _2, uchar _3,
        uchar _4, uchar _5, uchar _6, uchar _7);
uchar FR(float _data, uchar _dig);
void TimeRun(t_delay* time);
void Delay14us();
void Sonic_T();
void Sonic_R();
void Code_Read(uchar _addr, uchar* _data, uchar _dig);
void Code_Write(uchar _addr, uchar* _data, uchar _dig);
float Adc_Read(uchar _addr, uchar _data);
uchar LedChange(uchar _data, uchar _dig, uchar _en);
void TimeBack(t_delay* time);
#endif

type.h

#ifndef _TYPE_H
#define _TYPE_H


#define uchar unsigned char
#define uint unsigned int
#endif

在这里插入图片描述

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐