题目



代码
这次的题目就是有一个细节,下降沿刷新事件比较的有意思,稍微不注意可能就会写错,其他也是中规中矩的考,和之前出现的都差不多
timer.c
#include <timer.h>
/**
* @Function Timer0Init
* @author STC_isp
* @date 2020/7/7
* @Description: 定时器0的初始化
* @param void
* @return void
* @History 无
*/
void Timer0Init(void) //1毫秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x18; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=ET0=1;
}
timer.h
#ifndef _TIMER_H_
#define _TIMER_H_
#include <STC15F2K60S2.H>
void Timer0Init(void);
#endif
smg.c
#include <smg.h>
unsigned char code smgduan[24]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90
,0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10
,0XC1,0X8C,0XC8,0XFF};
//U:20 P:21 N:22 灭:23
unsigned char dspbuf[8];
/**
* @Function smg_display
* @author Barry
* @date 2020/7/7
* @Description: 数码管的显示函数
* @param void
* @return void
* @History 无
*/
void smg_display(void)
{
static unsigned char i=0;
P2=(P2&0X1F)|0XE0;
P0=0XFF;
P2&=0X1F;
P2=(P2&0X1F)|0XC0;
P0=(1<<i);
P2&=0X1F;
P2=(P2&0X1F)|0XE0;
P0=smgduan[dspbuf[i]];
P2&=0X1F;
if(++i==8)
i=0;
}
smg.h
#ifndef _SMG_H_
#define _SMG_H_
#include <STC15F2K60S2.H>
extern unsigned char dspbuf[8];
void smg_display(void);
#endif
keybord.c
#include <keybord.h>
unsigned char i=0,key_value,key_sum=0,key_press;
/**
* @Function keybord_read
* @author Barry
* @date 2020/7/7
* @Description: 矩阵键盘行列扫描
* @param void
* @return void
* @History 无
*/
void keybord_read(void)
{
P3=0XF0;
P42=P44=1;
if(P44==0||P42==0||P35==0||P34==0)
{
for(i=0;i<4;i++)
{
P3=0XFF;
P42=P44=1;
P3&=~(1<<i);
if(P44==0) key_value=4*i;
else if(P42==0) key_value=4*i+1;
else if(P35==0) key_value=4*i+2;
else if(P34==0) key_value=4*i+3;
}
if(++key_sum==1)
key_press=1;
}
else
key_sum=0;
}
keybord.h
#ifndef _KEYBORD_H_
#define _KEYBORD_H_
#include <STC15F2K60S2.H>
extern unsigned char key_value;
extern unsigned char key_press;
void keybord_read(void);
#endif
iic.c
#include <iic.h>
#include "intrins.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
void IIC_Start(void)
{
SDA = 1;
SCL = 1;
somenop;
SDA = 0;
somenop;
SCL = 0;
}
//总线停止条件
void IIC_Stop(void)
{
SDA = 0;
SCL = 1;
somenop;
SDA = 1;
}
//等待应答
bit IIC_WaitAck(void)
{
SDA = 1;
somenop;
SCL = 1;
somenop;
if(SDA)
{
SCL = 0;
IIC_Stop();
return 0;
}
else
{
SCL = 0;
return 1;
}
}
//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(byt&0x80)
{
SDA = 1;
}
else
{
SDA = 0;
}
somenop;
SCL = 1;
byt <<= 1;
somenop;
SCL = 0;
}
}
//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
unsigned char da;
unsigned char i;
for(i=0;i<8;i++)
{
SCL = 1;
somenop;
da <<= 1;
if(SDA)
da |= 0x01;
SCL = 0;
somenop;
}
return da;
}
/**
* @Function adc_read
* @author Barry
* @date 2020/7/7
* @Description: 读取adc值
* @param void
* @return void
* @History 无
*/
unsigned char adc_read(void)
{
unsigned char dat;
IIC_Start();
IIC_SendByte(0X90);
IIC_WaitAck();
IIC_SendByte(0X03);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0X91);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_Stop();
return dat;
}
/**
* @Function eeprom_write
* @author Barry
* @date 2020/7/7
* @Description: 写对应的数据到eeprom对应的地址
* @param 1 addr
* @param 2 dat
* @return void
* @History 无
*/
void eeprom_write(unsigned char addr,unsigned char dat)
{
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
/**
* @Function eeprom_write
* @author Barry
* @date 2020/7/7
* @Description: 从对应的eeprom地址读出对应的数据
* @param addr
* @return void
* @History 无
*/
unsigned char eeprom_read(unsigned char addr)
{
unsigned char dat=0;
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Start();
IIC_SendByte(0XA1);
IIC_WaitAck();
dat=IIC_RecByte();
IIC_Stop();
return dat;
}
iic.h
#ifndef _IIC_H_
#define _IIC_H_
#include <STC15F2K60S2.H>
unsigned char adc_read(void);
void eeprom_write(unsigned char addr,unsigned char dat);
unsigned char eeprom_read(unsigned char addr);
#endif
main.c
/*********************************************
File name: 电压调节器
Author: Barry
Version 1.0
Description: 2020/7/5 第11届蓝桥杯省赛第一场
Others: 无
Log: 无
*********************************************/
#include <STC15F2K60S2.H>
#include <timer.h>
#include <smg.h>
#include <keybord.h>
#include <iic.h>
//标志位
unsigned char flag_key;
unsigned char flag_adc;
unsigned char flag_smg=0;
unsigned char flag_1s;
unsigned char count_5s=0; //5秒计时
unsigned char s12_count=0; //s12按下的次数
long adc_dat;
unsigned int v; //v
unsigned int vp; //vp
unsigned char vp_save;
unsigned char count=0; //计数值
unsigned char error1=0,error2=0,error3=0; //每个界面的误操作次数
unsigned char L1_temp,L2_temp,L3_temp; //L1,L2,L3
unsigned char flag1=0,flag2=0,flag3=0,flag4=0; //判断下降沿
/**
* @Function all_init
* @author Barry
* @date 2020/7/7
* @Description: 初始化,关闭蜂鸣器,LED,继电器等
* @param void
* @return void
* @History 无
*/
void all_init(void)
{
P2=(P2&0X1F)|0XA0;
P0=0X00;
P2&=0X1F;
P2=(P2&0X1F)|0X80;
P0=0XFF;
P2&=0X1F;
}
/**
* @Function eeprom_init
* @author Barry
* @date 2020/7/7
* @Description: 初始化eeprom,读出0X00的数据并处理
* @param void
* @return void
* @History 无
*/
void eeprom_init(void)
{
if(eeprom_read(0X80)==0X55)
{
vp_save=eeprom_read(0X00);
vp=vp_save*10;
}
else
{
eeprom_write(0X80,0X55);
vp_save=0;
}
}
/**
* @Function main
* @author Barry
* @date 2020/7/7
* @Description: 主函数
* @param void
* @return void
* @History 无
*/
void main(void)
{
all_init();
Timer0Init();
eeprom_init();
while(1)
{
/**********KEY**********/
if(flag_key)
{
flag_key=0;
keybord_read();
}
if(key_press)
{
key_press=0;
if(key_value==14)
{
if(++s12_count==3)
s12_count=0;
switch(s12_count)
{
case 0: flag_smg=0;error2=0;error3=0;break;
case 1: flag_smg=1;error1=0;error3=0;break;
case 2:
flag_smg=2;
error1=0;
error2=0;
vp_save=vp/10;
eeprom_write(0X00,vp_save);
break;
}
}
if(flag_smg==0)
{
if(key_value==14)
error1=0;
else
error1++;
}
if(flag_smg==1)
{
if(key_value==15)
{
if(vp<500)
{
vp+=50;
error2=0;
}
else if(vp==500)
{
error2=0;
vp=0;
}
}
else if(key_value==11)
{
if(vp>0)
{
vp-=50;
error2=0;
}
else if(vp==0)
{
error2=0;
vp=500;
}
}
else if(key_value!=11 && key_value!=15 && key_value!=14)
error2++;
}
if(flag_smg==2)
{
if(key_value==10)
{
count=0;
error3=0;
}
else if(key_value!=10 && key_value!=14)
error3++;
}
}
/**********LED**********/
if(v<vp)
{
if(flag_1s)
{
flag_1s=0;
if(++count_5s>6)
L1_temp=0XF8;
else
L1_temp=0XF9;
}
}
else
{
L1_temp=0XF9;
count_5s=0;
}
if(count%2==0) //L2
L2_temp=0XFA;
else
L2_temp=0XF8;
if(error1>=3||error2>=3||error3>=3) //L3
L3_temp=0XF8;
else
L3_temp=0XFC;
P2=(P2&0X1F)|0X80;
P0=(L1_temp|L2_temp|L3_temp);
P2&=0X1F;
/**********ADC**********/
if(flag_adc)
{
flag_adc=0;
adc_dat=adc_read();
}
v=(unsigned int)(adc_dat*500/255);
/**********count**********/
if(v>vp)
{
flag1=1;
flag3=1;
flag4=0;
}
if(v<vp)
{
flag2=1;
flag4=1;
flag3=0;
}
if((flag1==1) && (flag2==1) && (flag3==0) && (flag4==1))
{
count++;
flag1=0;
flag2=0;
}
/**********SMG**********/
if(flag_smg==0)
{
dspbuf[0]=20;
dspbuf[1]=23;
dspbuf[2]=23;
dspbuf[3]=23;
dspbuf[4]=23;
dspbuf[5]=v/100+10;
dspbuf[6]=v%100/10;
dspbuf[7]=v%10;
}
if(flag_smg==1)
{
dspbuf[0]=21;
dspbuf[1]=23;
dspbuf[2]=23;
dspbuf[3]=23;
dspbuf[4]=23;
dspbuf[5]=vp/100+10;
dspbuf[6]=vp%100/10;
dspbuf[7]=vp%10;
}
if(flag_smg==2)
{
dspbuf[0]=22;
dspbuf[1]=23;
dspbuf[2]=23;
dspbuf[3]=23;
dspbuf[4]=23;
dspbuf[5]=23;
dspbuf[6]=count/10;
dspbuf[7]=count%10;
}
}
}
/**
* @Function timer0_isr
* @author Barry
* @date 2020/7/7
* @Description: 定时器0中断服务函数
* @param void
* @return void
* @History 无
*/
void timer0_isr(void) interrupt 1
{
static unsigned char flag_key_time=0;
static unsigned char flag_adc_time=0;
static unsigned int flag_1s_time=0;
if(++flag_key_time==30)
{
flag_key_time=0;
flag_key=1;
}
if(++flag_adc_time==100) //0.1S
{
flag_adc_time=0;
flag_adc=1;
}
if(++flag_1s_time==1000)
{
flag_1s_time=0;
flag_1s=1;
}
smg_display();
}
本次蓝桥杯省赛中,一道涉及单片机的题目成为焦点。题目中的下降沿刷新事件处理需格外注意,稍有不慎可能导致错误。参赛者需熟练掌握相关代码编写,如timer.c/h、smg.c/h、keybord.c/h、iic.c/h及main.c等文件的应用。

1020

被折叠的 条评论
为什么被折叠?



