14届蓝桥杯单片机模拟赛试题以及代码完整实现

        之前没有关注这个模拟赛,现在发现了顺手练习以下,还有2天就要开始比赛了,希望大家好好发挥

main函数以及各种定义

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

typedef unsigned char u8;
typedef unsigned int u16;

#define U ~0x3e
#define DELAY_TIME 20  //iic延时
#define SlaveAddrW 0x90  //pcf8591 写读地址
#define SlaveAddrR 0x91

sbit led1=P0^0;    //led蜂鸣器继电器引脚声明
sbit led2=P0^1; 
sbit led3=P0^2;
sbit beep=P0^6;
sbit relay=P0^4;
sbit DQ = P1^4;  //单总线接口
//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void dis_page();          //页面显示函数
void sys_init();		  //系统初始化函数
void led_kz();			  //led控制函数
void relay_beep_kz();	  //继电器蜂鸣器控制函数
void send_string(u8 *x);  //串口发送字符串函数
void key_set();			  //按键改变状态函数
void UartInit(void);	  //串口初始化,波特率9600
void send_char(u8 x);	  //串口发送字符
float get_tmp();		  //ds18b20获取温度
float ad_read_rb2(u8 addr); //读取ad值

//u8 putchar(u8 x);

const u8 smg_code[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x7f};

u16 tmp_dis=275;		//显示的温度变量
u16 ad_dis=135;			//显示的ad变量
u8 key_flag=0;			//按键松开标志,松开为0按下不松开为1
u8 page=0;				//页面号
u8 led3_flag=0;			//led3闪烁标志,没写
u8 flag=0;				//按键锁定标志,s4按下为1,s5按下为0
u8 read_buff;			//串口读取的数据



void main()
{
	sys_init();         //系统初始化
	UartInit();    		//串口初始化
	while(1)
	{
		ad_dis=ad_read_rb2(0x03)*100;    //读取ad值
		tmp_dis=get_tmp()*10;			//读取温度值
		key_set();						//按键扫描改变
		dis_page();						//显示页面
		led_kz();						//led控制
		relay_beep_kz();				//蜂鸣器继电器控制
	}
}

 系统初始化以及数码管显示函数

void h138(u8 x)
{
	switch(x)
	{
		case 1:{P2=P2&0X1F|0X80;break;} //LED
		case 2:{P2=P2&0X1F|0Xa0;break;}	//RELAY
		case 3:{P2=P2&0X1F|0XC0;break;} //SMG_W
		case 4:{P2=P2&0X1F|0XE0;break;} //SMG_D
	}
}

void sys_init()
{
	h138(1);
	P0=0XFF;
	h138(2);
	relay=0;
	beep=0;
}

void delay(u16 x)
{
	while(x--);
}

void smg_dis_one(u8 x,u8 dat)
{
	h138(3);
	P0=0x01<<x;
	delay(5);
	h138(4);
	P0=dat;
	delay(200);
	P0=0XFF;
}

void smg_dis_all(u8 d0,u8 d1,u8 d2,u8 d3,u8 d4,u8 d5,u8 d6,u8 d7)
{
	smg_dis_one(0,d0);
	smg_dis_one(1,d1);
	smg_dis_one(2,d2);
	smg_dis_one(3,d3);
	smg_dis_one(4,d4);
	smg_dis_one(5,d5);
	smg_dis_one(6,d6);
	smg_dis_one(7,d7);
}

void dis_page()
{
	if(page==0)
	{
		smg_dis_all(U,smg_code[1],0xff,0xff,0xff,smg_code[tmp_dis/100],smg_code[tmp_dis%100/10]&0x7f,smg_code[tmp_dis%10]);
	}
	if(page==1)
	{
		smg_dis_all(U,smg_code[2],0xff,0xff,0xff,smg_code[ad_dis/100]&0x7f,smg_code[ad_dis%100/10],smg_code[ad_dis%10]);
	}
}

按键扫描函数和按键控制函数

u8 key_scan()
{
	u8 key,h,l;
	P44=1;P42=1;P3=0XF0;
	if(P44==0||P42==0||P3!=0XF0&&key_flag==0)
	{
		if(P44==0) l=1;
		if(P42==0) l=2;
		if(P35==0) l=3;
		if(P34==0) l=4;
	}
	P44=0;P42=0;P3=0X0F;
	if(P3!=0X0F&&key_flag==0)
	{
		key_flag=1;
		if(P30==0) h=4; 
		if(P31==0) h=3; 
		if(P32==0) h=2; 
		if(P33==0) h=1; 
	}
	key = l*4+h-1;
	while(P3!=0X0F)
	{
		return key;
	}
	key_flag=0;
	return 0;
}


void key_set()
{
	u8 key;
	key=key_scan();
	if(key==4) flag=1;
	if(flag==1){
		if(key==5) flag=0;
	}
	if(key==12){
		if(page==0) printf("TEMP:%.1fC\n",tmp_dis/10.0);
		if(page==1) printf("Voltage:%.2fV\n",ad_dis/100.0);
	}
}

继电器蜂鸣器和led控制函数

void led_kz()
{
	h138(1);
	if(page==0) led1=0;
	else led1=1;
	if(page==1) led2=0;
	else led2=1;
	if(flag) led3=0;
	else led3=1;
}

void relay_beep_kz()
{
	h138(2);
	if(tmp_dis>=280) relay=1;
	else relay=0;
	if(ad_dis>360) beep=1;
	else beep=0;
}

串口配置使用

void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x40;		//定时器时钟1T模式
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0xC7;			//设置定时初始值
	TH1 = 0xFE;			//设置定时初始值
	ET1 = 0;			//禁止定时器中断
	TR1 = 1;			//定时器1开始计时
	EA=1;
	ES=1;
	REN=1;
}

void uart() interrupt 4 using 1
{
	if(RI)
	{
		read_buff=SBUF;
		RI=0;
		if(flag==0){
			if(read_buff=='A') page=0;
			if(read_buff=='B') page=1;
		}
		
	}
}


void send_char(u8 x)
{
	SBUF=x;
	while(!TI);
	TI=0;
}

//void send_string(u8 *x)
//{
//	u8 i=0;
//	while(*(x+i)!='\0')
//	{
//		send_char(*(x+i));
//		i++;
//	}
//}

/*
**重写printf调用的putchar函数,重定向到串口输出
**需要引入头文件<stdio.h>
*****/
char putchar(char c){
	//输出重定向到串口
	send_char(c);
	return c;  //返回给函数的调用者printf
}

还有两个模块获取数据这里就不贴出了,祝大家都能取得好成绩。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值