【蓝桥杯单片机】第十四届模拟赛II

如需代码,请自行提取:

链接:https://pan.quark.cn/s/47819f80b290
提取码:feWn

bbda4b96720a4b81b5aa45bae69c4060.jpg

db842822340a4047904be0c2dcc4ee43.jpg

87c27c16baaf42ce86bab70e039b87d7.jpg

d9c2ea0764fe44089d959783b990a5f5.jpg

main.c 

#include <REGX52.H>
#include <stdio.H>
#include <iic.H>
#include <onewire.H>
#include <intrins.H>

#define u8 unsigned char
#define u16 unsigned int
#define LED(X) {hc573(0); P0 = X; hc573(4); hc573(0);}
#define BUZ(X) {hc573(0); P0 = X; hc573(5); hc573(0);}
#define COM(X) {hc573(0); P0 = X; hc573(6); hc573(0);}
#define SMG(X) {hc573(0); P0 = X; hc573(7); hc573(0);}

sfr P4 = 0xc0;
sfr AUXR = 0x8e;
sbit R1 = P3^5;
sbit R2 = P4^4;
sbit C1 = P3^2;
sbit C2 = P3^3;
code u8 Seg_Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1};//10:熄灭 11:U
u8 tab[8]={10},flag_smg,flag_key,keyvalue,keystatus;
u16 temp,U,flag_collect;
u8 ui,PC,PC1,flag_led,flag_L3,flag,flag_BUZ;
bit flag_dsp;
float UART_U,UART_TEMP;
u8 led=0xff,dot;
//==========================函数声明区====================
void hc573(u8 channel);
void Timer0_Init(void);		//1毫秒@12.000MHz
void display();
void Nixie(u8 loc,num);
void Set_tab();
void InitSys();
void Collect();
void KeyScan();
void UartInit(void);
void taskKey();
void SendByte(float date);
void SendString(u8 *s);
//========================================================

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

	_nop_();
	_nop_();
	i = 39;
	j = 195;
	k = 2;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void hc573(u8 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 Timer0_Isr(void) interrupt 1
{
	display();
	if(flag_smg<20) flag_smg++;
	if(flag_key<20) flag_key++;
	if(flag_collect<200) flag_collect++;
	if(flag_led<20) flag_led++;
	if(flag_L3<100) flag_L3++;
	if(flag_BUZ<100) flag_BUZ++;
}
void Timer0_Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;			//设置定时器模式
	TL0 = 0x18;				//设置定时初始值
	TH0 = 0xFC;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	ET0 = 1;				//使能定时器0中断
	EA = 1;
}
void display()
{
	static u8 i;
	SMG(0xff);
	COM(0x01<<i);
	if((i+1)!=dot)	{SMG(Seg_Table[tab[i]]);}
	else SMG(Seg_Table[tab[i]]&0x7f);
	i = (i+1)%8;
}

void Set_tab()
{
	if(flag_smg<20) return;
	flag_smg = 0;
	switch(ui)
	{
		case 0:
			dot = 7;
			tab[0] =  11;
			tab[1] =  1;
			tab[2] =  10;
			tab[3] =  10;
			tab[4] =  10;
			tab[5] =  temp/100;
			tab[6] =  temp%100/10;
			tab[7] =  temp%10;
		break;
		case 1:
			dot = 6;
			tab[0] =  11;
			tab[1] =  2;
			tab[2] =  10;
			tab[3] =  10;
			tab[4] =  10;
			tab[5] =  U/100;
			tab[6] =  U%100/10;
			tab[7] =  U%10;
	}
}

void Collect()
{
	if(flag_collect<200) return;
	flag_collect = 0;
	U = PCF_Read();
	temp = Read_temp();
	
}
void KeyScan()
{
	if(flag_key<20) return;
	flag_key = 0;
	switch(keystatus)
	{
		case 0:
		R2 = 0;C1 = C2 = R1 = 1;
		if(C1 == 0||C2 == 0) //S4或者S5按下
		{
			keystatus = 1;
			break;
		}
		R1 = 0;C1 = C2 = R2 = 1;
		if(C2 == 0) //S12按下
		{
			keystatus = 2;
			break;
		}
		break;
		
		case 1:
		if(C1 == 0) keyvalue = 5;
		if(C2 == 0) keyvalue = 4;
		keystatus = 3;
		break;
		
		case 2:
		if(C2 == 0) keyvalue = 12;
		keystatus = 3;
		break;
		
		case 3:
			if(C1 == 1&&C2 == 1) keystatus = 0;
		break;
	}
}
void taskKey()
{
	switch(keyvalue)
	{
		case 4: if(flag == 0) flag = 1 ; //串口通信关闭
		led|=0x04;
		keyvalue = 0; break;
		case 5: if(flag == 1) flag = 0; //串口通信解锁
		led|=0x04; LED(led);
		keyvalue = 0; break;
		case 12: 
			ES = 0;
			if(flag_dsp == 1)
			{
				UART_U = ((float)U)/100;
				printf("Voltage:%.2f",UART_U);
			}
			if(flag_dsp == 0)
			{
				UART_TEMP = ((float)temp)/10;
				printf("TEMP:%.1fV",UART_TEMP);
			}
		keyvalue = 0; ES = 1;break;
		default :keyvalue = 0; break;
	}
}
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;
}

void SendByte(float date)
{
	
	SBUF = date;
	while(TI == 0);
	TI = 0;
}

char putchar(char c)
{
	SendByte(c);
	return c;
}
void UART() interrupt 4
{
	if(RI==1&&flag==0)
	{
		RI = 0;
		PC = SBUF;
		if(PC =='A') 
		{
			ui = 0;
			flag_dsp = 0;  //温度显示界面
		}
		if(PC =='B')
		{
			ui = 1;
			flag_dsp = 1;  //电压显示界面
		}
	}
	else 
	{
		PC1= SBUF;
		RI = 0;
	}
}

void LED_control()
{
	if(flag_led<20) return;
	flag_led = 0;
	if(flag_dsp == 0) led&=~0x01;
	else led |= 0x01;
	if(flag_dsp == 1) led&=~0x02;
	else led |= 0x02;
	LED(led);
}
void LED_L3()
{
	if(flag == 1)
	{
		if(flag_L3 < 100) return;
		flag_L3 = 0;
		led^=0x04;
		LED(led);
	}
		

}
void InitSys()
{
	BUZ(0x00);
	LED(0xff);
}
void BUZ_C()
{
	static buz = 0x00;
	if(flag_BUZ < 100) return;
	flag_BUZ = 0;
	
	if(temp/10>=28) buz |= 0x10; 
	else buz &=~0x10;
	if(U/10>=36&&U%10!=0&&flag==0) buz |= 0x40; 
	else buz &=~0x40;
	BUZ(buz);
}
void main()
{
	temp = Read_temp();
	Delay850ms();
  temp = Read_temp();
	InitSys();
	UartInit();
	Timer0_Init();
	while(1)
	{
		Set_tab();
		Collect();
		KeyScan();
		taskKey();
		LED_control();
		LED_L3();
		BUZ_C();
	}
}

iic.c

/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
#include <intrins.H>

#define DELAY_TIME	5
sbit scl = P2^0;
sbit sda = P2^1;
//
static void I2C_Delay(unsigned char n)
{
    do
    {
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();_nop_();		
    }
    while(n--);      	
}

//
void I2CStart(void)
{
    sda = 1;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 0;
	I2C_Delay(DELAY_TIME);
    scl = 0;    
}

//
void I2CStop(void)
{
    sda = 0;
    scl = 1;
	I2C_Delay(DELAY_TIME);
    sda = 1;
	I2C_Delay(DELAY_TIME);
}

//
void I2CSendByte(unsigned char byt)
{
    unsigned char i;
	
    for(i=0; i<8; i++){
        scl = 0;
		I2C_Delay(DELAY_TIME);
        if(byt & 0x80){
            sda = 1;
        }
        else{
            sda = 0;
        }
		I2C_Delay(DELAY_TIME);
        scl = 1;
        byt <<= 1;
		I2C_Delay(DELAY_TIME);
    }
	
    scl = 0;  
}

//
unsigned char I2CReceiveByte(void)
{
	unsigned char da;
	unsigned char i;
	for(i=0;i<8;i++){   
		scl = 1;
		I2C_Delay(DELAY_TIME);
		da <<= 1;
		if(sda) 
			da |= 0x01;
		scl = 0;
		I2C_Delay(DELAY_TIME);
	}
	return da;    
}

//
unsigned char I2CWaitAck(void)
{
	unsigned char ackbit;
	
    scl = 1;
	I2C_Delay(DELAY_TIME);
    ackbit = sda; 
    scl = 0;
	I2C_Delay(DELAY_TIME);
	
	return ackbit;
}

//
void I2CSendAck(unsigned char ackbit)
{
    scl = 0;
    sda = ackbit; 
	I2C_Delay(DELAY_TIME);
    scl = 1;
	I2C_Delay(DELAY_TIME);
    scl = 0; 
	sda = 1;
	I2C_Delay(DELAY_TIME);
}

unsigned int PCF_Read()
{
	unsigned int U;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	U = I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	U = U * 100 /51;
	return U;
}

iic.h

#ifndef __iic_H__
#define __iic_H__

unsigned int PCF_Read();
#endif

onewire.c

/*	# 	单总线代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <REGX52.H>
sbit DQ = P1^4;
//
void Delay_OneWire(unsigned int t)  
{
	unsigned char i;
	while(t--){
		for(i=0;i<12;i++);
	}
}

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

//
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;
}

//
bit init_ds18b20(void)
{
  	bit initflag = 0;
  	
  	DQ = 1;
  	Delay_OneWire(12);
  	DQ = 0;
  	Delay_OneWire(80);
  	DQ = 1;
  	Delay_OneWire(10); 
    initflag = DQ;     
  	Delay_OneWire(5);
  
  	return initflag;
}
unsigned int Read_temp()
{
	unsigned char LSB,MSB;
	unsigned int temp;
		init_ds18b20();
		Write_DS18B20(0xcc);
		Write_DS18B20(0x44);
		init_ds18b20();
	  Delay_OneWire(500);
		Write_DS18B20(0xcc);
		Write_DS18B20(0xbe);
		LSB = Read_DS18B20();
		MSB = Read_DS18B20();
		init_ds18b20();
		temp = (MSB << 8) | LSB ;
		temp = temp*0.0625*10;
		
   return temp;
}

onewire.h

#ifndef __onewire_H__
#define __onewire_H__

unsigned int Read_temp();
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值