蓝桥杯 国赛 第十届国赛

先说我遇到问题

//测温度闪烁,没有把标志位清零
//按键长按执行操作在松手检测里
//开ES=1--串口中断
//刚加usart初始化的时候整个数据显示坏了,然后把初始化的每句话一句一句注释,莫名其妙的好了,可能板子问题
//串口助手发送命令给单片机的时候 while(str[i]!='\0') 判断字符串结束 中断里是根据题目要求判断结束符号进行操作
//串口发送数据时候关闭中断
//sprintf函数头文件#include "stdio.h"
//发送命令的时候不可以加 \r\n 因为判断条件 '\r\n' 判断的是回车不是字符
//定义一个字符串用双引号char arrt[3]="asd";
//打印字符\r\n这样定义一个数组然后打印出来 char arrt[4]="\\r\\n"; 但是这样不知道为啥会打印两遍,然后把\\r\\n放到数据里边就好了
//打印温度参数和湿度参数的时候刚开始老是错,原因是定义了char类型,换成了int类型好了
//发送数据的时候把中断关了
//打印error\r\n的时候数组大小9个刚好,但是这样不知道为什么会多打印出来输入的错误命令,把数组大小换成10个就好了,这种不好,占内存,有三种方法
//判断命令结束条件 \r\n最后两个  所以写入命令的时候要打回车(没有写判断其他无回车换行的命令代码,麻烦。。。。。。。)
//发送一个字节函数参数定义是void sendbyte(unsigned char byte)
//发送字符串函数的参数定义为char    void sendstring(char str[])

然后就是串口发送error,刚开始我是一边接收一边判断,但是不好判断错误命令,然后改成接收完判断,好判断错误的命令,但是不好判断什么时候结束,我就规定换行的时候结束。

然后就是串口中断函数要放在main.c文件下的函数里,否则串口中断不执行操作,不知道为什么!!!

 代码:

main函数:

//测温度闪烁,没有把标志位清零
//按键长按执行操作在松手检测里
//开ES=1--串口中断
//刚加usart初始化的时候整个数据显示坏了,然后把初始化的每句话一句一句注释,莫名其妙的好了,可能板子问题
//串口助手发送命令给单片机的时候 while(str[i]!='\0') 判断字符串结束 中断里是根据题目要求判断结束符号进行操作
//串口发送数据时候关闭中断
//sprintf函数头文件#include "stdio.h"
//发送命令的时候不可以加 \r\n 因为判断条件 '\r\n' 判断的是回车不是字符
//定义一个字符串用双引号char arrt[3]="asd";
//打印字符\r\n这样定义一个数组然后打印出来 char arrt[4]="\\r\\n"; 但是这样不知道为啥会打印两遍,然后把\\r\\n放到数据里边就好了
//打印温度参数和湿度参数的时候刚开始老是错,原因是定义了char类型,换成了int类型好了
//发送数据的时候把中断关了
//打印error\r\n的时候数组大小9个刚好,但是这样不知道为什么会多打印出来输入的错误命令,把数组大小换成10个就好了,这种不好,占内存,有三种方法
//判断命令结束条件 \r\n最后两个  所以写入命令的时候要打回车(没有写判断其他无回车换行的命令代码,麻烦。。。。。。。)
//发送一个字节函数参数定义是void sendbyte(unsigned char byte)
//发送字符串函数的参数定义为char    void sendstring(char str[])

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

sbit h0=P3^2;
sbit h1=P3^3;
sbit l0=P3^5;
sbit l1=P3^4;

unsigned char code tab[]=
{
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //灭-10
0x88, //A-11
0x83, //b-12
0xc6, //C-13
0xa1, //d-14
0x86, //E-15
0x8e, //F-16
0xc7, //L-17
0xc8, //n-18
0x8c, //P-19
};
unsigned char dscom=0;
unsigned char dsbuff[8];
unsigned char keysta[2][2]={{1,1},{1,1}};
unsigned char keybackup[2][2]={{1,1},{1,1}};
unsigned char keybuff[2][2]={{0xff,0xff},{0xff,0xff}};
unsigned char code keycode[2][2]={{13,17},{12,16}};


unsigned char jiemian_mode=1;
unsigned char shuju_mode=1;
unsigned char canshu_mode=1;
//char wendu_canshu=30;
//char juli_canshu=35;
unsigned int wendu_canshu=30;
unsigned int juli_canshu=35;
bit dac_flag=0;

void yemian();
void keysong(unsigned char dat);
void keyaction(unsigned char dat);
	
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 timer0init()
{
	TMOD&=0xf0;
	TH0=(65536-1000)/256;
	TL0=(65536-1000)%256;
	TF0=0;
	ET0=1;
	EA=1;
	TR0=1;
	
	TH1=0;
	TL1=0;
	ET1=0;
	TF1=0;
	
}
void display()
{
	select573(7);
	P0=0xff;
	select573(6);
	P0=1<<dscom;
	select573(7);
	if(dscom==5 && jiemian_mode==1 && shuju_mode==1)
	{
		P0=tab[dsbuff[dscom]]&0x7f;
	}
	else
		P0=tab[dsbuff[dscom]];
		
	P2&=0x1f;
	P0=0xff;
	
	if(++dscom==8)
	{
		dscom=0;
	}
}
//=============按键函数=====================================================================
//==========按键扫描
void keyscan()
{
	static unsigned char keyout=0;
	unsigned char i=0;
	
	keybuff[keyout][0]=keybuff[keyout][0]<<1|l0;
	keybuff[keyout][1]=keybuff[keyout][1]<<1|l1;
	
	for(i=0;i<2;i++)
	{
		if((keybuff[keyout][i]&0xff)==0)
		{
			keysta[keyout][i]=0;
		}
		else if((keybuff[keyout][i]&0xff)==0xff)
		{
			keysta[keyout][i]=1;
		}
			
	}
	keyout++;
	if(keyout>=2)
		keyout=0;
	switch(keyout)
	{
		case 0:h0=0;h1=1;break;
		case 1:h1=0;h0=1;break;
	}
	
}
//==========按键处理
void keyhandle()
{
	unsigned char i,j;
	for(i=0;i<2;i++)
	{
		for(j=0;j<2;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];
			}
		}
	}
}

unsigned int canshu_count=0;
bit key_bit=0;
unsigned int key_count=0;
bit longthing=0;
bit eeprom_bit=0;

void keyaction(unsigned char dat)
{
	if(dat==13) //界面按键
	{
		if(jiemian_mode==1)
		{
			jiemian_mode=2; //参数界面
		}
		else if(jiemian_mode==2)
		{
			jiemian_mode=1; //数据界面
		}
		//==========长按================================================
		key_bit=1;
	}
	if(dat==12) //切换按键
	{
		if(jiemian_mode==1)
		{
			if(shuju_mode==1)      shuju_mode=2; //变更次数数据
			else if(shuju_mode==2) shuju_mode=3; //距离数据
			else if(shuju_mode==3) shuju_mode=1; //温度数据
		}
		else if(jiemian_mode==2)
		{
			if(canshu_mode==1)      canshu_mode=2; //距离参数
			else if(canshu_mode==2) canshu_mode=1; //温度参数
		}
		//==========长按================================================
		key_bit=1;
		
	}
	if(dat==16) //减按键
	{
		if(canshu_mode==1&&jiemian_mode==2)
		{
			canshu_count++;
			eeprom_bit=1;
			wendu_canshu-=2;
			if(wendu_canshu<=0)
				wendu_canshu=0;
		}
		else if(canshu_mode==2&&jiemian_mode==2)
		{
			canshu_count++;
			eeprom_bit=1;
			juli_canshu-=5;
			if(juli_canshu<=0)
				juli_canshu=0;
		}
	}
	if(dat==17) //加按键
	{
		if(canshu_mode==1&&jiemian_mode==2)
		{
			canshu_count++;
			eeprom_bit=1;
			wendu_canshu+=2;
			if(wendu_canshu>=99)
				wendu_canshu=99;
		}
		else if(canshu_mode==2&&jiemian_mode==2)
		{
			canshu_count++;
			eeprom_bit=1;
			juli_canshu+=5;
			if(juli_canshu>=99)
				juli_canshu=99;
		}
	}
}
void keysong(unsigned char dat)
{
	if(dat==12)
	{
		if(longthing==1)
		{
			longthing=0;
			canshu_count=0;
			eeprom_bit=1;
		}
		key_bit=0;
		key_count=0;
	}
	if(dat==13)
	{
		if(longthing==1)
		{
			longthing=0;
			dac_flag=~dac_flag;
		}
		key_bit=0;
		key_count=0;
	}
}
//==========超声波函数=======================================================
unsigned int distance=123;
sbit TX=P1^0;
sbit RX=P1^1;
void Delay12us()		//@12.000MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	i = 33;
	while (--i);
}
void send_wave()
{
	unsigned char i=8;
	do
	{
		TX=1;
		Delay12us();
		TX=0;
		Delay12us();
	}while(i--);
}
void csb_ceju()
{
	unsigned int disttt;
	TMOD=TMOD&0x0f;
	TH1=0;
	TL1=0;
	TF1=0;
	ET1=0;
	
	send_wave();
	TR1=1;
	while((RX==1)&&(TF1==0));
	TR1=0;
	disttt=TH1*256+TL1;
	if(TF1==0)
	{
		distance=disttt*0.017;
	}
	else
	{
		distance=999;
		TF1=0;
	}
		
	TH1=0;
	TL1=0;
}



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

	i = 59;
	j = 90;
	do
	{
		while (--j);
	} while (--i);
}


//==========中断函数=======================================================
unsigned int temperature;
unsigned int wendu_count=0;
bit wendu_bit=0;
unsigned char juli_count=0;
bit csb_bit=0;

bit dac_bit=1;
unsigned char dac_count=0;

void timer0()interrupt 1
{
	display();
	yemian();
	keyscan();
	
	//=======读取温度
	wendu_count++;
	if(wendu_count>=500)
	{
		wendu_count=0;
		wendu_bit=1;
	}
	//========测量距离
	juli_count++;
	if(juli_count>=200)
	{
		juli_count=0;
		csb_bit=1;
	}
	//========按键长按
	if(key_bit==1)
	{
		key_count++;
		if(key_count>=1000)
		{
			key_count=0;
			longthing=1;
		}
	}
	//========dac输出
	if(dac_flag==1) 
	{
		dac_count++;
		if(dac_count>=200)
		{
			dac_count=0;
			dac_bit=1;
		}
	}
}

//============main函数=====================================================================
void main()
{
	allinit();
	timer0init();
	UartInit();
	while(1)
	{
		keyhandle();
		//=======读取温度
		if(wendu_bit==1)
		{
			wendu_bit=0;
			temperature=read_temperature();
		}
		//========测量距离
		if(csb_bit==1 && jiemian_mode==1 && shuju_mode==2)
		{
			csb_bit=0;
			csb_ceju();
		}
		//========dac输出
		if(dac_bit==1)
		{
			dac_bit=0;
			if(distance<=juli_canshu)
			{
				pcf_dac(103);
			}
			else
			{
				pcf_dac(206);
			}
		}
		if(dac_flag==0)
		{
			pcf_dac(21);
		}
		//========eeprom数据写入
		if(eeprom_bit==1)
		{
			eeprom_write(0x00,canshu_count%256);
			Delay5ms();
			eeprom_write(0x01,canshu_count/256);
			eeprom_bit=0;
		}
		
		
		
	}
}
//======页面函数==========================================================================
void yemian()
{
	if(jiemian_mode==1)
	{
		if(shuju_mode==1)
		{
			dsbuff[0]=13;
			dsbuff[1]=10;
			dsbuff[2]=10;
			dsbuff[3]=10;
			dsbuff[4]=temperature/1000;
			dsbuff[5]=temperature%1000/100;
			dsbuff[6]=temperature%100/10;
			dsbuff[7]=temperature%10;
		}
		else if(shuju_mode==2)
		{
			dsbuff[0]=17;
			dsbuff[1]=10;
			dsbuff[2]=10;
			dsbuff[3]=10;
			dsbuff[4]=10;
			dsbuff[5]=distance/100;
			dsbuff[6]=distance/10%10;
			dsbuff[7]=distance%10;
		}
		else if(shuju_mode==3)
		{
			dsbuff[0]=18;
			dsbuff[1]=10;
			dsbuff[2]=10;
			dsbuff[3]=canshu_count/10000;
			dsbuff[4]=canshu_count%10000/1000;
			dsbuff[5]=canshu_count%1000/100;
			dsbuff[6]=canshu_count%100/10;
			dsbuff[7]=canshu_count%10;
		}
	}
	else if(jiemian_mode==2)
	{
		if(canshu_mode==1)
		{
			dsbuff[0]=19;
			dsbuff[1]=10;
			dsbuff[2]=10;
			dsbuff[3]=1;
			dsbuff[4]=10;
			dsbuff[5]=10;
			dsbuff[6]=wendu_canshu/10;
			dsbuff[7]=wendu_canshu%10;
		}
		else if(canshu_mode==2)
		{
			dsbuff[0]=19;
			dsbuff[1]=10;
			dsbuff[2]=10;
			dsbuff[3]=2;
			dsbuff[4]=10;
			dsbuff[5]=10;
			dsbuff[6]=juli_canshu/10;
			dsbuff[7]=juli_canshu%10;
		}
	}
	
}

char arry[11];
//char arrt[10]="error\\r\\n";
void usart()interrupt 4
{
	static unsigned char i=0;
	if(RI==1)
	{
		RI=0;
		arry[i]=SBUF;
		//一边接收一边判断,但是最好不好判断错误命令
//		if(arry[i]=='\n'&&arry[i-1]=='\r'&&arry[i-2]=='A'&&arry[i-3]=='R'&&arry[i-4]=='A'&&arry[i-5]=='P')
//		{
//			flag=1;
//			i=0;
//			sprintf(arry,"#%d,%d \\r\\n\r\n",juli_canshu,wendu_canshu);
//			sendstring(arry);
//		}
//		else if(arry[i-3]=='S'&&arry[i-2]=='T'&&arry[i-1]=='\r'&&arry[i]=='\n')
//		{
//			flag=1;
//			i=0;
//			sprintf(arry,"$%d,%.2f\\r\\n\r\n",distance,temperature/100.0);
//			sendstring(arry);
//		}
//		else
//			i++;	
		
		//接收完判断,好判断错误的命令,但是不好判断什么时候结束,我就规定换行的时候结束
		if(arry[i]=='\n'&&arry[i-1]=='\r')
		{
			if(arry[i-2]=='A'&&arry[i-3]=='R'&&arry[i-4]=='A'&&arry[i-5]=='P')
			{
				i=0;
				sprintf(arry,"#%d,%d \\r\\n\r\n",juli_canshu,wendu_canshu);
				sendstring(arry);
			}
			else if(arry[i-3]=='S'&&arry[i-2]=='T'&&arry[i-1]=='\r'&&arry[i]=='\n')
			{
				i=0;
				sprintf(arry,"$%d,%.2f\\r\\n\r\n",distance,temperature/100.0);
				sendstring(arry);
			}
			else
			{
				//方法一
//				sprintf(arry,"error\\r\\n");
//				sendstring(arry);
				//方法二
				sendstring("error\\r\\n\r\n");
				//方法三
//				sendstring(arrt);
			  i=0;
			}
		}
		else
		{
			i++;
		}
		
	}
}

onewire函数

#include "onewire.h"
#include "intrins.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_temperature()
{
	unsigned int temp;
	unsigned char low,high;
	EA=0;
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xcc);
	Write_DS18B20(0xbe);
	
	low=Read_DS18B20();
	high=Read_DS18B20();
	
	
	temp=high;
	temp=temp<<8;
	temp=temp|low;
	EA=1;
	
	return temp*6.25;
}

iic函数

#include "intrins.h"
#include "iic.h"

sbit scl=P2^0;
sbit sda=P2^1;

#define DELAY_TIME	5

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

void pcf_dac(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x40);
	I2CWaitAck();
	
	I2CSendByte(dat);
	I2CWaitAck();
	I2CSendAck(1);
	I2CStop();
}

void eeprom_write(unsigned char adress,unsigned char value)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CWaitAck();
	
	I2CSendByte(adress);
	I2CWaitAck();
	
	I2CSendByte(value);
	I2CWaitAck();
	I2CWaitAck();
	I2CSendAck(1);
	I2CStop();
}

usart函数

#include "usart.h"


void UartInit()		//4800bps@12.000MHz
{
//	IP|=0x10;
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR &= 0xFB;		//定时器2时钟为Fosc/12,即12T
	T2L = 0xCC;		//设定定时初值
	T2H = 0xFF;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	ES=1;

}


//=============发送字节======================
void sendbyte(unsigned char byte)
{
	EA=0;
	SBUF=byte;
	while(TI==0);
	TI=0;
	EA=1;
}
//============发送字符串========================
void sendstring(char str[])
{
	unsigned char i=0;
	while(str[i]!='\0')
	{
		sendbyte(str[i]);
		i++;
	}
}

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值