第十届“蓝桥杯”单片机省赛——程序设计题

第十届“蓝桥杯”单片机省赛——程序设计题 

个人编写,代码仅供参考

如有不足,多多指教

1.题目

 

 

 

2.代码

main.c程序

#include "reg52.h"
#include "iic.h"
#include "intrins.h"

uchar code smg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0XFF,0xc1,0x8e,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
//                    0    1    2    3    4    5    6     7   8    9    -   mie		U    F    0.   1.    2.  3.   4.   5.   6.   7.   8.   9.


//======================延时函数


void delay_smg(uint time)
{
	while(time--);
}

//====================参数定义
sfr AUXR = 0X8E;
sbit s4 = P3^3;
sbit s5 = P3^2;
sbit s6 = P3^1;
sbit s7 = P3^0;
sbit l1 = P0^0;
sbit l2 = P0^1;
sbit l3 = P0^2;
sbit l4 = P0^3;
sbit l5 = P0^4;

uint count_f;//计数器计数用
uchar count_dinshi;//定时器用

uint dat_f;//频率

uchar value_resis_temp;//从pcf读取的电位器的电压的0~255值
#define value_resis 5*((float)value_resis_temp/255)//电位器的电压(实际)

uchar value_output_temp;//让pcf输出的电压0~255值
#define value_output (float)(5*(value_output_temp/255))//让pcf输出的电压(实际)

//当shuchu_flag = 1  value_output_temp = 102 (2v)
//当shuchu_flag = 0  value_output_temp = value_resis_temp



uchar celiang_flag = 1;    // 1  电压测量      0  频率测量
uchar shuchu_flag = 1;    //  1   2v固定输出   0   跟随测量输出
uchar led_flag = 1;       //  1   led启用      0   led关闭
uchar smg_flag = 1;     //   1   smg启用      0   smg关闭

//========================函数定义
void key_scan();
void init();
void smg_dis(uchar pos,uchar val);
void smg_show();

void Init_Timer();

void get_resis();
void smg_dis_all(uchar val);
void pcf_dac_output();
void led_show();

//=========================主函数
void main()
{
	init();
	Init_Timer();
	while(1)
	{
		key_scan();
		get_resis();
		pcf_dac_output();
		led_show();
		smg_show();
	}
}
//========================初始化函数

void select(uchar channel)
{
	switch(channel)
	{
		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;
		case 0 : P2 = (P2 & 0X1F) | 0X00; break;
	}
}


void init()
{
	select(5);
	P0 &= 0XAF;
	select(4);
	P0 = 0XFF;
	select(6);
	P0 = 0XFF;
	select(7);
	P0 = smg[11];
	select(0);
	P0 = 0XFF;
}


//========================按键扫描
void key_scan()
{
	if(s4 == 0)
	{
		smg_show();
		if(s4 == 0)
		{
			while(s4 == 0)
			{
				smg_show();
			}
			switch(celiang_flag)
			{
				case 1 : celiang_flag = 0;break;
				case 0 : celiang_flag = 1;break;
			}
		}
	}
	if(s5 == 0)
	{
		smg_show();
		if(s5 == 0)
		{
			while(s5 == 0)
			{
				smg_show();
			}
			switch(shuchu_flag)
			{
				case 1 : shuchu_flag = 0;break;
				case 0 : shuchu_flag = 1;break;
			}
		}
	}
	if(s6 == 0)
	{
		smg_show();
		if(s6 == 0)
		{
			while(s6 == 0)
			{
				smg_show();
			}
			switch(led_flag)
			{
				case 1 : led_flag = 0;break;
				case 0 : led_flag = 1;break;
			}
		}
	}
	if(s7 == 0)
	{
		smg_show();
		if(s7 == 0)
		{
			while(s7 == 0)
			{
				smg_show();
			}
			switch(smg_flag)
			{
				case 1 : smg_flag = 0;break;
				case 0 : smg_flag = 1;break;
			}
		}
	}
}
//==========================数码管函数
void smg_dis(uchar pos,uchar val)
{
	select(7);
	P0 = 0XFF;
	select(6);
	P0 = 0X01 << pos;
	select(7);
	P0 = smg[val];
	select(0);
	delay_smg(500);
}
void smg_dis_all(uchar val)
{
	select(6);
	P0 = 0XFF;
	select(7);
	P0 = smg[val];
	select(0);
}
//=========================计数器0,定时器1          获取频率为  dat_f



void Init_Timer()
{
	TH0 = 0xff;        
	TL0 = 0xff;
	
	TH1 = (65536 - 50000) / 256;        
	TL1 = (65536 - 50000) % 256;
	
	TMOD = 0x16;     //定时器1用方式1,定时;定时器0用方式2,计数
	
  ET0 = 1;
  ET1 = 1;
	EA = 1;
	
	TR0 = 1;
	TR1 = 1;
}


void ser_counter() interrupt 1
{
	count_f++;
}

void ser_timer() interrupt 3
{
	TH1 = (65536 - 50000) / 256;        
	TL1 = (65536 - 50000) % 256;
	count_dinshi++;
	if(count_dinshi == 20)
	{
		dat_f = count_f;
		count_dinshi = 0;
		count_f = 0;
	}
}

//=======================获取输出电压
void get_resis()
{
	value_resis_temp = pcf_adc();
}
//=======================数码管显示函数
void smg_show()
{
	if(smg_flag == 0)
	{
		smg_dis_all(11);
	}
	else
	{
		if(celiang_flag == 1)
		{
			smg_dis(0,12);
			smg_dis(1,11);
			smg_dis(2,11);
			smg_dis(3,11);
			smg_dis(4,11);
			smg_dis(5,((int)((value_resis*100))/100)+14);
			smg_dis(6,(((int)((value_resis*100))/10))%10);
			smg_dis(7,((int)((value_resis*100)))%10);
			smg_dis_all(11);
		}
		else if(celiang_flag == 0)
		{
			if(dat_f >= 100000)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,dat_f/100000);
				smg_dis(3,(dat_f/10000)%10);
				smg_dis(4,(dat_f/1000)%10);
				smg_dis(5,(dat_f/100)%10);
				smg_dis(6,(dat_f/10)%10);
				smg_dis(7,dat_f%10);
				smg_dis_all(11);
			}
			else if(dat_f >= 10000)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,11);
				smg_dis(3,dat_f/10000);
				smg_dis(4,(dat_f/1000)%10);
				smg_dis(5,(dat_f/100)%10);
				smg_dis(6,(dat_f/10)%10);
				smg_dis(7,dat_f%10);
				smg_dis_all(11);
			}
			else if(dat_f >= 1000)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,11);
				smg_dis(3,11);
				smg_dis(4,dat_f/1000);
				smg_dis(5,(dat_f/100)%10);
				smg_dis(6,(dat_f/10)%10);
				smg_dis(7,dat_f%10);
				smg_dis_all(11);
			}
			else if(dat_f >= 100)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,11);
				smg_dis(3,11);
				smg_dis(4,11);
				smg_dis(5,dat_f/100);
				smg_dis(6,(dat_f/10)%10);
				smg_dis(7,dat_f%10);
				smg_dis_all(11);
			}
			else if(dat_f >= 10)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,11);
				smg_dis(3,11);
				smg_dis(4,11);
				smg_dis(5,11);
				smg_dis(6,dat_f/10);
				smg_dis(7,dat_f%10);
				smg_dis_all(11);
			}
			else if(dat_f >= 1)
			{
				smg_dis(0,13);
				smg_dis(1,11);
				smg_dis(2,11);
				smg_dis(3,11);
				smg_dis(4,11);
				smg_dis(5,11);
				smg_dis(6,11);
				smg_dis(7,dat_f);
				smg_dis_all(11);
			}
		}
		//
	}
}
//========================pcf输出函数
void pcf_dac_output()
{
	switch(shuchu_flag)
	{
		case 1 : value_output_temp = 102 + 5;break;//输出误差5
		case 0 : value_output_temp = value_resis_temp + 5;break;//输出误差5
	}
	pcf_dac(value_output_temp);
}
//========================led功能显示
void led_show()
{
	if(led_flag == 0)//led没有启用
	{
		select(4);
		P0 = 0XFF;
		select(0);
		P0 = 0XFF;
	}
	else if(led_flag == 1)//led启用
	{
		if(celiang_flag == 1)
		{
			select(4);
			P0 = (P0 & 0XFE) | 0XE2;
			select(0);

		}
		else if(celiang_flag == 0)
		{
			select(4);
			P0 = (P0 & 0XFD) | 0XE1;
			select(0);

		}
		if(value_resis < 1.5)
		{
			select(4);
			P0 |= 0XE4;
			select(0);

		}
		else if(value_resis < 2.5 && value_resis >= 1.5)
		{
			select(4);
			P0 = (P0 & 0XFB) | 0XE0;
			select(0);

		}
		else if(value_resis < 3.5 && value_resis >= 2.5)
		{
			select(4);
			P0 |= 0XE4;
			select(0);

		}
		else if(value_resis >= 3.5)
		{
			select(4);
			P0 = (P0 & 0XFB) | 0XE0;
			select(0);

		}
		if(dat_f < 1000)
		{
			select(4);
			P0 |= 0XE8;
			select(0);

		}
		else if(dat_f < 5000 && dat_f >= 1000)
		{
			select(4);
			P0 = (P0 & 0XF7) | 0XE0;
			select(0);

		}
		else if(dat_f < 10000 && dat_f >= 5000)
		{
			select(4);
			P0 |= 0XE8;
			select(0);

		}
		else if(dat_f >= 10000)
		{
			select(4);
			P0 = (P0 & 0XF7) | 0XE0;
			select(0);

		}
		if(shuchu_flag == 1)//如果固定输出2v,led5 灭
		{
			select(4);
			P0 |= 0XF0;
			select(0);

		}
		else if(shuchu_flag == 0)//如果固定输出跟随,led5 亮
		{
			select(4);
			P0 = (P0 & 0XEF) | 0XE0;
			select(0);

		}
	}
}
//======================END

iic.c程序

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

#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;    
}

//===========================================
uchar pcf_adc()
{
	uchar temp;
	
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(0X03);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0X91);
	IIC_WaitAck();
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return temp;
}

void pcf_dac(uchar dat)//dat  (0,255)
{
	IIC_Start();
	IIC_SendByte(0X90);
	IIC_WaitAck();
	IIC_SendByte(0X43);
	IIC_WaitAck();
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

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); 


void pcf_dac(uchar dat);
uchar pcf_adc();


#endif

=================================//欢迎指正//===============================

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Young__

谢谢打赏^~^

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值