基本模块
蜂鸣器继电器
(1)继电器 P04 0X10 蜂鸣器P06 0X40
数码管
void Display()
{
static unsigned char com=0;
InitHC138(7);
P0=0xff;
InitHC138(0);
InitHC138(6);
P0=0x01<<com;
InitHC138(0);
InitHC138(7);
P0=duanma[buff[com]];
InitHC138(0);
com++;
if(com==8){com=0;}
}
(1)左边的数码管为缓冲区的0,右边为7
AD/DA转换
unsigned int voltint;
unsigned char volt;
if(volt_flag)
{
volt_flag=0;
volt=ADRead(0x03);01光敏,03电位器
voltint=volt*100/51;
}
unsigned char ADRead(unsigned char addr)//读电压90+91
{
unsigned char value;
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();//第一组没有STOP
I2CStart();
I2CSendByte(0x91);
I2CWaitAck();
value=I2CReceiveByte();
I2CSendAck(1);//注意读的话是SendAck(1)
I2CStop();
return value;
}
}
void DAWrite(unsigned char dat)//读90+40/43
{
I2CStart();
I2CSendByte(0x90);
I2CWaitAck();
I2CSendByte(0x43);//如果是同时用43,用一个40
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
(1)光敏电阻0X01,电位器0X03
EEPROM
unsigned char EEPROMRead(unsigned char dat)
{
unsigned char value;
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStart();
I2CSendByte(0xA1);
I2CWaitAck();
value=I2CReceiveByte();
I2CSendAck(1);
I2CStop();//别忘了STOP
Delay10ms();//延时
return value;
}
void EEPROMWrite(unsigned char addr,unsigned char dat)
{
I2CStart();
I2CSendByte(0xA0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
Delay10ms();
}
超声波
sbit TX=P1^0;
sbit RX=P1^1;
void SendWave()
{
unsigned char i;
for(i=0;i<8;i++)
{
TX=1;
Delay12us();
TX=0;
Delay12us();
}
}
unsigned char ReadDistance()
{
unsigned int time;
AUXR&=0XBF;
TMOD&=0X0F;
TH1=TL1=0;
SendWave();
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1==0)
{
time=(TH1<<8)|TL1;
return 0.017*time;
}else if(TF1==1)
{
TF1=0;
return 0;
}
}
时钟ds1302
#include <STC15F2K60S2.H>
#include <intrins.h>
sbit RST=P1^3;
sbit SCK=P1^7;
sbit SDA=P2^3;
void SetTime()
{
Write_Ds1302_Byte(0x80,0x30);
Write_Ds1302_Byte(0x82,0x27);
Write_Ds1302_Byte(0x84,0x18);
}
void ReadTime()
{
now[0]=Read_Ds1302_Byte(0x81);
now[1]=Read_Ds1302_Byte(0x83);
now[2]=Read_Ds1302_Byte(0x85);
}
定时器2
void Timer2Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x04; //定时器时钟1T模式
T2L = 0x20; //设置定时初值
T2H = 0xD1; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
IE2|=0x04;//开定时器2中断,中断号为12
EA=1;
}
温度DS18B20
sbit DQ=P1^4;
float ReadTemperature()
{
unsigned char 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)/16.0;
}
if(temp_flag)
{
temp_flag=0;
temp=ReadTemperature;
tempint=(unsigned int)(100*temp);
}
LED灯显示
void LED(unsigned char addr,unsigned char enable)
{
static unsigned char temp;
static unsigned char temp_old;
if(enable)
{
temp|=(0x01<<(addr-1));
}else
{
temp&=~(0x01<<(addr-1));
}
if(temp!=temp_old)
{
InitHC138(4);
P0=~temp;
InitHC138(0);
temp_old=temp;
}
}
额外功能
按键双击
unsigned char key_count1,key_count2;
void ServiceKBD()
{
key_value=ScanKBD();
switch(key_value)
{
case 19:
LED(1,1);
key_count1++;
if(key_count1==2)
{
LED(3,1);
key_count1=0;
}
key_value=0;
break;
case 15:
LED(1,0);
key_count2++;
if(key_count2==2)
{
LED(3,0);
key_count2=0;
}
key_value=0;
break;
case 11:
LED(2,1);
key_value=0;
break;
case 7:
LED(2,0);
key_value=0;
break;
}
}
主要实现:设置变量Key_count.每次按下Key_count++,并设置If(key_count==2)则{执行函数 清零key_count}
按键长按
if(P42==0)
{
F_key=1;keycount=0;
while(P42==0);F_key=0;
if(keycount>1000) {key_value=20;}
else {key_value=10;}
key_state=1;
}
case 20:
LED(4,1);
key_value=0;
break;
}
}
void ServiceTimer1() interrupt 3
{
static unsigned int time1;
Display();
time1++;
if(F_key==1){keycount++;}
if(time1==100){key_flag=1;time1=0;}
}
数据的采集采集触发
void Caiji()
{
miao0=miao1;
miao1=(now[0]/16)*10+now[0]%16;
if(mod==1)
{
if((miao1%timepara==0)&&(miao1!=miao0))
{
distance=ReadDistance();
i=i+1;
if(i==10) {i=0;}
distancer[i]=distance*10;
Jisuan();
}
}else if(mod==2)
{
if(volt>30)
{
Lightstate=1;
}
if(Lightstate==1)
{
if(volt<30)
{
Lightstate=0;//确保暗状态下不会再触发
distance=ReadDistance();
i=i+1;
if(i==10) {i=0;}
distancer[i]=distance*10;
Jisuan();
}
}
}
}
(1)触发条件:首先设置一个标志位,正常为1,被触发时为0
两个并列的if 第一个判断值正常时,标志位为1
第二个判断,当标志位为1时,如果值不正常,则执行读取
数据的保存
全局变量法:需要一个数组a[10]和一个计数变量i
读取即时变量到值b中
i=i+1;if(i==10) {i=0;}
保存b到a[i]中
对a[i]进行操作
LED闪烁
void Light()
{
if(shanshuo==1){LED(2,1);}
else if(shanshuo==0){LED(2,0);}
}
if(time3==500) {shanshuo=~shanshuo;time3=0;}
基础模版
Basic.c
#include "STC15F2K60S2.H"
void InitHC138(unsigned char n)
{
switch(n)
{
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;
case 0:
P2=P2&0x1f;
break;
}
}
void InitSystem()
{
InitHC138(4);
P0=0xff;
InitHC138(0);
InitHC138(5);
P0=P0&0xaf;
InitHC138(0);
}
void Delay10ms() //@12.000MHz
{
unsigned char i, j;
i = 117;
j = 184;
do
{
while (--j);
} while (--i);
}
unsigned char ScanKBD()
{
static unsigned char key_state=0;
unsigned char hang;
unsigned char key_value;
switch(key_state)
{
case 0:
P3=0x0f;P42=0;P44=0;
if(P3!=0x0f)
{
Delay10ms();
if(P3!=0x0f)
{
if(P30==0) {hang=1;}
if(P31==0) {hang=2;}
if(P32==0) {hang=3;}
if(P33==0) {hang=4;}
switch(hang)
{
case 1:
P3=0xf0;P42=1;P44=1;
if(P34==0){key_value=19;key_state=1;}
if(P35==0){key_value=15;key_state=1;}
if(P42==0){key_value=11;key_state=1;}
if(P44==0){key_value=7;key_state=1;}
break;
case 2:
P3=0xf0;P42=1;P44=1;
if(P34==0){key_value=18;key_state=1;}
if(P35==0){key_value=14;key_state=1;}
if(P42==0){key_value=10;key_state=1;}
if(P44==0){key_value=6;key_state=1;}
break;
case 3:
P3=0xf0;P42=1;P44=1;
if(P34==0){key_value=17;key_state=1;}
if(P35==0){key_value=13;key_state=1;}
if(P42==0){key_value=9;key_state=1;}
if(P44==0){key_value=5;key_state=1;}
break;
case 4:
P3=0xf0;P42=1;P44=1;
if(P34==0){key_value=16;key_state=1;}
if(P35==0){key_value=12;key_state=1;}
if(P42==0){key_value=8;key_state=1;}
if(P44==0){key_value=4;key_state=1;}
break;
}
}
}
break;
case 1:
P3=0x0f;P42=0;P44=0;
if(P3==0x0f) {key_state=0;}
break;
}
return key_value;
}
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x20; //设置定时初值
TH1 = 0xD1; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1=1;
EA=1;
}
void LED(unsigned char addr,enable)
{
static unsigned char temp=0x00;
static unsigned char temp_old=0xff;
if(enable)
{
temp|=0x01<<(addr-1);
}else
{
temp&=~(0x01<<(addr-1));//这个地方两层括号
}
if(temp!=temp_old)
{
InitHC138(4);
P0=~temp;
InitHC138(0);
temp_old=temp;
}
}
Basic.h
#ifndef __BASIC_H
#define __BASIC_H
void InitHC138(unsigned char n);
void InitSystem();
void Delay10ms();
unsigned char ScanKBD();
void Timer1Init(void);
void LED(unsigned char addr,enable);
#endif
main.c
#include <STC15F2K60S2.H>
#include <BASIC.H>
code unsigned char duanma[24]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xc7,0x89,0xfe,0xbf,0xf7,0x8c};//0-9,灭,A-F,-,L,H,上,中,下,P
unsigned char buff[8]={10,10,10,10,10,10,10,10};
unsigned char key_value;
void Display();
bit key_flag;
void ServiceKBD()
{
key_value=ScanKBD();
switch(key_value)
{
case 19:
LED(1,1);
key_value=0;
break;
case 15:
LED(1,0);
key_value=0;
break;
case 11:
LED(2,1);
key_value=0;
break;
case 7:
LED(2,0);
key_value=0;
break;
}
}
void ServiceTimer1() interrupt 3
{
static unsigned int time1;
Display();
time1++;
if(time1==100){key_flag=1;time1=0;}
}
void Displayf()
{
buff[0]=1;
}
void main()
{
InitSystem();
Timer1Init();
while(1)
{
if(key_flag) { key_flag=0; ServiceKBD();}
Displayf();
}
}
void Display()
{
static unsigned char com;
InitHC138(7);
P0=0xff;
InitHC138(0);
InitHC138(6);
P0=0x01<<com;
InitHC138(0);
InitHC138(7);
P0=duanma[buff[com]];
InitHC138(0);
if(++com==8) {com=0;}
}
基础模块主要包括:初始化函数2个,定时器1初始化1个,延时10ms函数1个,键盘扫描1个,LED一个
主函数包括:数码管显示函数
国赛总结
第十二届国赛(2021)总结
(1)国赛要用的界面多,在草稿纸上画树状图和标志位比较好
(2)题目没有涉及到数据的存储功能,因而只需算出最大值,最小值,平均值即可
备忘录
(1)别忘了把BASIC也放进去
常见报错
条件语句未结束,一般在h文件中