蓝桥杯单片机组--------一个小时省赛二等奖

蓝桥杯单片机组--------一个小时省赛二等奖

蓝桥杯必备资料汇总
各位来看应该都是报了蓝桥杯的,想要获奖的,博主有幸参加过一次,总体来说蓝桥杯单片机比赛对于在大一、大二校生来讲还是一个不错的比赛的,比较基础,对于新手来说比较合适。
当时我参加比赛其实总共也没准备多久,由于疫情的一些原因导致比赛时间比较乱,省赛大概就两个星期左右吧!国赛稍微长点……
废话不多说下面给大伙分享一些我参加比赛的干货,希望对大家有用

题型分析

蓝桥杯单片机组--------一个小时省赛二等奖_第1张图片这张图片相信大家都看过,比较经典,要考什么一目了然,省赛的话LED、数码管、蜂鸣器、独立按键绝对是必考,定时器当然不用说,剩下的主要就是18B20测温、A/D和D/A、1302时钟、24C02存储,每年基本都在这里面调两个一块考,当然第十届是个例外,考的是测频率的,稍微难理解一点。
接下来给大家展示一下我自己准备的模板。学会的画可以省很大一部分时间的哦!

SYS_init.c

这部分可以说那套题都可以用的上,首先系统初始化,关LED、蜂鸣器、继电器……,然后是显示函数,直接在子函数写段选或者位选都可以,最后呢就是每题必有的对单个LED的开关控制,有了LED_on();和LED_shout();两个子函数直接调用就可以了,舒服吧!

#include "main.h"
#include "onewire.h"  //单总线函数库

code unsigned char tab[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xC6,0x8c};

//=====================系统初始化
void all_init()
{
	P2=((P2&0x1f)|0x80);P0=0xFF;P2=P2&0x1f;//关闭LED
	P2=((P2&0x1f)|0xA0);P0=0x00;P2=P2&0x1f;//关闭继电器,蜂鸣器
	P2=((P2&0x1f)|0xC0);P0=0xff;P2=P2&0x1f;//关闭数码管位选
	P2=((P2&0x1f)|0xE0);P0=0xff;P2=P2&0x1f;//关闭数码管段选
}

//=====================500ms延时函数,蜂鸣器间隔响正好
void Delay500ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 22;
	j = 3;
	k = 227;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

//=====================100us延时函数
void delayms(int ms)
{
	int i,j;
	for(i=ms;i>0;i--)
		for(j=845;j>0;j--);
}

void Delay100us()		//@11.0592MHz
{
	unsigned char i, j;

	i = 3;
	j = 82;
	do
	{
		while (--j);
	} while (--i);
}

//=====================数码管显示函数
//=====================段选函数
void Display_1(unsigned char weixuan,unsigned char duanxuan)
{
	switch (weixuan)
       {
       	case 1:P2=((P2&0x1f)|0xC0);P0=0X01;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
       	case 2:P2=((P2&0x1f)|0xC0);P0=0X02;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 3:P2=((P2&0x1f)|0xC0);P0=0X04;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 4:P2=((P2&0x1f)|0xC0);P0=0X08;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 5:P2=((P2&0x1f)|0xC0);P0=0X10;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 6:P2=((P2&0x1f)|0xC0);P0=0X20;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 7:P2=((P2&0x1f)|0xC0);P0=0X40;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
		case 8:P2=((P2&0x1f)|0xC0);P0=0X80;P2=((P2&0x1f)|0xE0);P0=tab[duanxuan];
       		break;
       	default:
       		break;
       }
//      delayms(1);
	Delay100us();
	Delay100us();
	Delay100us();
	Delay100us();
	Delay100us();
}

//=====================单独打开LED,蜂鸣器,继电器
void LED_on(unsigned char num)
{
	switch (num)
       {
       	case 1:P2=((P2&0x1f)|0x80);P0=0xFE;P2=P2&0x1f;//打开LED1
       		break;
		case 2:P2=((P2&0x1f)|0x80);P0=0xFD;P2=P2&0x1f;//打开LED2
       		break;
		case 3:P2=((P2&0x1f)|0x80);P0=0xFB;P2=P2&0x1f;//打开LED3
       		break;
		case 4:P2=((P2&0x1f)|0x80);P0=0xF7;P2=P2&0x1f;//打开LED4
       		break;
		case 5:P2=((P2&0x1f)|0x80);P0=0xEF;P2=P2&0x1f;//打开LED5
       		break;
		case 6:P2=((P2&0x1f)|0x80);P0=0xDF;P2=P2&0x1f;//打开LED6
       		break;
       	case 7:P2=((P2&0x1f)|0x80);P0=0xBF;P2=P2&0x1f;//打开LED7
       		break;
		case 8:P2=((P2&0x1f)|0x80);P0=0x7F;P2=P2&0x1f;//打开LED8
       		break;
		case 9:P2=((P2&0x1f)|0xA0);P0|=0x40;P2=P2&0x1f;//打开蜂鸣器
       		break;
		case 10:P2=((P2&0x1f)|0xA0);P0|=0x10;P2=P2&0x1f;//打开继电器
       		break;
       	default:
       		break;
       }	
}

//=====================单独关闭LED,蜂鸣器,继电器
void LED_shut(unsigned char num)
{
	switch (num)
       {
       	case 1:P2=((P2&0x1f)|0x80);P0=P0|0x01;P2=P2&0x1f;//关闭LED1
       		break;
		case 2:P2=((P2&0x1f)|0x80);P0=P0|0x02;P2=P2&0x1f;//关闭LED2
       		break;
		case 3:P2=((P2&0x1f)|0x80);P0=P0|0x04;P2=P2&0x1f;//关闭LED3
       		break;
		case 4:P2=((P2&0x1f)|0x80);P0=P0|0x08;P2=P2&0x1f;//关闭LED4
       		break;
		case 5:P2=((P2&0x1f)|0x80);P0=P0|0x10;P2=P2&0x1f;//关闭LED5
       		break;
		case 6:P2=((P2&0x1f)|0x80);P0=P0|0x20;P2=P2&0x1f;//关闭LED6
       		break;
       	case 7:P2=((P2&0x1f)|0x80);P0=P0|0x40;P2=P2&0x1f;//关闭LED7
       		break;
		case 8:P2=((P2&0x1f)|0x80);P0=P0|0x80;P2=P2&0x1f;//关闭LED8
       		break;
		case 9:P2=((P2&0x1f)|0xA0);P0&=0xBF;P2=P2&0x1f;//关闭蜂鸣器
       		break;
		case 10:P2=((P2&0x1f)|0xA0);P0&=0xEF;P2=P2&0x1f;//关闭继电器
			break;
       	default:
       		break;
       }	
}

onewire.c

#include "main.h"
#include "onewire.h"  //单总线函数库

sbit DQ = P1^4;

int wendu;
bit temper_flag;

//************************************

//************************************

//单总线延时函数
//#ifndef STC12  
//void Delay_OneWire(unsigned int t)  //STC89C52RC
//{
//	while(t--);
//}
//#else
void Delay_OneWire(unsigned int t)  //STC12C5260S2
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}
//#endif

//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		DQ = 0;
		DQ = dat&0x01;
		Delay_OneWire(5);
		DQ = 1;
		dat >>= 1;
	}
	Delay_OneWire(5);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20初始化
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80); // 延时大于480us
  	DQ = 1;
  	Delay_OneWire(10);  // 14
  	initflag = DQ;     // initflag等于1初始化失败
  	Delay_OneWire(5);
  
  	return initflag;
}

//DS18B20温度采集程序:整数
unsigned char rd_temperature(void)
{
	unsigned char low,high;
  	char temp;
  
  	init_ds18b20();
  	Write_DS18B20(0xCC);
  	Write_DS18B20(0x44); //启动温度转换
  	Delay_OneWire(200);

  	init_ds18b20();
  	Write_DS18B20(0xCC);
  	Write_DS18B20(0xBE); //读取寄存器

  	low = Read_DS18B20(); //低字节
  	high = Read_DS18B20(); //高字节
  
  	temp = high<<4;
  	temp |= (low>>4);
  
  	return temp;
}


DS18B20温度采集程序:浮点数
//float rd_temperature(void)
//{
//    unsigned int temp;
//	float temperature;
//    unsigned char low,high;
//  
//  	init_ds18b20();
//  	Write_DS18B20(0xCC);
//  	Write_DS18B20(0x44); //启动温度转换
//  	Delay_OneWire(200);

//  	init_ds18b20();
//  	Write_DS18B20(0xCC);
//  	Write_DS18B20(0xBE); //读取寄存器

//  	low = Read_DS18B20(); //低字节
//  	high = Read_DS18B20(); //高字节
///** 精度为0.0625摄氏度 */  
//	temp = (high&0x0f);
//	temp <<= 8;
//	temp |= low;
//	temperature = temp*0.0625;

//  	return temperature;
//}


DS18B20温度采集程序:浮点数
//float rd_temperature(void)
//{
//	float tp;  				//单精度
//	unsigned int temp;
//	float temperature;
//	unsigned char low,high;
//  
//  	init_ds18b20();
//  	Write_DS18B20(0xCC);
//  	Write_DS18B20(0x44); //启动温度转换
//  	Delay_OneWire(200);

//  	init_ds18b20();
//  	Write_DS18B20(0xCC);
//  	Write_DS18B20(0xBE); //读取寄存器

//  	low = Read_DS18B20(); //低字节
//  	high = Read_DS18B20(); //高字节
///** 精度为0.0625摄氏度 */  
//	temp = high;
//	temp <<= 8;
//	temp |= low;
//	
//	if(temp< 0)				//当温度值为负数
//  	{
//		//因为读取的温度是实际温度的补码,所以减1,再取反求出原码
//		temp=temp-1;
//		temp=~temp;
//		tp=temp;
//		temperature=tp*0.0625*100+0.5;	
//		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//		//算加上0.5,还是在小数点后面。
// 
//  	}
// 	else
//  	{			
//		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
//		//如果温度是正的那么,那么正数的原码就是补码它本身
//		temperature=tp*0.0625*100+0.5;	
//		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
//		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
//		//算加上0.5,还是在小数点后面。
//	}
//	
//  
//  
//  	return temperature;
//}

onewire.h

#define _ONEWIRE_H

#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe

//函数声明
//unsigned char rd_temperature(void);

//onewire.c

extern int wendu;
extern bit temper_flag;

//code unsigned char tab[13] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xC6,0x8c};



extern void WenDu_display();
extern void Delay_OneWire(unsigned int t);	//单总线延时函数
extern void Write_DS18B20(unsigned char dat);	//通过单总线向DS18B20写一个字节
extern unsigned char Read_DS18B20(void);		//从DS18B20读取一个字节
extern bit init_ds18b20(void);			//DS18B20初始化
extern unsigned char rd_temperature(void);	//DS18B20温度采集程序:整数
//extern float rd_temperature(void);			//DS18B20温度采集程序:
#endif

main.c

#include "main.h"
#include "onewire.h"  //单总线函数库

int intr = 0;
int frequency = 0;
unsigned int temperature;

void Timer0Init(void);

void main()
{
	rd_temperature(); //先读取一次温度但不显示,消除温度寄存器原来存在的+85
	rd_temperature();
	
	all_init();
	Timer0Init();
	
	while(1)
	{
		Display_1(7,wendu % 100 / 10);
		Display_1(8,wendu % 10);
	}	
}

void Timer0Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0x20;		//设置定时初值
	TH0 = 0xD1;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}

//定时器中断服务函数
void isr_timer_0(void)  interrupt 1  //默认中断优先级 1
{
	if(++intr == 100)  	//0.3s内执行一次
	{
		intr = 0;
		wendu = rd_temperature();  //读温度   
	}
}

main.h

#include 
#include "intrins.h"

//=====================SYS_init.c
//0-9,空,C,P


extern void all_init();
extern void display(void);
extern void all_init();
extern void delayms(int ms);

extern void Display_1(unsigned char weixuan,unsigned char duanxuan);

extern void LED_on(unsigned char num);
extern void LED_shut(unsigned char num);


总体来说呢,这套模板比较适合底子比较薄的小伙伴们,如果小伙伴客观题能答对七八个,再加上这套程序拿个省二应该没啥问题。但是想进国赛的话最好多练几套题,省赛、国赛的都练一下。
后续我也会把我比赛的资料,题目……整理好发出来,小伙伴们记得时时关注哦!

你可能感兴趣的:(串口通信,c语言,经验分享)