第十四届蓝桥杯单片机第二场模拟赛程序(AD+字符接受串口)

******完整代码**** 

#include <STC15F2K60S2.H>
#include <stdio.H>

#include <IIC.H>

#define u8 unsigned char
#define u16 unsigned int

u8 Nodat[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
u8 Isdat[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};

u8  smg_i,tab[8];
u16 smg_db,parm=65;
u16 cont2;

u8 R_I;
u8 keyval;
u8 stbuf[6];
u8 L1=0;L2=0;L8=0;

bit smg_mode;
bit flag10ms,flag100ms,flag200ms;
//======== ==================初始化函数=========================
void initsystem()
{
	P0=0; P2=0xa0; P2=0;
	P0=0xff; P2=0x80; P2=0;
}
//======== T0定时(串口接收字符串)
void Timer0Init(void)		//10毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x01;			//设置定时器模式
	TL0 = 0xE0;				//设置定时初始值
	TH0 = 0xB1;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
}
//======== T1串口
void UartInit(void)		//[email protected]
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR &= 0xBF;		//定时器1时钟为Fosc/12,即12T
	AUXR &= 0xFE;		//串口1选择定时器1为波特率发生器
	TMOD &= 0x0F;		//设定定时器1为16位自动重装方式
	TL1 = 0xE6;		//设定定时初值
	TH1 = 0xFF;		//设定定时初值
	ET1 = 0;		//禁止定时器1中断
	TR1 = 1;		//启动定时器1
	EA=1; ES=1;
}
//======== T2定时
void Timer2Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xFB;		//定时器时钟12T模式
	T2L = 0x18;		//设置定时初值
	T2H = 0xFC;		//设置定时初值
	AUXR |= 0x10;		//定时器2开始计时
	IE2 |= 0x04;  
	EA=1;
}
//======== =================数据读取函数=========================
//======== AD数据读取
float read_ADC()
{
	float  val;
	EA=0;
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x03);
	I2CWaitAck();
	I2CStop();
	
	I2CStart();
	I2CSendByte(0x91);
	I2CWaitAck();
	val=(5.00/255)*I2CReceiveByte();
	I2CSendAck(1);
	I2CStop();
	EA=1;
	return val;
}	
//======== 串口打印T1
void Uart_Ist()  interrupt 4
{
	if(RI)
	{  RI=0;
		 stbuf[R_I++]=SBUF;
	}
}
void sendbyte(u8 udat)
{
	SBUF=udat;
	while(TI==0);
	TI=0;
}
char putchar(char c)
{
	sendbyte(c);
	return  c;
}
void uart_mange()
{
  u8 i;
	if(TF0)
	{
		 TF0=0;
		if(R_I!=6)
		{  for(i=0;i<7;i++)
			{ stbuf[i++]=0; }
		}
		else 
		{ stbuf[R_I]='\0';
			if((stbuf[0]=='R')&&(stbuf[1]=='e')&&(stbuf[2]=='t')&&(stbuf[3]=='u')&&(stbuf[4]=='r')&&(stbuf[5]=='n'))
				printf("Noises:%.1fdB",(float)smg_db/10);
		}
		R_I=0;
	}
}					

//======== =================数码管显示=========================
void setsmg()
{
	if(smg_mode==0)
	{
		tab[0]=0xc1;
		tab[1]=Nodat[1];
		tab[2]=0xff;
		tab[3]=0xff;
		tab[4]=0xff;
		if(smg_db>99)
		tab[5]=Nodat[smg_db/100];
		else tab[5]=0xff;
		tab[6]=Isdat[smg_db/10%10];
		tab[7]=Nodat[smg_db%10];
		L1=1; L2=0;
	}
	if(smg_mode==1)
	{
		tab[0]=0xc1;
		tab[1]=Nodat[2];
		tab[2]=0xff;
		tab[3]=0xff;
		tab[4]=0xff;
		tab[5]=0xff;
		if(parm>9)
		tab[6]=Nodat[parm/10];
		else tab[6]=0xff;
		tab[7]=Nodat[parm%10];
		L2=1; L1=0;
	}	
}
//======== =================按键扫描========================
u8 read_key()
{
	u8 val=0,x=0,y=0;
	TR1=0;
	P3=0x0f; P42=0; P44=0;
	if(!P30)   x=3;
	else if(!P31)  x=2;
	else if(!P32)  x=1;
	else if(!P33)  x=0;
	P3=0xf0; P42=1; P44=1;
	if(!P34)   y=4;
	else if(!P35)  y=3;	
	else if(!P42)  y=2;
	else if(!P44)  y=1;
	val=x+4*y;
	TR1=1; P3=0xff;
	return  val;
}
void scankey()
{
	u8 up,down,temp;
	static u8 old=0;
	temp=read_key();
	down=temp&(temp^old);
	up=~temp&(temp^old);
	old=temp;
	if(up) keyval=up;
}
//======== =================定时轮询========================
void t2int() interrupt 12           //中断入口
{
	cont2++;
	if(cont2==1000)
		cont2=0;
	if(cont2%2==0)
	{ P0=~(L1+2*L2+128*L8); P2=0x80; P2=0;
		P0=0; P2=0xc0; P2=0;
	  P0=tab[smg_i]; P2=0xe0; P2=0;
	  P0=(1<<smg_i); P2=0xc0; P2=0;	
			smg_i++; smg_i&=0x07;
		if(cont2%10==0)
	{  flag10ms=1;
		if(cont2%100==0)
	{   flag100ms=1;
		if(cont2%200==0)
	{ 
		flag200ms=1;
	 }}}
	}
}
//======== =================主函数========================
void main()
{
	initsystem();
	Timer0Init();
	UartInit();
	Timer2Init();
	while(1)
	{
     	 
	switch(keyval)
	{ 
		case 12 :  smg_mode=!smg_mode;     break;
		case 16 : if(smg_mode) if(parm>=90) parm=90; else  parm+=5;  break;
		case 17 : if(smg_mode) if(parm<=0)   parm=0; else  parm-=5;  break;
	}
	keyval=0;
  
	
	if(flag10ms)
	 {  flag10ms=0;
		    scankey();     	 
	  if(flag100ms)
	   {  flag100ms=0;	
        uart_mange();   			
       if(smg_db>parm*10)	
           L8=!L8;
        else L8=0;			 
	   if(flag200ms)
	   {  flag200ms=0;	
			  smg_db=read_ADC()*18*10;;
			  if(smg_db>=900)
		      smg_db=900;
		 }
	  }  
	 }
	 setsmg();	
	}
}

驱动程序

#ifndef __IIC_H_
#define __IIC_H_

void I2CStart(void);
void I2CStop(void);
void I2CSendByte(unsigned char byt);
unsigned char I2CReceiveByte(void);
unsigned char I2CWaitAck(void);
void I2CSendAck(unsigned char ackbit);
#endif
/*	#   I2C代码片段说明
	1. 	本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
	2. 	参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
		中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <reg52.H>
#include <intrins.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);
}

猜你喜欢

转载自blog.csdn.net/qq_56095985/article/details/129935538
今日推荐