蓝桥杯单片机第六届国赛题目-智能物料传送系统
·
题目

要点
几个注意的点:
- 倒计时以及倒计时的停止的写法。
- 注意状态在什么时候被改变了,这次的改变可能导致你本来在这里变化进入程序,但是下一瞬间就被切换到另外的状态了
- 蜂鸣器和继电器一定要同时操作,否则会相互影响(1开启,0关闭)
- 可用^取反操作
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

更多推荐
所有评论(0)