蓝桥杯单片机第十五届省赛

 4T评测

蓝桥杯单片机第十五届省赛_第1张图片

记录自己的学习过程

以下代码仅供参考,有不对的请多多指教(西风模版)

main.c

#include 
#include "init.h"
#include "key.h"
#include "led.h"
#include "seg.h"
#include "ds1302.h"
#include "iic.h"

//Key
unsigned char Key_vol,key_down,key_old;
//Seg
unsigned char Seg_pos;
unsigned char Seg_buf[]={10,10,10,10,10,10,10,10};
//Led	
unsigned char ucLed[]={0,0,0,0,0,0,0,0};
unsigned char ucRtc[]={13,3,5};
//DA
unsigned char DA_freg;//DA的电压输出
unsigned int Freq;//频率
int Freq_Jaz_plus=0;
unsigned int time_1000ms;
int Freq_Jaz=0;//校准
unsigned int ChaoXian=2000;

unsigned char Seg_disp_mode;//0-频率 1-参数 2-时间 3-回显
bit Seg_disp_S5;//参数界面 0-超限参数 1-校准值  
                //回显界面 0-频率回显 1-时间回显

bit mode0_flag;//闪缩200ms标志位
bit error;//错误标志位 

unsigned int Freq_max=0;
unsigned char ucRtc_max[]={0,0,0};
unsigned char Timer200ms;

void Key_proc()
{
	if(time_1000ms%10)return;
		
	
	Key_vol=Key_Read();
	key_down=Key_vol&(key_old^Key_vol);
	key_old=Key_vol;
	
	switch(key_down)
	{
		case 4://界面切换
			if(++Seg_disp_mode==4)Seg_disp_mode=0;
			if((Seg_disp_mode==1)||(Seg_disp_mode==3))Seg_disp_S5=0;
		break;
		
		case 5://参数界面 0-超限参数 1-校准值  
			   //回显界面 0-频率回显 1-时间回显
			if(Seg_disp_mode==1)
			{
				Seg_disp_S5^=1;
			}
			if(Seg_disp_mode==3)
			{
				Seg_disp_S5^=1;
			}
		break;
		
		case 8://超限参数:+1000
			   //校准值参数:+100
			if(Seg_disp_mode==1)//参数界面下对子页面值修改
			{
				if(Seg_disp_S5==1)//校准值参数
				{
					Freq_Jaz=Freq_Jaz+100;
					if(Freq_Jaz>900)Freq_Jaz=900;
				}
				else if(Seg_disp_S5==0)//超限参数
				{
					ChaoXian=ChaoXian+1000;
					if(ChaoXian>9000)ChaoXian=9000;
				}
			}
		break;
		
		case 9://超限参数:-1000
			   //校准值参数:-100
			if(Seg_disp_mode==1)//参数界面下对子页面值修改
			{
				if(Seg_disp_S5==1)//校准值参数
				{
					Freq_Jaz=Freq_Jaz-100;
					if(Freq_Jaz<-900)Freq_Jaz=-900;				
				}
				
				else if(Seg_disp_S5==0)//超限参数
				{
					ChaoXian=ChaoXian-1000;
					if(ChaoXian<1000)ChaoXian=1000;
				}
			}
		break;
	}
}
void Seg_proc()
{
	unsigned char i;
	if(time_1000ms%500)return;
	
	Read_Rtc(ucRtc);
	
	Freq_Jaz_plus=Freq+Freq_Jaz;
	
	if(Freq_max0)&&(Freq_Jaz<=900))
					{
						Seg_buf[4]=10;
						Seg_buf[5]=Freq_Jaz/100%10;
						Seg_buf[6]=Freq_Jaz/10%10;
						Seg_buf[7]=Freq_Jaz%10;
					}
					
					else if(Freq_Jaz<0)
					{
						Seg_buf[4]=13;//-
						Seg_buf[5]=(-Freq_Jaz)/100%10;
						Seg_buf[6]=(-Freq_Jaz)/10%10;
						Seg_buf[7]=(-Freq_Jaz)%10;
					}
				}
		break;
		
		case 2://时间界面
			Seg_buf[2]=Seg_buf[5]=13;//-
		
			Seg_buf[0]=ucRtc[0]/10%10;
			Seg_buf[1]=ucRtc[0]%10;
			
			Seg_buf[3]=ucRtc[1]/10%10;
			Seg_buf[4]=ucRtc[1]%10;
		
			Seg_buf[6]=ucRtc[2]/10%10;
			Seg_buf[7]=ucRtc[2]%10;
		break;
		
		case 3://回显界面(0-频率 1-时间)
			if(Seg_disp_S5==0)//回显子页面最大频率
			{
				Seg_buf[0]=14;//H
				Seg_buf[1]=11;//F
				Seg_buf[2]=10;
				Seg_buf[3]=Freq_max/10000%10;
				Seg_buf[4]=Freq_max/1000%10;
				Seg_buf[5]=Freq_max/100%10;
				Seg_buf[6]=Freq_max/10%10;
				Seg_buf[7]=Freq_max%10;
				i=3;
				while(Seg_buf[i]==0)
				{
					Seg_buf[i]=10;
					if(++i==7)break;	
				}
			}
			
			if(Seg_disp_S5==1)//回显子页面最大时间
			{
				Seg_buf[0]=14;//H
				Seg_buf[1]=15;//A
				Seg_buf[2]=ucRtc_max[0]/10%10;
				Seg_buf[3]=ucRtc_max[0]%10;
				Seg_buf[4]=ucRtc_max[1]/10%10;
				Seg_buf[5]=ucRtc_max[1]%10;
				Seg_buf[6]=ucRtc_max[2]/10%10;
				Seg_buf[7]=ucRtc_max[2]%10;
			}
		break;
	}
}
void Led_proc()
{
	if(time_1000ms%2)return;
	
	ucLed[0]=mode0_flag?!Seg_disp_mode:0;//0亮
	if(error)
		ucLed[1]=1;
	else
		ucLed[1]=mode0_flag?(Freq_Jaz_plus>ChaoXian):0;
	
}
void DA_proc()
{
	float temp_da;
	if(time_1000ms%150)return;
	
	if(error)
	{
		DA_Read(0);
	}
	else if(Freq_Jaz_plus<=500)
	{
		DA_Read(1*51);
	}
	else if((Freq_Jaz_plus>500)&&(Freq_Jaz_plusChaoXian)
	{
		DA_Read(5*51);
	}
}


void Timer1_Init(void)		//1毫秒@12.000MHz
{
	AUXR |= 0x40;			//定时器时钟1T模式
	TMOD &= 0x0F;			//设置定时器模式
	TL1 = 0x20;				//设置定时初始值
	TH1 = 0xD1;				//设置定时初始值
	TF1 = 0;				//清除TF1标志
	TR1 = 1;				//定时器1开始计时
	ET1=1;
	EA=1;
}


void Timer1_Server() interrupt 3
{
	if(++Seg_pos==8)Seg_pos=0;
	if(++Timer200ms==200)
	{
		Timer200ms=0;
		mode0_flag^=1;
	}
	if(++time_1000ms==1000)
	{
		time_1000ms=0;
		Freq=TH0<<8|TL0;
		TH0=TL0=0;
	}
	Seg_disp(Seg_pos,Seg_buf[Seg_pos]);
	Led_disp(Seg_pos,ucLed[Seg_pos]);
}

void Timer0_Init()		//1毫秒@12.000MHz
{
	AUXR &= 0x7F;			//定时器时钟12T模式
	TMOD &= 0xF0;			//设置定时器模式
	TMOD |= 0x05;
	TL0 = 0;				//设置定时初始值
	TH0 = 0;				//设置定时初始值
	TF0 = 0;				//清除TF0标志
	TR0 = 1;				//定时器0开始计时
	EA = 1;					//使能定时器0中断
}

void main()
{
	Sys_init();
	Timer0_Init();
	Timer1_Init();
	Set_Rtc(ucRtc);
	while(1)
	{
		Key_proc();
		Seg_proc();
		Led_proc();
		DA_proc();
	}
}

init.c

#include "init.h"

void Sys_init()
{
	P0=0xFF;
	P2=P2&0x1F|0x80;
	P2=P2&0x1F;
	
	P0=0x00;
	P2=P2&0x1F|0xA0;
	P2=P2&0x1F;
	
}

key.c

#include "key.h"

unsigned char Key_Read()
{
	unsigned char temp=0;
	P44=0;P42=1;P35=1;//P34=1;
	if(P33==0)temp=4;
	if(P32==0)temp=5;
	if(P31==0)temp=6;
	if(P30==0)temp=7;
	P44=1;P42=0;P35=1;//P34=1;
	if(P33==0)temp=8;
	if(P32==0)temp=9;
	if(P31==0)temp=10;
	if(P30==0)temp=11;
	P44=1;P42=1;P35=0;//P34=1;
	if(P33==0)temp=12;
	if(P32==0)temp=13;
	if(P31==0)temp=14;
	if(P30==0)temp=15;
	
	return temp;
//	P44=1;P42=1;P35=1;P34=0;
//	if(P33==0)temp=4;
//	if(P32==0)temp=4;
//	if(P31==0)temp=4;
//	if(P30==0)temp=4;
	
	
}

seg.c

#include "seg.h"

code unsigned char Seg_dula[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
						       0x82,0xf8,0x80,0x90,0xff,0x8e,
							   0x8c,0xbf,0x89,0x88,0xc7};

void Seg_disp(unsigned char wela,unsigned char dula)
{
	//消影
	P0=0xFF;
	P2=P2&0x1F|0xe0;
	P2=P2&0x1F;
	
	P0=0x01<

led.c

#include "led.h"

void Led_disp(unsigned char addr,bit enable)
{
	static unsigned char temp=0x00;
	static unsigned char temp_old=0xff;
	
	if(enable)
		temp=temp|(0x01<

ds1302.c

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

sbit RST = P1^3;
sbit SDA = P2^3;
sbit SCK = P1^7;

//
void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK = 0;
		SDA = temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

//
void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

//
unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

void Set_Rtc(unsigned char *ucRtc)
{
	unsigned char i;
	
	Write_Ds1302_Byte(0x8e,0x00);//关闭写保护
	for(i=0;i<3;i++)
	{
		Write_Ds1302_Byte(0x84-i*2,ucRtc[i]/10<<4|ucRtc[i]%10);//10->16
	}
	Write_Ds1302_Byte(0x8e,0x80);
}
void Read_Rtc(unsigned char *ucRtc)
{
	unsigned char temp,i;
	
	for(i=0;i<3;i++)
	{
		temp=Read_Ds1302_Byte(0x85-i*2);//16->10
		ucRtc[i]=temp/16*10+temp%16;
	}
}

iic.c

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

#define DELAY_TIME	10

#include "iic.h"
#include "intrins.h"
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);
}

void DA_Read(unsigned char dat)
{
	I2CStart();
	I2CSendByte(0x90);
	I2CWaitAck();
	I2CSendByte(0x41);
	I2CWaitAck();
	I2CSendByte(dat);
	I2CWaitAck();
	I2CStop();
}


你可能感兴趣的:(蓝桥杯,单片机)