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

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

个人编写,代码仅供参考

如有不足,多多指教

1.题目

 2.代码 

main.c程序

#include "reg52.h"
#include "iic.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,0x8c,0xc8,0xc6,0x88};
//                    0    1    2    3    4    5    6     7   8    9    -   mie		U    F    0.   1.    2.  3.   4.   5.   6.   7.   8.   9.   p    n    C    A

sfr AUXR = 0X8E; 
sbit s4 = P3^3;
sbit s5 = P3^2;
sbit s6 = P3^1;
sbit s7 = P3^0;

uchar xianshi = 0;//0  频率显示   1  周期显示   2  电压界面
uchar channel = 3;//1   通道一(光敏电阻)   3  通道二(电位器)
	
float vol_3 = 0.00;//通道三采集的电压
float vol_1 = 0.00;//通道一采集的电压
float vol_3_temp = 0.00;//缓存通道三采集的电压

uint freq = 0;//频率
uint freq_temp = 0;//缓存频率
uchar count_dinshi = 0;//定时
uint count_f = 0;//计数

uint period = 0;
#define period 1000000/freq

uchar s7_press = 0;//s7按下为1  短按为3  长按为2
uchar key_count = 0;//用于s7按下时长计时

uchar led_flag = 1;//led开1    led关0
//=============================函数声明
void select(uchar channel);
void cls_relay_buz_led_smg();
void key_scan();
void smg_delay(uint time);
void smg_dis(uchar pos,uchar val);
void smg_dis_all(uchar val);
void smg_show();
void led_show();
void Init_Timer();
//=============================主函数
void main()
{
	cls_relay_buz_led_smg();
	Init_Timer();
	while(freq == 0);//防止频率还没测量好(数码管没显示),led已经显示一部分
	while(1)
	{
		if(channel == 1)
		{
			vol_1 = (float)read_pcf_ain1()*5/255;
		}
		else if(channel == 3)
		{
		vol_3 = (float)read_pcf_ain3()*5/255;
		}																			//放一个函数同时采集,好像有点冲突问题,故想办法分开采集
		key_scan();
		smg_show();
		led_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 cls_relay_buz_led_smg()
{
	select(4);
	P0 = 0XFF;
	select(5);
	P0 &= 0xaf;
	select(0);
	P0 = 0XFF;
	select(6);
	P0 = 0XFF;
	select(7);
	P0 = 0xff;
	select(0);
}
//=============================按键扫描函数
void key_scan()
{
	if(s4 == 0)
	{
		smg_show();
		if(s4 == 0)
		{
			while(s4 == 0)
			{
				smg_show();
			}
			switch(xianshi)
			{
				case 0 : xianshi = 1;break;
				case 1 : channel = 1;xianshi = 2;break;
				case 2 : xianshi = 0;break;
			}
		}
	}
	if(s5 == 0)
	{
		smg_show();
		if(s5 == 0)
		{
			while(s5 == 0)
			{
				smg_show();
			}
			if(xianshi == 2)
			{
				switch(channel)
				{
					case 1 : channel = 3;break;
					case 3 : channel = 1;break;
				}
			}
		}
	}
	if(s6 == 0)
	{
		smg_show();
		if(s6 == 0)
		{
			while(s6 == 0)
			{
				smg_show();
			}
			vol_3 = (float)read_pcf_ain3()*5/255;
			vol_3_temp = vol_3;
		}
	}
	if(s7 == 0)
	{
		smg_show();
		if(s7 == 0)
		{
			while(s7 == 0)
			{
				smg_show();
			}
			switch(s7_press)
			{
				case 2 : if(led_flag == 0){led_flag = 1;}else{led_flag = 0;}s7_press = 0; key_count = 0;break;
				case 3 : freq_temp = freq; s7_press = 0; key_count = 0;break;
			}
		}
	}
}
//===================================数码管函数
void smg_delay(uint time)
{
	while(time--);
}

void smg_dis(uchar pos,uchar val)
{
	select(7);
	P0 = 0XFF;
	select(6);
	P0 = 0x01 << pos;
	select(7);
	P0 = smg[val];
	select(0);
	smg_delay(500);
}

void smg_dis_all(uchar val)
{
	select(7);
	P0 = 0XFF;
	select(6);
	P0 = 0xff;
	select(7);
	P0 = smg[val];
	select(0);
	smg_delay(500);
}

void smg_show()
{
	if(xianshi == 0)
	{
		if(freq >= 1000000)
		{
		smg_dis(0,13);
		smg_dis(1,freq/1000000);
		smg_dis(2,freq/100000%10);
		smg_dis(3,freq/10000%10);
		smg_dis(4,freq/1000%10);
		smg_dis(5,freq/100%10);
		smg_dis(6,freq/10%10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 100000)
		{
		smg_dis(0,13);
		smg_dis(1,11);
		smg_dis(2,freq/100000);
		smg_dis(3,freq/10000%10);
		smg_dis(4,freq/1000%10);
		smg_dis(5,freq/100%10);
		smg_dis(6,freq/10%10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 10000)
		{
		smg_dis(0,13);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,freq/10000);
		smg_dis(4,freq/1000%10);
		smg_dis(5,freq/100%10);
		smg_dis(6,freq/10%10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 1000)
		{
		smg_dis(0,13);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,11);
		smg_dis(4,freq/1000);
		smg_dis(5,freq/100%10);
		smg_dis(6,freq/10%10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 100)
		{
		smg_dis(0,13);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,11);
		smg_dis(4,11);
		smg_dis(5,freq/100);
		smg_dis(6,freq/10%10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 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,freq/10);
		smg_dis(7,freq%10);
		smg_dis_all(11);
		}
		else if(freq >= 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,freq);
		smg_dis_all(11);
		}
	}
	else if(xianshi == 1)
	{
		if(period >= 1000000)
		{
		smg_dis(0,25);
		smg_dis(1,period/1000000);
		smg_dis(2,period/100000%10);
		smg_dis(3,period/10000%10);
		smg_dis(4,period/1000%10);
		smg_dis(5,period/100%10);
		smg_dis(6,period/10%10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 100000)
		{
		smg_dis(0,25);
		smg_dis(1,11);
		smg_dis(2,period/100000);
		smg_dis(3,period/10000%10);
		smg_dis(4,period/1000%10);
		smg_dis(5,period/100%10);
		smg_dis(6,period/10%10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 10000)
		{
		smg_dis(0,25);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,period/10000);
		smg_dis(4,period/1000%10);
		smg_dis(5,period/100%10);
		smg_dis(6,period/10%10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 1000)
		{
		smg_dis(0,25);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,11);
		smg_dis(4,period/1000);
		smg_dis(5,period/100%10);
		smg_dis(6,period/10%10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 100)
		{
		smg_dis(0,25);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,11);
		smg_dis(4,11);
		smg_dis(5,period/100);
		smg_dis(6,period/10%10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 10)
		{
		smg_dis(0,25);
		smg_dis(1,11);
		smg_dis(2,11);
		smg_dis(3,11);
		smg_dis(4,11);
		smg_dis(5,11);
		smg_dis(6,period/10);
		smg_dis(7,period%10);
		smg_dis_all(11);
		}
		else if(period >= 1)
		{
		smg_dis(0,25);
		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,period);
		smg_dis_all(11);
		}
	}
	else if(xianshi == 2)
	{
		if(channel == 1)
		{
//		vol_1 = (float)read_pcf_ain1()*5/255;
		smg_dis(0,12);
		smg_dis(1,10);
		smg_dis(2,channel);
		smg_dis(3,11);
		smg_dis(4,11);
		smg_dis(5,(uint)(vol_1*100)/100+14);
		smg_dis(6,(uint)(vol_1*100)/10%10);
		smg_dis(7,(uint)(vol_1*100)%10);
		smg_dis_all(11);
		}
		else if(channel == 3)
		{
//		vol_3 = (float)read_pcf_ain3()*5/255;
		smg_dis(0,12);
		smg_dis(1,10);
		smg_dis(2,channel);
		smg_dis(3,11);
		smg_dis(4,11);
		smg_dis(5,(uint)(vol_3*100)/100+14);
		smg_dis(6,(uint)(vol_3*100)/10%10);
		smg_dis(7,(uint)(vol_3*100)%10);
		smg_dis_all(11);
		}
	}
}
//=========================计数器0,定时器1     获取频率为  freq
void Init_Timer()
{
	TH0 = 0xff;        
	TL0 = 0xff;
	
	TH1 = 0X3C;
	TL1 = 0XB0;

	TMOD = 0x04;     //定时器1用十六位自动重载,定时,50ms;定时器0用十六位自动重载,计数,1us;
	
  ET0 = 1;
  ET1 = 1;
	EA = 1;
	
	TR0 = 1;
	TR1 = 1;
}

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

void ser_timer() interrupt 3
{
	if(s7 == 0)
	{
		key_count++;
		if(key_count >= 20)
		{
			s7_press = 2;
		}
		else
		{
			s7_press = 3;
		}
	}
	count_dinshi++;
	if(count_dinshi == 20)
	{
		freq = count_f;
		count_dinshi = 0;
		count_f = 0;
	}
}
//=========================================LED函数
void led_show()
{
	if(led_flag == 1)
	{
		if(vol_3 > vol_3_temp)
		{
			select(4);
			P0 = P0 & 0XFE;
			select(0);
		}
		else
		{
			select(4);
			P0 = P0 | 0x01;
			select(0);
		}
		if(freq > freq_temp)
		{
			select(4);
			P0 = P0 & 0xfd;
			select(0);
		}
		else
		{
			select(4);
			P0 = P0 | 0x02;
			select(0);
		}
		if(xianshi == 0)
		{
			select(4);
			P0 = (P0 & 0xfb) | 0x18;
			select(0);
		}
		else if(xianshi == 1)
		{
			select(4);
			P0 = (P0 & 0xf7) | 0x14;
			select(0);
		}
		else if(xianshi == 2)
		{
			select(4);
			P0 = (P0 & 0xef) | 0x0c;
			select(0);
		}
	}
	else if(led_flag == 0)
	{
		select(4);
		P0 = 0xff;
		select(0);
	}
}

iic.c程序

#include "iic.h"

#define DELAY_TIME 5

//I2C总线内部延时函数
void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}

//I2C总线启动信号
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//I2C总线停止信号
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;  					
    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;    
}
//======================================pcf读取函数
uchar read_pcf_ain3()//resistor
{
	
	uchar ain3;

	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x03);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	ain3 = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();

	return ain3;
}

uchar read_pcf_ain1()//light resisitor
{
	
	uchar ain1;

	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(0x01);
	IIC_WaitAck();
	IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	ain1 = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();

	return ain1;
}

iic.h程序

#ifndef _IIC_H
#define _IIC_H

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

sbit SDA = P2^1;
sbit SCL = P2^0;

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

uchar read_pcf_ain3();//resistor
uchar read_pcf_ain1();//light resisitor

#endif

有个小疑问?

为什么PCF8591读取电位器电压和光敏电阻电压函数放一起执行,读出的电压两个相反或者两个都是电位器电压?

希望大佬解答!!!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

__Young__

谢谢打赏^~^

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

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

打赏作者

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

抵扣说明:

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

余额充值