蓝桥杯单片机14届模拟题2

题目如下,按键扫描用的是中断扫描,自从学会了中断扫描的方法之后用了还想用,因为消抖很好。还有就是我总结了一些细节问题:主要太马虎了,写的时候会因为一个小错误浪费世间,所以每次写的时候把遇到的问题写下来,供自己回顾记忆,都很简单,看看笑笑就好:

//main写成了mian
//按键扫描的时候规定按键按下为0,
//    case 0:h0=0;h1=1;break;
//    case 1:h1=0;h0=1;break;
// 扫描那一行就把哪一行拉低,因为按下为零是我们判断条件 也试了设置为按下为高,case 0:h0=1;h1=0;break;
// 但是上电会执行一次按键number会变为1,不知道为啥,所以还是设置为按下为低,number是我验证按键函数是否正确而定义的一个变量,然后数码管显示出来,最后再删了
//读取温度的4个命令 0xcc 0x44  0xcc 0xbe
// 串口中断标志位要开 ES=1;  RI要及时清零
// 每次添加完新的点c文件不要忘记添加进组里
// 定义一个数组char arry[13];
// 定义接收命令command类型为char   把中断服务函数放进main.c函数(主函数)才能执行切换页面操作,不知道为什么,放在usart.c里就不行,这个是第二次敲的时候遇到的问题,我嫌都放在一个点C文件里太长,找函数不好找,就分开了一个usart.c文件,但是led灯等函数没写,就把第一遍写的代码发上来了
// sendstring函数
// 按键发送数据只能发送一次的问题:发送字符串函数定义变量i定义成了static ,发送完一次数据没有清零,所以按键12只能发一次,改成局部变量即可多次发送

 

 

 主函数代码如下

#include "stc15f2k60s2.h"
#include "iic.h"
#include "onewire.h"
#include "stdio.h"

unsigned char dscom=0;
unsigned char code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xc1};
unsigned char dsbuff[8]={0};
unsigned char ad_value=0;
unsigned int ad_value_D=0;
unsigned int wendu_value;
bit ad_flag=0;
bit wendu_flag=0;
bit l1_flag=0;
bit l2_flag=0;
bit lock_flag=0; 
bit jdq_flag=0;
bit beep_flag=0;
unsigned char led_num=0xff;
unsigned char jdq_num=0x00;
unsigned char keysta[2][4]={{1,1,1,1},{1,1,1,1}};
unsigned char keybackup[2][4]={{1,1,1,1},{1,1,1,1}};
unsigned char keybuff[2][4]={{0xff,0xff,0xff,0xff},{0xff,0xff,0xff,0xff}};
unsigned char code keycode[2][4]={{5,9,13,17},{4,8,12,16}};
sbit l0=P4^4;
sbit l1=P4^2;
sbit l2=P3^5;
sbit l3=P3^4;
sbit h2=P3^2;
sbit h3=P3^3;
unsigned char number=0;
char arry[10]="dasdasd";
unsigned char ym_mode=2;
unsigned int ad_t=0;
unsigned char l3_count=0;
void keyaction(unsigned char keydat);
void keysong(unsigned char keydat);
void yemian();
void select573(unsigned char channel)
{
	P2&=0x1f;
	P0=0xff;
	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 allinit()
{
	select573(4);P0=0xff;
	select573(5);P0=0x00;
	select573(6);P0=0xff;
	select573(7);P0=0xff;
}
void display()
{
	select573(7);P0=0xff;
	select573(6);P0=1<<dscom;
	select573(7);
	if(ym_mode==2&&dscom==6)
	{
		P0=tab[dsbuff[dscom]]&0x7f;
	}
	else if(ym_mode==1&&dscom==5)
	{
		P0=tab[dsbuff[dscom]]&0x7f;
	}
	else
		P0=tab[dsbuff[dscom]];
	P2&=0x1f;
	if(++dscom>=8)
		dscom=0;
}
void timer0init()
{
	TMOD=TMOD&0xf0;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	TF0=0;
	TR0=1;
	ET0=1;
	EA=1;
}
void UartInit(void)		//9600bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xE6;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	ES=1;
}
//==================串口发送函数==============================================================================================
void sendbyte(unsigned char bdat)
{
	SBUF=bdat;
	while(TI==0);
	TI=0;
}
void sendstring(char str[])
{
	unsigned char i=0;
	while(str[i]!='\0')
	{
		sendbyte(str[i]);
		i++;
	}
}
void usart()interrupt 4
{
	char command;
	if(RI==1)
	{
		RI=0;
		command=SBUF;
		if(command=='A')
		{
			ym_mode=2;
		}
		else if(command=='B')
		{
			ym_mode=1;
		}
	}
}
//==================按键函数==============================================================================================
void keyscan()
{
	unsigned char i;
	static unsigned char j=0;
	keybuff[j][0]=keybuff[j][0]<<1|l0;
	keybuff[j][1]=keybuff[j][1]<<1|l1;
	keybuff[j][2]=keybuff[j][2]<<1|l2;
	keybuff[j][3]=keybuff[j][3]<<1|l3;
	for(i=0;i<4;i++)
	{
		if((keybuff[j][i]&0x0f)==0)
			keysta[j][i]=0;
		else if((keybuff[j][i]&0x0f)==0x0f)
			keysta[j][i]=1;
	}
	j++;
	if(j>=2)
		j=0;
	switch(j)
	{
		case 0:h2=0;h3=1;break;
		case 1:h3=0;h2=1;break;
	}
}
//==================按键处理
void keyhandle()
{
	unsigned char i,j;
	for(i=0;i<2;i++)
	{
		for(j=0;j<4;j++)
		{
			if(keybackup[i][j]!=keysta[i][j])
			{
				if(keysta[i][j]==0)
				{
					keyaction(keycode[i][j]);
				}
				else if(keysta[i][j]==1)
				{
					keysong(keycode[i][j]);
				}
			}
			keybackup[i][j]=keysta[i][j];
		}
	}
}
void keyaction(unsigned char keydat)
{
	float t;
	if(keydat==4)//按键S4定义为“锁定”按键,按下S4按键,能够锁定当前界面“温度显示界面”或“电压显示界面”,串口切换界面指令失效。
	{
		lock_flag=1;
		ES=0;
	}
	else if(keydat==5)//按键S5定义为“解锁”按键,在界面锁定时,按下S5按键,可取消界面锁定,串口指令恢复控制
	{
		lock_flag=0;
		led_num|=0x04;
		ES=1;
	}
	else if(keydat==12)//按键S12定义为“发送”按键,每次按下,串口将当前数码管显示的数据发送给PC端的串口调试工具。
	{
		if(ym_mode==1)     //电压
		{
			t=ad_value_D;
			t=t/100.0;
			sprintf(arry,"Voltage:%.2fV",t);
			sendstring(arry);
		}
		else if(ym_mode==2)//温度
		{
//			sprintf(arry,"TEMP:%d.%d℃",wendu_value/10,wendu_value%10);
//			sendstring(arry);
			t=wendu_value;
			t=t/10.0;
			sprintf(arry,"TEMP:%.1f℃",t);
			sendstring(arry);
		}
	}
}
void keysong(unsigned char keydat)
{
	if(keydat==4)
	{
		
	}
}
//==============================================================================================================================
void ledhandle()
{
	P2&=0x1f;P0=0xff;
	select573(4);
	P0=led_num;
	P2&=0x1f;P0=0xff;
}
void jdq_fmq_handle()
{
	P2&=0x1f;P0=0x00;
	select573(5);
	P0=jdq_num;
	P2&=0x1f;P0=0xff;
}
//==================中断函数=============================================================================================

void timer0()interrupt 1
{
	ledhandle();
	jdq_fmq_handle();
	keyscan();
	yemian();
	display();
	ad_t++;
	if(ad_t>=500)
	{
		ad_t=0;
		ad_flag=1;
		wendu_flag=1;
	}
	
	if(l1_flag==1)
	{
		led_num=led_num&0xfe;
	}
	else if(l1_flag==0)
	{
		led_num=led_num|0x01;
	}
	else
		led_num=led_num|0x01;
	if(l2_flag==1)
	{
		led_num=led_num&0xfd;
	}
	else if(l2_flag==0)
	{
		led_num=led_num|0x02;
	}
	else
		led_num=led_num|0x02;
	
	if(lock_flag==1)
	{
		l3_count++;
		if(l3_count<100)
		{
			led_num=led_num&0xfb;
		}
		else if(l3_count>=100&&(l3_count<200))
		{
			led_num=led_num|0x04;
		}
		else if(l3_count==200)
		{
			l3_count=0;
		}
	}
	//继电器
  if(jdq_flag==1)
	{
		jdq_num=jdq_num|0x10;
	}
	else if(jdq_flag==0)
	{
		jdq_num=jdq_num&0xef;
	}
	//蜂鸣器
	if(beep_flag==1)
	{
		jdq_num=jdq_num|0x40;
	}
	else if(beep_flag==0)
	{
		jdq_num=jdq_num&0xbf;
	}
}
//===================main函数============================================================================================
void main()
{
	allinit();
	timer0init();
	UartInit();
	while(1)
	{
		keyhandle();
		if(ad_flag==1)
		{
			ad_flag=0;
			ad_value=pcf_ad();
			ad_value_D=ad_value*1.9607;
		}
		else if(wendu_flag==1)
		{
			wendu_flag=0;
			wendu_value=read_temperature();
		}
		if(ym_mode==2)//温度界面
		{
			l1_flag=1;
		}
		else l1_flag=0;
		if(ym_mode==1)//电压界面
		{
			l2_flag=1;
		}
		else l2_flag=0;
		
		if(wendu_value>=260)
		{
			jdq_flag=1;
		}
		else
		{
			jdq_flag=0;
		}
		
		if(ad_value_D>360)
		{
			beep_flag=1;
		}
		else
		{
			beep_flag=0;
		}
	}
}
void yemian()
{
	if(ym_mode==1)
	{
		dsbuff[0]=11;
		dsbuff[1]=2;
		dsbuff[2]=10;
		dsbuff[3]=10;
		dsbuff[4]=10;
		dsbuff[5]=ad_value_D/100;
		dsbuff[6]=ad_value_D/10%10;
		dsbuff[7]=ad_value_D%10;
	}
	else if(ym_mode==2)
	{
		dsbuff[0]=11;
		dsbuff[1]=1;
		dsbuff[2]=10;
		dsbuff[3]=10;
		dsbuff[4]=10;
		dsbuff[5]=wendu_value/100;
		dsbuff[6]=wendu_value/10%10;
		dsbuff[7]=wendu_value%10;
	}
}
#include "intrins.h"
#include "stc15f2k60s2.h"
#include "iic.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 char pcf_ad()
{
	unsigned char adt;
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adt=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	EA=1;
	return adt;
}

IIC.C函数

#include "intrins.h"
#include "stc15f2k60s2.h"
#include "iic.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 char pcf_ad()
{
	unsigned char adt;
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	adt=I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	EA=1;
	return adt;
}

onewire.c函数

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

int read_temperature()
{
	unsigned char low,high;
	unsigned int temp;
	EA=0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	low=Read_DS18B20();
	high=Read_DS18B20();
	EA=1;
	temp=high<<8;
	temp=temp|low;
	
	return temp*0.625; //保留两位小数
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值