蓝桥杯省赛模板(更新至20210604)

本模板主要参考《“蓝桥杯”全国软件和信息技术专业人才大赛(电子类)实训指导书》,并依据自己习惯编写而成。

User

main.c

#include "stdio.h"

#include "tim.h"
#include "bsp_init.h"
#include "bsp_led.h"
#include "bsp_seg.h"
#include "bsp_key.h"
#include "bsp_ds1302.h"
#include "bsp_iic.h"
#include "bsp_onewire.h"
#include "bsp_ultrasonic.h"

/******函数声明******/
void KEY_Proc(void);
void SEG_Proc(void);
void LED_Proc(void);

/******变量定义******/
//LED专用
uchar LED = 0x00;

//SEG专用
uchar seg_string[10];
uchar seg_buf[8];
uchar seg_pos;

//KEY专用
uchar key_value;
uchar key_down;
uchar key_old;

//减速专用
uchar key_delay;
uchar seg_delay;
uchar led_delay;

//滴答变量
uint ms_tick;
uint s_tick;

//DS1302专用
uchar RTC[3];

//at24c02专用
uchar rom_string[8];

//根据代码需求进行变化

/******主函数******/
void main(void)
{
	cls_peripheral();//关闭外设
	
	Timer1Init();
	EA = 1;
	
	//EEPROM读取
	EEPROM_Read(rom_string,0x00,1);
	
	while(1)
	{
		KEY_Proc();
		SEG_Proc();
		LED_Proc();
	}
}

/******定时器1中断服务函数******/
void timer1(void) interrupt 3
{
	if (++key_delay == 10) key_delay = 0;
	if (++seg_delay == 200) key_delay = 0;
	if (++led_delay == 100) key_delay = 0;
	
	//滴答变量
	
	//数码管显示
	SEG_Disp(seg_buf,seg_pos);
	if (++seg_pos == 8) seg_pos = 0;
	
	//LED显示
	LED_Disp(LED);
}

/*****KEY处理函数******/
void KEY_Proc(void)
{
	if (key_delay) return;
	key_delay = 1;
	
	//键值获取
	key_value = KEY_READ_KBD();
	key_down = key_value & (key_value ^ key_old);
	key_old = key_value;
	
	//根据代码需求进行改变
	
}

/*****SEG处理函数******/
void SEG_Proc(void)
{
	if (seg_delay) return;
	seg_delay = 1;
	
	//SEG内容
	
	//SEG编码
	SEG_Tran(seg_string, seg_buf);

}

/*****LED处理函数******/
void LED_Proc(void)
{
	if (led_delay) return;
	led_delay = 1;
	
	//根据代码需求进行改变
	
}

Sys

tim.c

#include "tim.h"

void Timer1Init(void)		//1毫秒@12.000MHz
{
	AUXR &= 0xBF;		//定时器时钟12T模式
	TMOD &= 0x0F;		//设置定时器模式
	TL1 = 0x18;		//设置定时初值
	TH1 = 0xFC;		//设置定时初值
	TF1 = 0;		//清除TF1标志
	TR1 = 1;		//定时器1开始计时
	ET1 = 1;
}

void Timer0Init_Freq(void)
{
	TMOD |= 0x04;
	TL0 = 0;
	TH0 = 0;
	TR0 = 1;
}

uart.c

#include "uart.h"

void UartInit(void)		//4800bps@12.000MHz
{
	SCON = 0x50;		//8位数据,可变波特率
	AUXR |= 0x01;		//串口1选择定时器2为波特率发生器
	AUXR |= 0x04;		//定时器2时钟为Fosc,即1T
	T2L = 0x8F;		//设定定时初值
	T2H = 0xFD;		//设定定时初值
	AUXR |= 0x10;		//启动定时器2
	
	ES = 1;		//一定一定不要忘记开中断!
}


//发送一个字节
void Uart_Sendbyte(uchar byte)
{
	SBUF = byte;
	while(TI == 0);
	TI = 0;
}


//发送一个字符串
void Uart_Sendstring(uchar *string)
{
	while(*string != '\0')
	{
		Uart_Sendbyte(*string);
		string++;
	}
}

Driver

bsp_init.c

#include "bsp_init.h"

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

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
}


//开关蜂鸣器和继电器的部分代码
void open_beep(void)
{
	P0 = 0x40;
	P2 = P2 & 0x1F | 0xA0;
	P2 = P2 & 0x1F;
}

void close_beep(void)
{
	P0 = 0x00;
	P2 = P2 & 0x1F | 0xA0;
	P2 = P2 & 0x1F;
}

void open_relay(void)
{
	P0 = 0x10;
	P2 = P2 & 0x1F | 0xA0;
	P2 = P2 & 0x1F;
}

bsp_init.h

#ifndef _BSP_INIT_H
#define _BSP_INIT_H

#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int 
#endif

#include "STC15F2K60S2.H"

void cls_peripheral(void);
void UartInit(void);

#endif

bsp_led.c

#include "bsp_led.h"

void LED_Disp(uchar LED)
{
	P0 = ~LED;
	P2 = P2 & 0x1F | 0x80;
	P2 = P2 & 0x1F;
}

bsp_seg.c

#include "bsp_seg.h"

void SEG_Disp(uchar *seg_buf, uchar seg_pos)
{
	P0 = 0xFF;
	P2 = P2 & 0x1F | 0xe0;
	P2 = P2 & 0x1F;
	
	P0 = 1 << seg_pos;
	P2 = P2 & 0x1F | 0xc0;
	P2 = P2 & 0x1F;
	
	P0 = seg_buf[seg_pos];
	P2 = P2 & 0x1F | 0xe0;
	P2 = P2 & 0x1F;
}

void SEG_Tran(uchar *seg_string, uchar *seg_buf)
{
	uchar i,j,temp;
	
	for (i=0,j=0;i<8;i++,j++)
	{
		switch (seg_string[j])
		{
			case '0': temp = 0xc0; break;
			case '1': temp = 0xf9; break;
			case '2': temp = 0xa4; break;
			case '3': temp = 0xb0; break;
			case '4': temp = 0x99; break;
			case '5': temp = 0x92; break;
			case '6': temp = 0x82; break;
			case '7': temp = 0xf8; break;
			case '8': temp = 0x80; break;
			case '9': temp = 0x90; break;
			
			case 'C': temp = 0xc6; break;
			case '-': temp = 0xbf; break;
			case ' ': temp = 0xff; break;
			default: temp = 0xff;
		}
		if (seg_string[j+1] == '.')
		{
			temp = temp & 0x7F;
			j++;
		}
		seg_buf[i] = temp;
	}
}

bsp_key.c

#include "bsp_key.h"

uchar KEY_READ_BIN(void)
{
	uchar key_value;
	
	if (P30 == 0) key_value = 7;
	else if (P31 == 0) key_value = 6;
	else if (P32 == 0) key_value = 5;
	else if (P33 == 0) key_value = 4;
	else key_value = 0;
	
	return key_value;
}

uchar KEY_READ_KBD(void)
{
	uchar key_value;
	uint key_new;
	
	P44 = 0; P42 = 1; P35 = 1; P34 = 1;
	key_new = P3 & 0x0F;
	P44 = 1; P42 = 0; P35 = 1; P34 = 1;
	key_new = (P3 & 0x0F) | (key_new << 4);
	P44 = 1; P42 = 1; P35 = 0; P34 = 1;
	key_new = (P3 & 0x0F) | (key_new << 4);
	P44 = 1; P42 = 1; P35 = 1; P34 = 0;
	key_new = (P3 & 0x0F) | (key_new << 4);
	
	switch(~key_new)
	{
		case 0x8000: key_value = 4; break;
		case 0x4000: key_value = 5; break;
		case 0x2000: key_value = 6; break;
		case 0x1000: key_value = 7; break;
		
		case 0x0800: key_value = 8; break;
		case 0x0400: key_value = 9; break;
		case 0x0200: key_value = 10; break;
		case 0x0100: key_value = 11; break;
		
		case 0x0080: key_value = 12; break;
		case 0x0040: key_value = 13; break;
		case 0x0020: key_value = 14; break;
		case 0x0010: key_value = 15; break;
		
		case 0x0008: key_value = 16; break;
		case 0x0004: key_value = 17; break;
		case 0x0002: key_value = 18; break;
		case 0x0001: key_value = 19; break;
		
		default: key_value = 0;
	}
	
	return key_value;
}

bsp_onewire.h

#include "bsp_onewire.h"

sbit DQ = P1^4;  //单总线接口

//单总线延时函数
void Delay_OneWire(unsigned int t)  //STC89C52RC
{
	t=t * 12;
	while(t--);
}

void delay_us(void)
{
	uchar i = 30;
	while(--i);
}

//通过单总线向DS18B20写一个字节
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);
}

//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
	unsigned char i;
	unsigned char dat;
  
	for(i=0;i<8;i++)
	{
		DQ = 0;
		dat >>= 1;
		DQ = 1;
		delay_us();
		
		if(DQ)
		{
			dat |= 0x80;
		}	    
		Delay_OneWire(5);
	}
	return dat;
}

//DS18B20设备初始化
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;
}

uint READ_Tempature(void)
{
	uchar low,high;
	
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0x44);
	
	init_ds18b20();
	Write_DS18B20(0xCC);
	Write_DS18B20(0xBE);
	
	low = Read_DS18B20();
	high = Read_DS18B20();
	
	return (high<<8) | low;
}

bsp_ds1302

#include <bsp_ds1302.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												


//读取RTC
void RTC_READ(uchar *RTC)
{
	uchar temp;
	
	temp = Read_Ds1302_Byte(0x85);
	RTC[0] = (temp>>4)*10 + temp&0x0F;
	temp = Read_Ds1302_Byte(0x83);
	RTC[1] = (temp>>4)*10 + temp&0x0F;
	temp = Read_Ds1302_Byte(0x81);
	RTC[2] = (temp>>4)*10 + temp&0x0F;
}
	

//设置RTC
void RTC_SET(uchar *RTC)
{
	uchar temp;
	
	Write_Ds1302_Byte(0x8e, 0);
	
	temp = ((RTC[0]/10)<<4) | (RTC[0]%10);
	Write_Ds1302_Byte(0x84,temp);
	temp = ((RTC[1]/10)<<4) | (RTC[1]%10);
	Write_Ds1302_Byte(0x82,temp);
	temp = ((RTC[2]/10)<<4) | (RTC[2]%10);
	Write_Ds1302_Byte(0x80,temp);
	
	Write_Ds1302_Byte(0x8e, 0x80);
}

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

bsp_iic.c

#include "bsp_iic.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
    SDA = 0;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
    unsigned char i, da;
    for(i=0; i<8; i++)
    {   
    	SCL = 1;
	IIC_Delay(DELAY_TIME);
	da <<= 1;
	if(SDA) da |= 1;
	SCL = 0;
	IIC_Delay(DELAY_TIME);
    }
    return da;    
}

//读ROM
void EEPROM_Read(uchar *rom_string, uchar addr, uchar num)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0xa1);
	IIC_WaitAck();
	
	while(num--)
	{
		*rom_string++ = IIC_RecByte();
		if (num)
			IIC_SendAck(0);
		else
			IIC_SendAck(1);
	}
}
	

//写ROM
void EEPROM_Write(uchar *rom_string, uchar addr, uchar num)
{
	IIC_Start();
	IIC_SendByte(0xa0);
	IIC_WaitAck();
	
	IIC_SendByte(addr);
	IIC_WaitAck();
	
	while(num--)
	{
		IIC_SendByte(*rom_string++);
		IIC_WaitAck();
		IIC_Delay(200);
	}
	
	IIC_Stop();
	IIC_Delay(200);
}

//读PCF8591,ADC
uchar PCF8591_ADC(uchar channel)
{
	uchar temp;
	
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(channel);
	IIC_WaitAck();
	
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	
	temp = IIC_RecByte();
	IIC_SendAck(1);
	IIC_Stop();
	
	return temp;
}

//写PCF8591,DAC
void PCF8591_DAC(uchar dat)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	
	IIC_SendByte(0x42);
	IIC_WaitAck();
	
	IIC_SendByte(dat);
	IIC_WaitAck();
	IIC_Stop();
}

bsp_ultrasonic.c

#include "bsp_ultrasonic.h"

sbit TX = P1 ^ 0;
sbit RX = P1 ^ 1;

void Timer0Init(void)		//13微秒@12.000MHz
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xF3;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 0;		//定时器0开始计时
}

uchar Wave_Recv(void)
{
	uchar distance, num = 10;

	//超声波发送代码
	TX = 0;
	TL0 = 0xF3;		//设置定时初值
	TH0 = 0xFF;		//设置定时初值
	TR0 = 1;
	while(num--)
	{
		while(!TF0);
		TX ^= 1;
		TF0 = 0;
	}
	
	//超声波接收代码
	TR0 = 0;
	TL0 = 0;
	TH0 = 0;
	TR0 = 1;
	while(RX && (!TF0));
	TR0 = 0;
	if (TF0)
	{
		TF0 = 0;
		distance = 255;
	}
	else
		distance = ((TH0<<8)+TL0)*0.017*1.085;
	
	return distance;## 标题
}

其他部分

频率测量

//定时器1中断函数部分
if (++freq_num >= 1000)
	{
		TR0 = 0;
		freq = (TH0<<8)|TL0;
		freq_num = 0;
		
		Timer0Init_Freq();
	}

串口部分

//串口专用变量
uchar uart_send_string[12];
uchar uart_recv_string[12];
uchar uart_recv_num;
//串口中断
void Uart_ISR(void) interrupt 4
{
	if (RI)
	{
		uart_recv_string[uart_recv_num] = SBUF;
		uart_recv_num++;
		RI = 0;
	}
}
//串口处理函数
void UART_Proc(void)
{
	if (uart_delay) return;
	uart_delay = 1;
	
	if ((uart_recv_string[uart_recv_num-1] == '\n') && (uart_recv_string[uart_recv_num-2] == '\r'))
	{
		if (uart_recv_num == 4)
		{
			if((uart_recv_string[0] == 'S') && (uart_recv_string[1] == 'T'))
			{
				uart_recv_num = 0;
				sprintf(uart_send_string, "had recv ST\r\n");
				Uart_Sendstring(uart_send_string);
			}
		}
		else
		{
			uart_recv_num = 0;
			sprintf(uart_send_string, "ERROR\r\n");
			Uart_Sendstring(uart_send_string);
		}
	}
	
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值