题目是超声波测量可能大家比较陌生,这也是省赛第一次出,如果知道这个模块的话还是比较简单的(跟其他模块也差不多)然后下面 就贴代码了 。想要源码的工程文件可以去博主的资源中下载(免费)点点关注就行。
一.先看主函数
#include "config.h"
#include "iic.h"
void main()
{
Init_System();//初始化
while(1){
if(flag_v) //电压采集标志位
{
flag_v=0;
sum_v= read_adc()*1.96; //电压采集
if(sum_v>(param_min*10)&&sum_v<(param_max*10)) //电压在参数之间
flag_wave=1; //启用超声波功能
else flag_wave=0;
if(flag_wave)
{
wave= wave_recv(); //测距
if(wave<=20)dac_out(1*51);
else if(wave>=20&&wave<=80)dac_out((wave*0.067-0.034)*51);
else dac_out(255);
}
else dac_out(0);
}
scan_kbd();//扫描键盘
key_real(); //按键功能
SMG_show(); //数码管赋值
}
}
二.配置文件
#include "config.h"
#include "intrins.h"
unsigned char key_num=16;
unsigned char segbuff[8]={0};
unsigned int count_v=0;//电压采集计数
bit flag_v=0 ;//电压可以采集标志
unsigned int sum_v=0; //采集的电压数据
unsigned int param_max=30; //参数电压上限
unsigned int param_min=15; //参数电压下限
unsigned int min_old=15; //设置的参数下限
unsigned int max_old=30; //设置的参数上限
unsigned int wave=10; //超声波距离
unsigned char mod1=0; //界面切换
unsigned char mod2=0; //模式切换
bit flag_wave=0;//超声波可以采集标志
unsigned int count_w=0;
unsigned char segtab[]={0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff, //Ϩİ -10
0xc1, //U -11
0xc0&0x7f,0xf9&0x7f,0xa4&0x7f,0xb0&0x7f,0x99&0x7f,0x92&0x7f,
0x82&0x7f,0xf8&0x7f,0x80&0x7f,0x90&0x7f,0x8c,0xc7,0x88
};
void Timer0Init(void) //12??@12.000MHz
{
//12T 12ms
AUXR &= 0x7F;
TMOD &= 0xF0;
TL0 = 0xF4;
TH0 = 0xFF;
TF0 = 0;
TR0 = 1;
}
unsigned char wave_recv()
{
unsigned char ucdist,num=10;
TX=0;
TL0=0xf4;
TH0=0xff;
TR0=1;
//发送40Khz频率
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;
ucdist=255;
}
else //测距成功
ucdist=((TH0<<8)+TL0)*0.017;
return ucdist;
}
void time0 (void) //1??@12.000MHz
{
//1T 1ms
AUXR &= 0xBF;
TMOD &= 0x0F;
TL1 = 0x18;
TH1 = 0xFC;
TF1 = 0;
TR1 = 1;
EA = 1;
ET1= 1;
}
void Timer0() interrupt 3
{
TL1 = 0x18;
TH1 = 0xFC;
segs(); //刷新数码管
count_v++; //采集电压计数
count_w++;
if(count_v==300) 0.3s采集一次
{
count_v=0;
flag_v=1; //可以采集
}
led_work(); //led灯
}
void segs()
{
static unsigned char wei=0;
P2=P2&0x1f|0xe0;
P0=0xff;
P2=P2&0x1f|0xc0;
P0=1<<wei;
P2=P2&0x1f|0xe0;
P0=segtab[segbuff[wei]];
if(++wei==8)wei=0;
}
void scan_kbd()
{
static unsigned char state=0;
unsigned char key_press;
switch(state)
{
case state_0:
kbd_io=0x0f;
key_press=kbd_io;
if(key_press!=kbd_maskrow)
state=state_1;
break;
case state_1:
key_press=kbd_io;
if(key_press!=kbd_maskrow)
{
if((kbd_io&0x08)==0)key_num=0; //S4
if((kbd_io&0x04)==0)key_num=1; //S5
if((kbd_io&0x02)==0)key_num=2; //S6
if((kbd_io&0x01)==0)key_num=3; //S7
state=state_2;
}
else state=state_0;
break;
case state_2:
kbd_io=0x0f;
key_press=kbd_io;
if(key_press==kbd_maskrow)state=state_0;
break;
default :break;
}
}
void key_real()
{
switch(key_num)
{
case 0:
mod1++; //界面切换
if(mod1==3)mod1=0;
if(mod1==0)
{ param_min=min_old;
param_max=max_old;
}
if(mod1==1)
{
min_old=param_min;
max_old=param_max;
}
break;
case 1: //模式切换
mod2++;
if(mod2==2)mod2=0;
break;
case 2:
if(mod1==2)
{
if(mod2)
{
min_old+=5;
if(min_old>50)min_old=0;
}
else
{
max_old+=5;
if(max_old>50)max_old=0;
}
}
break;
case 3:
if(mod1==2)
{
if(mod2)
{
if(min_old==0)min_old=50;
else min_old-=5;
}
else
{
if(max_old==0)max_old=50;
else max_old-=5;
}
}
break;
default :break;
}
key_num=16;
}
void SMG_show()
{
switch(mod1)
{
//显示电压界面
case 0: segbuff[0]=11;
segbuff[1]=10;
segbuff[2]=10;
segbuff[3]=10;
segbuff[4]=10;
segbuff[5]=sum_v/100+12;
segbuff[6]=sum_v/10%10;
segbuff[7]=sum_v%10;
break;
//显示参数界面
case 2:
segbuff[0]=22;
segbuff[1]=10;
segbuff[2]=10;
segbuff[3]=max_old/10;
segbuff[4]=max_old%10;
segbuff[5]=10;
segbuff[6]=min_old/10;
segbuff[7]=min_old%10;
break;
//显示超声波界面
case 1:
segbuff[0]=23;
segbuff[1]=10;
segbuff[2]=10;
segbuff[3]=10;
segbuff[4]=10;
if(flag_wave)
{
if(wave>99)
segbuff[5]=wave/100;
else segbuff[5]=10;
segbuff[6]=wave/10%10;
segbuff[7]=wave%10;
}
else
{
segbuff[5]=24;
segbuff[6]=24;
segbuff[7]=24;
}
break;
}
}
void led_work()
{
unsigned char old=P0;
P2=P2&0x1f|0x00;
P0=0xff;
if(mod1==0)
{
P2=P2&0x1f|0x80;
P0=0xfe;
}
else if(mod1==1)
{
P2=P2&0x1f|0x80;
P0=0xfd;
}
else if(mod1==2)
{
P2=P2&0x1f|0x80;
P0=0xfb;
}
P2=P2&0x1f;
P0=old;
}
//初始化
void Init_System()
{
P2=P2&0x1f|0x80;
P0=0xff;
P2=P2&0x1f|0xa0;
P0=0xaf;
time0();
Timer0Init();
}
三.H操作
#ifndef _CONFIG_H
#define _CONFIG_H
#include <STC15F2K60S2.H>
#define kbd_io P3
#define state_0 0
#define state_1 1
#define state_2 2
#define kbd_maskrow 0x0f
sbit TX=P1^0;
sbit RX=P1^1;
extern unsigned int wave;
extern unsigned int sum_v;
extern bit flag_v;
extern bit flag_wave;
extern unsigned int param_max; //֧ѹʏО
extern unsigned int param_min;
extern bit flag_w;
void segs();
void SMG_show();
void scan_kbd();
void segs();
unsigned char wave_recv();
void time0();
void led_work();
void key_real();
void Init_System();
void Timer0Init(void);
#endif
其他IIC.c
/* # I2C代码片段说明
1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。
2. 参赛选手可以自行编写相关代码或以该代码为基础,根据所选单片机类型、运行速度和试题
中对单片机时钟频率的要求,进行代码调试和修改。
*/
#include <STC15F2K60S2.H>
#include <intrins.h>
#define DELAY_TIME 5
sbit SCL =P2^0;
sbit SDA=P2^1;
//
static void I2C_Delay(unsigned char n)
{
do
{
nop_();
}
while(n--);
}
//
void I2C_Start(void)
{
SDA = 1;
SCL = 1;
I2C_Delay(DELAY_TIME);
SDA = 0;
I2C_Delay(DELAY_TIME);
SCL = 0;
}
//
void I2C_Stop(void)
{
SDA = 0;
SCL = 1;
I2C_Delay(DELAY_TIME);
SDA = 1;
I2C_Delay(DELAY_TIME);
}
//
void I2C_SendByte(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 I2C_ReceiveByte(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 I2C_WaitAck(void)
{
unsigned char ackbit;
SCL = 1;
I2C_Delay(DELAY_TIME);
ackbit = SDA;
SCL = 0;
I2C_Delay(DELAY_TIME);
return ackbit;
}
//
void I2C_SendAck(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 dac_out(unsigned int dat)
{
I2C_Start();
I2C_SendByte(0x90);
I2C_WaitAck();
I2C_SendByte(0x40);
I2C_WaitAck();
I2C_SendByte(dat);
I2C_WaitAck();
I2C_Stop();
}
unsigned int read_adc()
{
unsigned int dat;
I2C_Start();
I2C_SendByte(0x90);
I2C_WaitAck();
I2C_SendByte(0x03);
I2C_WaitAck();
I2C_Stop();
I2C_Start();
I2C_SendByte(0x91);
I2C_WaitAck();
dat=I2C_ReceiveByte();
I2C_SendAck(1);
I2C_Stop();
return dat;
}
IIC.H
#ifndef _I2C_H #define _I2C_H void I2C_Start(void); void I2C_Stop(void); void I2C_SendByte(unsigned char byt) ; unsigned char I2C_ReceiveByte(void); unsigned char I2C_WaitAck(void); void I2C_SendAck(unsigned char ackbit); void dac_out(unsigned int dat); unsigned int read_adc(); #endif