【蓝桥杯单片机】常见考点及其模板

在蓝桥杯单片机比赛中,有几个常用外设,只要将这些外设学会就可以应对比赛。
省赛考点:LED、蜂鸣器、继电器、数码管、独立键盘、矩阵键盘、实时时钟、数模\模数转换、EEPROM储存器、温度传感器、定时计数器、中断等
国赛考点:LED、蜂鸣器、继电器、数码管、独立键盘、矩阵键盘、实时时钟、数模\模数转换、EEPROM储存器、温度传感器、定时计数器、中断、超声波距离传感器、NE555、串口通信(第十届)等

#include "reg52.h"
#include "iic.h"
#include "onewire.h"
#include "ds1302.h"

//矩阵按键
sfr P4 = 0xc0;
sbit R1 = P3^0;
sbit R2 = P3^1;
sbit R3 = P3^2;
sbit R4 = P3^3;
sbit C1 = P4^4;
sbit C2 = P4^2;
sbit C3 = P3^5;
sbit C4 = P3^4;

void scankeys()
{
   R1 = 0;
   R2 = R3 = R4 = 1;
   C1 = C2 = C3 = C4 = 1;
   if (C1 == 0)
   {
     delay(1000);
	 if (C1 == 0)
	 {
	   //添加所需功能
	   while(C1 == 0);
	 }
   }		

   else if (C2 == 0)
   {
     delay(1000);
	 if (C2 == 0)
	 {
	   //添加所需功能
	   while(C2 == 0);
	 }
   }

  else if (C3 == 0)
   {
     delay(1000);
	 if (C3 == 0)
	 {
	   //添加所需功能
	   while(C3 == 0);
	 }
   }

  else if (C4 == 0)
   {
     delay(1000);
	 if (C4 == 0)
	 {
	   //添加所需功能
	   while(C4 == 0);
	 }
   }

   R2 = 0;
   R1 = R3 = R4 = 1;
   C1 = C2 = C3 = C4 = 1;
   if (C1 == 0)
   {
     delay(1000);
	 if (C1 == 0)
	 {
	   //添加所需功能
	   while(C1 == 0);
	 }
   }		

   else if (C2 == 0)
   {
     delay(1000);
	 if (C2 == 0)
	 {
	   //添加所需功能
	   while(C2 == 0);
	 }
   }

  else if (C3 == 0)
   {
     delay(1000);
	 if (C3 == 0)
	 {
	   //添加所需功能
	   while(C3 == 0);
	 }
   }

  else if (C4 == 0)
   {
     delay(1000);
	 if (C4 == 0)
	 {
	   //添加所需功能
	   while(C4 == 0);
	 }
   }

   R3 = 0;
   R1 = R2 = R4 = 1;
   C1 = C2 = C3 = C4 = 1;
   if (C1 == 0)
   {
     delay(1000);
	 if (C1 == 0)
	 {
	   //添加所需功能
	   while(C1 == 0);
	 }
   }		

   else if (C2 == 0)
   {
     delay(1000);
	 if (C2 == 0)
	 {
	   //添加所需功能
	   while(C2 == 0);
	 }
   }

  else if (C3 == 0)
   {
     delay(1000);
	 if (C3 == 0)
	 {
	   //添加所需功能
	   while(C3 == 0);
	 }
   }

  else if (C4 == 0)
   {
     delay(1000);
	 if (C4 == 0)
	 {
	   //添加所需功能
	   while(C4 == 0);
	 }
   }

   R4 = 0;
   R1 = R2 = R3 = 1;
   C1 = C2 = C3 = C4 = 1;
   if (C1 == 0)
   {
     delay(1000);
	 if (C1 == 0)
	 {
	   //添加所需功能
	   while(C1 == 0);
	 }
   }		

   else if (C2 == 0)
   {
     delay(1000);
	 if (C2 == 0)
	 {
	   //添加所需功能
	   while(C2 == 0);
	 }
   }

  else if (C3 == 0)
   {
     delay(1000);
	 if (C3 == 0)
	 {
	   //添加所需功能
	   while(C3 == 0);
	 }
   }

  else if (C4 == 0)
   {
     delay(1000);
	 if (C4 == 0)
	 {
	   //添加所需功能
	   while(C4 == 0);
	 }
   }
}

//数码管
void select_HC573(unsigned char n)
{
  switch(n)
  {
    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 delay(unsigned int t)
{
  while(t--);
}

void display_smg(unsigned char pos,unsigned char value)
{
  select_HC573(7);
  P0 = 0xff;
  select_HC573(6);
  P0 = 0x01 << pos;
  select_HC573(7);
  P0 = value;
}

void closeall()
{
  select_HC573(6);
  P0 = 0xff;
  select_HC573(7);
  P0 = 0xff;
}

//实时时钟
write_1302[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
read_1302[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
timer[7] = {0x00,0x59,0x06};  //秒,分,时,日,月,周,年

void timeconfing()
{
  unsigned char i = 0;
  Write_Ds1302_Byte(0x8e,0x00);
  for (i = 0;i < 3;i ++)
  {
  	Write_Ds1302_Byte(write_1302[i],timer[i]);
  }
  Write_Ds1302_Byte(0x8e,0x80);
}

void time_show()
{
  unsigned char i = 0;
  for (i = 0;i < 3;i ++)
  {
  	timer[i] = Read_Ds1302_Byte(read_1302[i]);
  }
  Write_Ds1302_Byte(0x8e,0x80);	
}

duanma[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void display_1302time()
{
  display_smg(0,duanma[time[2] / 16]);
  delay(300);
  display_smg(1,duanma[time[2] % 16]);
  delay(300);
  display_smg(2,0xff);
  delay(300);
  display_smg(3,duanma[time[1] / 16]);
  delay(300);
  display_smg(4,duanma[time[1] % 16]);
  delay(300);
  display_smg(5,0xff);
  delay(300);
  display_smg(6,duanma[time[1] / 16]);
  delay(300);
  display_smg(7,duanma[time[1] % 16]);
  delay(300);
  closeall();
  delay(300);
}

//BCD码的加减
unsigned char Timeradd(unsigned char dat)
{
	dat = dat + 1;
	switch(dat)
	{
		case 10:
			dat = 16;break;			 //BCD的10
		case 26:
			dat = 32;break;			 //BCD的20
		case 42:
			dat = 48;break;			 //BCD的30
		case 58:
			dat = 64;break;			 //BCD的40
		case 74:
			dat = 80;break;			 //BCD的50
		case 90:
			dat = 96;break;			 //BCD的60
	}
	return dat;
}

unsigned char Timerminus(unsigned char dat)
{
	dat = dat - 1;
	switch(dat)
	{
		case 79:
			dat = 73;break;	   
		case 63:
			dat = 57;break;
		case 47:
			dat = 41;break;
		case 31:
			dat = 25;break;
		case 15:
			dat = 9;break;
		case -1:
			dat = 89;break;		
	}
	return dat;
}

//温度
void read_temperature()
{
  unsigned char LSB,MSB;
  init_ds18b20();
  Write_DS18B20(0xcc);
  Write_DS18B20(0x44);
  delay(10000);

  init_ds18b20();
  Write_DS18B20(0xcc);
  Write_DS18B20(0xbe);
  LSB = Read_DS18B20();
  MSB = Read_DS18B20();
  init_ds18b20();

  temp = 0x0000;
  temp = MSB;
  temp = (temp << 8) | LSB;

  if((temp & 0xf800) == 0x0000)
  {
    temp >>= 4;
	temp *= 10;
	temp += (LSB & 0x0f) * 0.625;   //这个是实际温度的十倍
	//若一直显示不出来可将onewire.c中的延迟时间都增加十倍
  }
}

//PCF8591
void write_8591(unsigned char dat)
{
  IIC_Start();
  IIC_SendByte(0x90); 
  IIC_WaitAck();
  IIC_SendByte(0x40); 
  IIC_WaitAck();
  IIC_SendByte(dat);
  IIC_WaitAck();
  IIC_Stop();
}

void read_8591()
{
  IIC_Start();
  IIC_SendByte(0x90); 
  IIC_WaitAck();
  IIC_SendByte(addr); //只有A/D功能是0x01光敏电阻,0x03电位器;A/D和D/A功能都有则0x41光敏电阻,0x43电位器
  IIC_WaitAck();

  IIC_Start();
  IIC_SendByte(0x91); 
  IIC_WaitAck();
  msg = IIC_RecByte(); 
  IIC_WaitAck();
  IIC_SendAck(0);
  IIC_WaitAck();
  IIC_Stop();
}

//AT24C02
void write_C02(unsigned char addr,unsigned char dat)	  //两次写之间需要延时一下
{
  IIC_Start();
  IIC_SendByte(0xa0); 
  IIC_WaitAck();
  IIC_SendByte(addr); 
  IIC_WaitAck();
  IIC_SendByte(dat);
  IIC_WaitAck();
  IIC_Stop();
}

void read_C02(unsigned char addr)
{
  IIC_Start();
  IIC_SendByte(0xa0); 
  IIC_WaitAck();
  IIC_SendByte(addr); 
  IIC_WaitAck();

  IIC_Start();
  IIC_SendByte(0xa1); 
  IIC_WaitAck();
  msg = IIC_RecByte(); 
  IIC_WaitAck();
  IIC_SendAck(0);
  IIC_WaitAck();
  IIC_Stop();
}

//NE555
void init_time()
{
  TMOD = 0x16;
  TH0 = 0xff;	//八位重装计数
  TL0 = 0xff;
  TH1 = (65535 - 50000) / 256;
  TL1 = (65535 - 50000) % 256; //50ms

  EA = 1;
  ET0 = 1;
  ET1 = 1;
  TR0 = 1;
  TR1 = 1;
}

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

void service_t() interrupt 3
{
  TH1 = (65535 - 50000) / 256;
  TL1 = (65535 - 50000) % 256; //50ms

  count ++;
  if (count == 20)
  {
    f = count_f;  //频率
	count = 0;
	count_f = 0;
  }
}

//超声波
#include "intrins.h"

sbit TX = P1^0;
sbit RX = P1^1;

void delay12()
{
  _nop_();
  _nop_();
  unsigned int i = 33;
  while(--i);
}

void send_wave()
{
  unsigned char i ;
  for(i = 0;i < 8;i ++)
  {
    TX = 1;
    delay12();
    TX = 0;
    delay12();
  }
}

void distance()
{
  unsigned int time = 0;
  TMOD &= 0x0f;
  TL1 = 0x00;
  TH1 = 0x00;

  send_wave();
  TR1 = 1;
  while((RX == 1) | (TF1 == 0));
  TR1 = 1;
  if (TF1 == 0)
  {
    time = TH1;
	time <<= 8;
	time = time | TL1;

	d = ((time /10) *17) + 3;  //单位cm
  }
  else 
  {
    TF1 = 0;
	d = 999;    //超量程
  }

}

//串口通信
sbit AUXR = 0x8e;
void init_uart()
{
  TMOD = 0x21;
  TH1 = 0xfd;
  TL1 = 0xfd;
  TR1 = 1;
  ES = 1;
  EA = 1;

  AUXR = 0x00;
  SCON = 0x50;
}

void servixe_uart()	 interrupt 4
{
  if (RI == 1)
  {
    dat = SBUF;
	RI = 0;
  }
}

void sendbyte(unsigned char dat)
{
  SBUF = dat;
  while(TI == 0);
  TI = 0;
}

void sendstring(unsigned char *str)
{
  while(*str != '\0')
  {
    sendbyte(*str);
	str ++;
  }
}


void main()
{
  while(1)
  {}
}

版权声明:本文为CSDN博主「我只经过」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_46690542/article/details/117573880

生成海报
点赞 0

我只经过

我还没有学会写个人说明!

暂无评论

发表评论

相关推荐