第十三届蓝桥杯全国软件和信息技术专业人才大赛个人赛(电子类)单片机设计与开发科目 程序设计题

文章介绍了作者为蓝桥杯单片机比赛准备的模拟题,主要包括数码管显示代码、独立按键处理、I2C驱动程序以及LED控制。在数码管代码中,实现了不同模式下的数值显示;独立按键代码用于切换模式;I2C驱动用于读取电压数据;LED控制则根据程序状态显示相应指示。此外,文章还展示了部分功能的截图。
摘要由CSDN通过智能技术生成

目录

前言

一、功能描述

二、各模块代码

1.数码管相关代码

2.独立按键代码

3.I2C驱动代码

         4.LED代码

         5.主函数

三.功能展示

总结



前言

  最近准备蓝桥杯单片机比赛,差不多学完了省赛要考的各个模块。因此做了一套省赛模拟题,用来记录一下学习过程。功能应该差不多实现完了,大家仅供参考。第一次发文,不完善的地方大家多多担待。


一、功能描述

如图:

二、各模块代码

1.数码管相关代码

1.SMG.c

#include "regx52.h"

code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x8e,0xc8,0xc1,0xbf};//0-9,熄灭,F,N,U,-;
unsigned int DispBuff[8] = {10,10,10,10,10,10,10,10};
unsigned char dspcom=0; 
extern unsigned char mainmode,submode;
extern unsigned short cnt1;
extern unsigned short T;
extern unsigned short V1,V2;
//锁存器选择
void Select_Y(unsigned char 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;
	 }
}	

void SMG_Scan(void)
{
	  //消影
	  Select_Y(7);
    P0 = 0xff;
	 //送位码
	  Select_Y(6);
	  P0 = 1<<dspcom;
	//送段码
	  Select_Y(7);
	  P0 = tab[DispBuff[dspcom]];
	   
//加小数点
	if(mainmode==2&&dspcom == 5)
		{
		  P0 = tab[DispBuff[dspcom]]&0x7f;
		}
	  if(++dspcom == 8)
			dspcom = 0;	  
}

void SMG_DispUpdate(void)
{
//频率界面
   if(mainmode == 0)
	 {
	  DispBuff[0] = 11; 
		DispBuff[1] = 10; 
		DispBuff[2] = 10; 
		if(cnt1>9999)
		DispBuff[3] = cnt1/10000;
		else DispBuff[3] = 10;
		if(cnt1>999)
		DispBuff[4] = (cnt1/1000)%10;
		else DispBuff[4] = 10;
		if(cnt1>99)
		DispBuff[5] = (cnt1/100)%10;
		else DispBuff[5] = 10;
		if(cnt1>9)
		DispBuff[6] = (cnt1/10)%10;
		else DispBuff[6] = 10;
		if(cnt1>0)
		DispBuff[7] = cnt1%10;
	 }
//周期界面
	  else if(mainmode == 1)
	 {
	  DispBuff[0] = 12; 
		DispBuff[1] = 10; 
		DispBuff[2] = 10; 
		if(T>9999)
		DispBuff[3] = T/10000;
		else DispBuff[3] = 10;
		if(T>999)
		DispBuff[4] = (T/1000)%10;
		else DispBuff[4] = 10;
		if(T>99)
		DispBuff[5] = (T/100)%10;
		else DispBuff[5] = 10;
		if(T>9)
		DispBuff[6] = (T/10)%10;
		else DispBuff[6] = 10;
		if(T>0)
		DispBuff[7] = T%10;
	 }
//电压界面
	 else if(mainmode == 2)
	 {
//通道1
	   if(submode == 0)
		 {
		  DispBuff[0] = 13;
			DispBuff[1] = 14;
			DispBuff[2] = 1;
			DispBuff[3] = 10;
			DispBuff[4] = 10;  
			DispBuff[5] = V1/100;
			DispBuff[6] = V1/10%10; 
			DispBuff[7] = V1%10;
		 }
//通道3
		 else if(submode == 1)
		 {
		  DispBuff[0] = 13;
			DispBuff[1] = 14;
			DispBuff[2] = 3;
			DispBuff[3] = 10;
			DispBuff[4] = 10;
			DispBuff[5] = V2/100;
			DispBuff[6] = V2/10%10; 
			DispBuff[7] = V2%10;
		 }
	 }
}

2.独立按键代码

key.c

#include "regx52.h"
#include "iic.h"
#include "SMG.h"

extern unsigned short V1,V2;
extern unsigned char Vflag,Tflag;
extern unsigned char  keyflag,longkeyflag,shortkeyflag;
extern unsigned char mainmode,submode;
extern unsigned char LEDflag;

void delay(unsigned int xms)		//@12.000MHz
	{
		unsigned char i, j;
		while(xms)
		{		
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	xms--;
		}
		
	}
	

void modechange(void)
{
   mainmode++;
	 if(mainmode>2) mainmode = 0;
}

void submodechange(void)
{
  submode++;
	if(submode>1) submode = 0;
}
void Key_Scan(void)
{
	 static unsigned char cnt = 0;
     if(P3_3 == 0)
		 {
		   delay(20);
			 while(P3_3 == 0)
				 delay(20);
			   modechange();
		 }
		 if(P3_2 == 0)
		 {
		   delay(20);
			 while(P3_2 == 0)
				 delay(20);
			   submodechange();
		 }
		 if(P3_1 == 0)
		 {
		  delay(20);
			while(P3_1 == 0)
			{
			delay(20);
			Vflag = 1;
			}
		 }
		 if(P3_0 == 0)
		 {
		  delay(20);
			while(P3_0 == 0)
			{
				 delay(20);
         keyflag = 1;
				 if(longkeyflag == 1)
				 {
					 LEDflag = 1 - LEDflag ;
				   longkeyflag = 0;
					 cnt++;
					 
					 if(cnt == 2)
					 {
						  LEDflag = 1 - LEDflag;
					    cnt = 0;
					 }
				 }
				 else if( shortkeyflag == 1)
				 {
				   shortkeyflag = 0;
					 Tflag = 1;
				 }
			}
		 }	 
}

3.I2C驱动代码

iic.c

#include "iic.h"
#include "regx52.h"

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

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

//应答位控制
void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	IIC_Delay(10);
	SCL = 1;
	IIC_Delay(10);
	SCL = 0;
	SDA = 1; 
	IIC_Delay(10);
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	IIC_Delay(10);
	SCL = 1;
	IIC_Delay(10);
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		IIC_Delay(10);
		SCL = 1;
		byt <<= 1;
		IIC_Delay(10);
		SCL = 0;
	}
}

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

void Delay1ms()		//@12.000MHz
{
	unsigned char i, j;

	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
}

unsigned char Get_V(unsigned char ain)
{
  unsigned char dat;
  IIC_Start();
	IIC_SendByte(0x90);//写
	IIC_WaitAck();
  IIC_SendByte(ain);
	IIC_WaitAck();
	IIC_Stop();
	//读了丢舍弃一次
	IIC_Start();
	IIC_SendByte(0x91);//读
	IIC_WaitAck();
	//加延时把数据丢完不然要数据异常
	Delay1ms();
  IIC_RecByte();
	IIC_Ack(0);
  IIC_Stop();
	
	IIC_Start();
	IIC_SendByte(0x91);//读
	IIC_WaitAck();	
	dat = IIC_RecByte();
	IIC_Ack(0);
  IIC_Stop();
	return dat;
}
//读取电压
void Read_V(unsigned short *V1,unsigned short*V2)
{
  *V1 = Get_V(1)*(5.0/255)*100;
  *V2 = Get_V(3)*(5.0/255)*100;
}

void AT24C02_WriteByte(unsigned char address,unsigned char dat)
{
	 EA = 0;
   IIC_Start();
	 IIC_SendByte(0Xa0);
   IIC_WaitAck();
	 IIC_SendByte(address);
	 IIC_WaitAck();
	 IIC_SendByte(dat);
	 IIC_WaitAck();
	 IIC_Stop();
	 EA = 1;
	 Delay1ms();
}

unsigned char AT24C02_ReadByte(unsigned address)
{
     unsigned char dat;
	   EA = 0;
     IIC_Start();
	   IIC_SendByte(0Xa0);
     IIC_WaitAck();
	   IIC_SendByte(address);
	   IIC_WaitAck();
	   IIC_Start();
	   IIC_SendByte(0Xa1);
	   IIC_WaitAck();
	   dat = IIC_RecByte();
	   IIC_Ack(0);
     IIC_Stop();
	   EA = 1;
	   return dat;
}
	

 4.LED代码

LED.c

#include <regx52.h>
#include "SMG.h"

extern unsigned char VSET;
extern unsigned short V1,cnt1,FSET;
extern unsigned char LEDflag;
extern unsigned char mainmode;

void LED_Control(void)
{
	 if(LEDflag == 1)
{ 
   Select_Y(4);
	 P0 = 0xff;
	if(V1 > VSET*10)
		P0_0 = 0;
	else 
		P0_0 = 1;
	if(cnt1>FSET)
		P0_1 = 0;
	else 
		P0_1 	= 1;
	if(mainmode == 0)
		P0_2 = 0;
	 else P0_2 = 1;
	if(mainmode == 1)
		P0_3 = 0;
	 else P0_3 = 1;
	if(mainmode == 2)
		P0_4 = 0;
	 else P0_4 = 1;
	
}
else {
	 Select_Y(4);
   P0 = 0xff;
}
}

5.主函数

main.c

#include <regx52.h>
#include "key.h"
#include "SMG.h"
#include "IIC.h"
#include "LED.h"

unsigned char mainmode = 0,submode = 0;
unsigned short cnt = 0,cnt1 = 0;
unsigned short timecnt = 0;
unsigned short T = 0;
unsigned char timeflag1 = 0,timeflag2 = 0,timeflag3 = 0,timeflag4 = 0;
unsigned short V1,V2;
unsigned char VSET = 0; 
unsigned short FSET;
unsigned char Vflag = 0,Tflag = 0;
unsigned short longkeycnt = 0;
unsigned char  keyflag = 0,longkeyflag = 0, shortkeyflag = 0;
unsigned char LEDflag  = 1;

void Init_Timer()
{
  TH0 = 0Xff;
	TL0 = 0xff;
	
	TH1 = (65536-2000)/256;
	TL1 = (65536-2000)%256;
	 
	TMOD = 0x16;
	ET0 = 1;
	ET1 = 1;
	EA  = 1;
	TR0 = 1;
	TR1 = 1;
}

void Init_System(void)
{
  Select_Y(4);
	P0 = 0XFF;
	Select_Y(5);
	P0 = 0X00;
}
void main(void)
{
	Init_System();
	Init_Timer();
	SMG_DispUpdate();
  while(1)
	{
		if(timeflag1 == 1)
		{
		timeflag1 = 0;
		SMG_Scan();
		SMG_DispUpdate();
	  Key_Scan();
		LED_Control();
		}
		if(timeflag2 == 1)
		{
			timeflag2 = 0;
			Read_V(&V1,&V2);
	    SMG_DispUpdate();	
		}
		if(timeflag3 == 1)
		{
			timeflag3 = 0;
		  cnt1 = cnt;
	    cnt = 0;
	    timecnt = 0;
	    T = 1000000/cnt1;
	    SMG_DispUpdate();
		}
		if(timeflag4 == 1)
		{
			timeflag4 = 0;
		  VSET = AT24C02_ReadByte(0x01);
		  FSET = AT24C02_ReadByte(0x02);
			FSET = (FSET<<8) | AT24C02_ReadByte(0x03);
			
		}
		if(Vflag == 1)
		{
		  Vflag = 0;
			AT24C02_WriteByte(0x01,V2/10);
		}
		if(Tflag == 1)
		{
		  Tflag = 0;
			AT24C02_WriteByte(0x02,cnt1/256);
			AT24C02_WriteByte(0x03,cnt1%256);
		}
	}
}


void Timer0() interrupt 1
{
  cnt++;
}

void Timer1() interrupt 3
{
  TH1 = (65536-2000)/256;
	TL1 = (65536-2000)%256;
	timecnt++;
	if(keyflag == 1)
	{
	   keyflag = 0;
		 longkeycnt++;
		 if(longkeycnt>=50)
		 {
		   longkeycnt = 0;
			 longkeyflag = 1;
		 }
		 else 
			shortkeyflag = 1;
	}
  timeflag1 = 1;
	if(timecnt == 5)
	{
	timeflag2 = 1;
	timeflag4 = 1;
	}
	if(timecnt == 500) 
	{
	timecnt = 0;
	timeflag3 = 1;
	}
}

三.功能展示

    这里因为全部功能展示的话,视频太大了因此就发几张图片来展示部分功能。(这里的第六位数码管是坏了的,所以显示有点问题,不过不影响功能)这里的LED1,LED2为什么一直亮着,是因为我的缓存电压和缓存频率默认是0。

1.频率界面

 2.周期界面

 

3. 电压界面

 

 4.LED灯禁用

总结

  第一次发文,不好的地方,希望大家多多见谅。总的来说这套题思路不难,就是在写代码会遇见各种各样的小问题,这个需要花时间解决,不过练多了就会很快。大家加油,有问题也希望大家给我指出来,一起学习。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值