栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【13届蓝桥杯单片机组第二场省赛程序 】

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【13届蓝桥杯单片机组第二场省赛程序 】

main.c文件
#include 
#include "FUnCTION.H"

static unsigned int count = 0;
static unsigned int distance = 45;
bit isSon = 0;
bit isAdr = 0;
bit isCel = 0;
bit isLE7 = 0;
bit isTia = 1;

unsigned char Ad_R = 0;

static unsigned char Ad_up = 45;
static unsigned char Ad_down = 5;

static unsigned char Ad_up_temp = 45;
static unsigned char Ad_down_temp = 5;

unsigned char Key  = 0;
unsigned char Key0 = 0;

bit State2 = 0;//对应2种电压 0-低 1-高
unsigned char State1 = 0;//对应3种显示状态

void Timer0Init(void)		//100微秒12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x50;		
	TH0 = 0xFB;		
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	
	TMOD |= 0x10;	//设置定时器1为16位计数器
	TL1 = 0;		//设置定时初值
	TH1 = 0;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 0;		//关闭定时器1
}

unsigned char Key_Num(); //独立按键

void Timer()   //定时服务,写在定时器外面,减少中断占用
{
	if(count == 1)
	{
		if(isAdr)//判断是否测压
		{
			Ad_R = AD_Read(0x03);  //01光敏,03电位器
		}
		if(isSon)//判断是否测距
		{
			distance = measure_distance();
		}
		
	}
	if((count%100)==20)
	{
		if(isCel)//led闪烁,由于计时器0有时会被关闭,就用了0.01s,肯定有更好的实现方法,但是
                 //考试时候时间紧,来不及想
		{
			isLE7 = ~isLE7;
		}
	}
}

void Init()    //初始化板子
{
	Select(5);
	P0 = 0x00;
	Select(4);
	P0 = 0xFF;
	EA = 1;
	ET0 = 1;
	Timer0Init();
}

//超声波相关函数
void Delay12us()		//@12.000MHz   12us专用延时
{
	unsigned char i;

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

void send_wave()   //发送超声波
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		TX=1;
		Delay12us();
		TX=0;
		Delay12us();
  }
}

//超声波测距
unsigned int measure_distance()	
{
	unsigned int distance = 0;
	unsigned int time = 0; //用于计数脉冲个数
	
	TH1 = 0;TL1 = 0;
	send_wave(); //发送超声波信号
	TR0 = 0;
	TR1 = 1;       //启动定时器,开始测距	
	while((RX == 1)&&(TF1 == 0)); //等待接收到超声波信号返回,或者等到测量超出范围  TF1是溢出标志位,计满溢出后置1  
	TR1 = 0;      //停止定时器
	
	if(RX == 0&&TF1 == 0)//收到返回信号,计算时间
	{
		time = TH1;
		time = (time<<8)|TL1; //读取定时器脉冲个数,获得时间T
		distance = (unsigned int)time*0.017 + 1;//时间转化为距离单位cm
  }
	else if(RX == 1&&TF1 == 1)//溢出
	{
		TF1 = 0;
		distance = 999;
   }
	TH1 = 0;TL1 = 0;
	TR1 = 0;
	TR0 = 1;
	return distance;
}

//状态机
void FSM()
{
	Key0 = Key_Num();
	if(Key0)
	{
		Key = Key0;
		Key0 = 0;					//判断按键并回零
		if(Key == 4)
		{
		State1++;
		Key = 0;
		if(State1 == 3) State1 = 0;
		}
	}
	
		switch (State1)				//根据State1进入相应状态
	{
		case 0:{							//ad状态
							if(~isTia)   //进入状态0,将调参的参数保存
						{
							Ad_up = Ad_up_temp;
						  Ad_down = Ad_down_temp;
							isTia = 1;
						}
			
							isAdr = 1;
							isCel = 1;
							Nixie_Show_Ad(Ad_R);
							Select(4);
							Delay(5);
							P0 = 0xFE;
						}
		break;
		case 1:							//测距状态
					{

						
						
						isAdr = 1;
						isCel = 1;
						Nixie_Show_Son(distance,isSon);
						Select(4);
						P0 = 0xFD;
					}
			break;
		case 2:					//调参状态
					{
						if(isTia)
						{
							Ad_up_temp = Ad_up;  //把Ad已有参数传给temp值
						  Ad_down_temp = Ad_down;
							isTia = 0;           //转入标志位,表示进入temp状态
						}
						
						isAdr = 0;
						isCel = 0;
						isLE7 = 0;//关闭led8闪烁
						Nixie_Show_Can(Ad_down_temp,Ad_up_temp);
						Select(4);
						Delay(5);
						P0 = 0xFB;//使led8常亮
						
						if(Key == 5)  //
						{
							State2 = ~State2;   //调整调参变量
							Key = 0;
						}
						
						if(State2)
						{
							if(Key == 6)
							{
								Ad_up_temp += 5;
								if(Ad_up_temp >= 50)Ad_up_temp = 0;
								Key = 0;
							}
							if(Key == 7)
							{
								Ad_up_temp -= 5;
								if(Ad_up_temp <= 5)Ad_up_temp = 50;
								Key = 0;
							}
						}
						else
						{
							if(Key == 6)
							{
								Ad_down_temp += 5;
								if(Ad_down_temp >= 50)Ad_down_temp = 0;
								Key = 0;
							}
							if(Key == 7)
							{
								Ad_down_temp -= 5;
								if(Ad_down_temp <= 5)Ad_down_temp = 50;
								Key = 0;
							}
						}
						Key = 0;//key归零,方便再次检测
					}
			break;
		default:
			break;
	}
	
	if(isSon)//根据是否打开超声波检测,以及测量值输出电压详细规则见题目
	{
		if(distance<20)DA_Set(51);
		else if(80 

Function.h文件

#ifndef _FUNCTION_H_
#define _FUNCTION_H_

#include 
#include "IIC.H"
#include "intrins.h"

sbit TX=P1^0;  //超声波针脚
sbit RX=P1^1;  
//各种显示函数
void Select(unsigned char val);
void Delay(unsigned int xus);
void Nixie_Show(unsigned char ch,unsigned char dat);
void Nixie_Show_Son(unsigned int son,bit isSon);
void Nixie_Show_Ad(unsigned char ad);
void Nixie_Show_Can(unsigned char down,up);

//ad,da函数
unsigned char AD_Read(unsigned char add);
void DA_Set(unsigned char val);


#endif
Function.c文件
#include "FUNCTION.H"
//都是一些常用的基本模块,没啥可说的
code unsigned char Date[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x80,0x3E,0x73,0x3C,0x77};
//							0~9													.	  U   P    L   
code unsigned char Com[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void Delay(unsigned int xus)
{
	while(xus--);
}

void Select(unsigned char val)
{
	switch (val)
  {
		case 4:P2 = P2&0x1F|0x80;break;
		case 5:P2 = P2&0x1F|0xA0;break;
		case 6:P2 = P2&0x1F|0xC0;break;
		case 7:P2 = P2&0x1F|0xE0;break;
  	default:
  		break;
  }
}


void Nixie_Show(unsigned char ch,unsigned char dat)
{
	P2 = P2&0x1F|0xC0;
	Delay(5);
	P0 = Com[ch];
	
	P2 = P2&0x1F|0xE0;
	Delay(5);
	P0 = ~Date[dat];
	Delay(100);
	
	P2 = P2&0x1F|0x00;
}

void Nixie_Show_Son(unsigned int son,bit isSon)
{
	if(isSon)
	{
		Nixie_Show(0,13);
		
		if(son%1000/100)
		{
		Nixie_Show(5,son%1000/100);
		Nixie_Show(6,son%100/10);
		Nixie_Show(7,son%10);
		}
		else if(son%100/10)
		{
		Nixie_Show(6,son%100/10);
		Nixie_Show(7,son%10);
		}
		else
		{
		Nixie_Show(7,son%10);
		}
	}
	else
	{
	Nixie_Show(0,13);
	
	Nixie_Show(5,14);
	Nixie_Show(6,14);
	Nixie_Show(7,14);
	}
}

void Nixie_Show_Ad(unsigned char ad)
{
	unsigned int adin = (int)(ad*(1.96));//500/255=1.96
	Nixie_Show(0,11);
	Nixie_Show(5,adin/100);
	Nixie_Show(5,10);
	Nixie_Show(6,adin%100/10);
	Nixie_Show(7,adin%10);
}

void Nixie_Show_Can(unsigned char down,up)
{
	Nixie_Show(0,12);
	
	Nixie_Show(3,down%100/10);
	Nixie_Show(3,10);
	Nixie_Show(4,down%10);
	
	Nixie_Show(6,up%100/10);
	Nixie_Show(6,10);	
	Nixie_Show(7,up%10);
}

void DA_Set(unsigned char val)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x43);
	IIC_WaitAck();
	IIC_SendByte(val);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char AD_Read(unsigned char add)
{
	unsigned char rec;

	IIC_Start();
	IIC_SendByte(0x90);

	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	//Delay(5000);
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	rec = IIC_RecByte();
	IIC_SendByte(0);
	IIC_Stop();
	
	return rec;
}
IIC.h文件
#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

#endif
IIC.c文件
#include "reg52.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
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;    
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886844.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号