main.c
#include "main.h"
unsigned char tab[13]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF,0X8E};
unsigned char dsbuff[8]={11,11,11,11,11,11,11,11};
unsigned char com;
bit key5 = 0,key7 = 0,key6 = 0;//0-测距显示 1-回显
int key7_num;
unsigned char distince;
int ui_Sonic_flag;
int history[10];//距离历史数据
int num;//次数
int mangqu;//盲区
int result;//计算结果
int dis;//超声波测距结果用于和盲区比较
int dac_num;//dac输出
bit over = 0,start = 0;
bit option = 0;//操作
bit Sonic_flag;
int led_count;
bit led1_flag;//led1闪烁标志
int led_time;//led闪烁次数
bit led1,led7,led8;//led1 led7 led8标志位
int led1_count;
void main(void)
{
EA = 1;
all_init();
Timer0Init();
Timer1Init();
// eeprom_init();
eeprom_read();
mangqu = iic_read(0X00);
Delay3ms();
while(1)
{
Key_Individual();
Sonic_Proc();
dac_out();
if((key5 == 1))//数据回显
{
eeprom_read();
smg_display((key7_num+1)/10%10,(key7_num+1)/1%10,11,11,11,history[key7_num]/100%10,history[key7_num]/10%10,history[key7_num]/1%10);
}else if((key6 == 1))//参数设置
{
smg_display(12,11,11,11,11,mangqu/100%10,mangqu/10%10,mangqu/1%10);
}else if((key5 == 0)&&(key6 == 0))
{
distince_display();
}
if(over == 1)
{
while(led_time < 10)
{
if(led1_flag == 1)
{
led_one(0XFE);
}else if(led1_flag == 0)
{
led_one(0XFF);
}
}
if(led_time >= 10)
{
led_time = 0;
over = 0;
}
}
}
}
void distince_display(void)//测距显示界面
{
if(option == 0)//显示上一次测量数据
{eeprom_read();
if(num-2 < 0)
{
result = history[num-2+10];
}else if(num-2 >= 0)
{
result = history[num-2];
}
}else if(option == 1)显示上一次测量与本次测量数据
{eeprom_read();
if(num-2 < 0)
{
result = history[num-1+10]+history[num-2+10];
}else if(num-2 >= 0)
{
result = history[num-1]+history[num-2];
}
}
smg_display(option,11,result/100%10,result/10%10,result/1%10,history[num-1]/100%10,history[num-1]/10%10,history[num-1]/1%10);
}
//全部初始化
void all_init(void)
{
P2 &=0X1F;
P0=0XFF;
P2 = ((P2&0X1F)|0X80);
P2 &=0X1F;
P0=0X00;
P2 = ((P2&0X1F)|0XA0);
P2 &=0X1F;
P0=0XFF;
P2 = ((P2&0X1F)|0XE0);
P2 &=0X1F;
}
//数码管显示
void display(void)
{
P0 = 0XFF;
P2 = ((P2&0X1F)|0XE0);
P2 &= 0X1F;
P0 = 0X01<<com;
P2 = ((P2&0X1F)|0XC0);
P2 &= 0X1F;
P0 = tab[dsbuff[com]];
P2 = ((P2&0X1F)|0XE0);
P2 &= 0X1F;
if(++com >= 8)
com = 0;
}
//数码管显示函数
void smg_display(int s1,int s2,int s3,int s4,int s5,int s6,int s7,int s8)
{
dsbuff[0] = s1;dsbuff[1] = s2;
dsbuff[2] = s3;dsbuff[3] = s4;
dsbuff[4] = s5;dsbuff[5] = s6;
dsbuff[6] = s7;dsbuff[7] = s8;
}
//独立按键扫描
void Key_Individual(void)
{
P3 |= 0x0F;
if(P3_LOW4 != 0x0F)
{
Delay3ms();
if(P3_LOW4 != 0x0F)
{
switch(P3_LOW4)
{
case 0x0E://S7
if(key5 == 1)//回显
{
if(++key7_num >= 10)
{
key7_num = 0;
}
}else if(key5 == 0)
{
key7_num = 0;
}
if(key6 == 1)
{
mangqu+=10;
if(mangqu > 90)
{
mangqu = 0;
}
}
if((key5 == 0) && (key6 == 0))
{
option = ~option;
}
while(P3_LOW4 == 0x0E);
break;
case 0x0D://S6//参数设置
if(key5 == 0)
{
key6 = ~key6;//1-参数设置
if(key6 == 0)
{
iic_write(0X00,mangqu);
}
}
while(P3_LOW4 == 0x0D);
break;
case 0x0B://S5//数据回显
if(key6 == 0)
{
over = 0;
key5 = ~key5;
}
while(P3_LOW4 == 0x0B);
break;
case 0x07://S4
if((key5 == 0) && (key6 == 0))
{
start = 1;//启动测量
}
while(P3_LOW4 == 0x07);
break;
}
}
}
}
void dac_out(void)
{
if(mangqu >= dis)//输出0v
{
pcf8951_dac(0);
}else if(mangqu < dis)
{
dac_num = (dis - mangqu)*0.02;
if(dac_num > 5)//输出5v
{
pcf8951_dac(255);
}else {
pcf8951_dac(dac_num*51/5);
}
}
}
void led_option(void)//1、7、8
{
if(key6 == 1)//参数设置7亮
{
led_one(0XBF);
}if(key5 == 1)//数据回显8亮
{
led_one(0X7F);
}else if((key5 == 0)&&(key6 == 0))//全灭
{
led_one(0XFF);
}
}
//定时器
void Timer0Init(void) //12微秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xF4; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0停止计时
}
void Timer1Init(void) //2毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9A; //设置定时初值
TH1 = 0xA9; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
}
void timer1_isr() interrupt 3
{
display();
if(++ui_Sonic_flag == 50)
{
ui_Sonic_flag = 0; //超声波刷新频率 300ms一次
Sonic_flag = 1;
}
if(++led_count >= 10)
{
led_count = 0;
led_option();
}
if(over == 1)
{
if(++led1_count >= 100)
{
led1_count = 0;
led1_flag = ~led1_flag;
led_time++;
}
}
}
//超声波
//超声波数据处理函数
unsigned char Sonic(void)
{
unsigned char Dist , s_num=10;
TX = 0;
Timer0Init();
TR0 = 1;
while(s_num--)
{
while(!TF0);
TX ^= 1;
TF0 = 0;
}
TR0 = 0;
TL0 = 0;
TH0 = 0;
TR0 = 1;
while(RX && !TF0);
TR0 = 0;
if(TF0)
{
TF0 = 0;
Dist = 0;
}
else
{
Dist = ((TH0<<8)+TL0)*0.017;
}
return Dist;
}
void Sonic_Proc(void)
{
if(start == 1)
{
start = 0;
distince = Sonic(); //测距
iic_write(0x01+num,distince);Delay3ms();
history[num] = iic_read(0x01+num);Delay3ms();
dis = history[num];
over = 1;
if(++num >= 10)
{
num = 0;
}
}
}
void eeprom_read(void)
{
int i;
for(i=0;i<10;i++)
{
history[i] = iic_read(0x01+i);Delay3ms();Delay3ms();
}
}
//LED操作
void led_one(unsigned char dat)//单个LED操作
{
P0 = dat;
P2 = ((P2&0X1F)|0X80);
P2 &= 0X1F;
}
main.h
#ifndef _MAIN_H
#define _MAIN_H
#include "STC15F2K60S2.h"
#include "iic.h"
sbit TX = P1^0; //接收
sbit RX = P1^1; //发射
#define P3_LOW4 (P3&0x0F)
void all_init(void); //全部初始化
void display(void); //数码管显示
void smg_display(int s1,int s2,int s3,int s4,int s5,int s6,int s7,int s8);
void Key_Individual(void); //独立按键扫描
void Timer0Init(void); //2毫秒@11.0592MHz
void Timer1Init(void); //2微秒@11.0592MHz
void Sonic_Proc(void);
void distince_display(void); //测距显示界面
void dac_out(void);
void led_option(void);//1、7、8
void eeprom_read(void);
void led_one(unsigned char dat);//单个LED操作
#endif
iic.c
/*
程序说明: IIC总线驱动程序
软件环境: Keil uVision 4.10
硬件环境: CT107单片机综合实训平台(12MHz)
日 期: 2011-8-9
*/
#include "iic.h"
//总线启动条件
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;
}
void iic_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();
}
unsigned char iic_read(unsigned char addr)
{
unsigned char temp;
IIC_Start();
IIC_SendByte(0XA0);
IIC_WaitAck();
IIC_SendByte(addr);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0XA1);
IIC_WaitAck();
temp = IIC_RecByte();
IIC_WaitAck();
IIC_Stop();
return temp;
}
void pcf8951_dac(unsigned char dat)
{
IIC_Start();
IIC_SendByte(0X90);
IIC_WaitAck();
IIC_SendByte(0X40);
IIC_WaitAck();
IIC_SendByte(dat);
IIC_WaitAck();
IIC_Stop();
}
//3ms延时
void Delay3ms() //@12.000MHz
{
unsigned char i, j;
i = 36;
j = 1;
do
{
while (--j);
} while (--i);
}
void eeprom_init(void)
{
int i;
for( i = 0; i < 11;i++)
{
iic_write(0x00+i,0);Delay3ms();
}
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#include "STC15F2K60S2.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_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//函数声明
void IIC_Start(void);
void IIC_Stop(void);
//void IIC_Ack(unsigned char ackbit);
void IIC_SendByte(unsigned char byt);
bit IIC_WaitAck(void);
unsigned char IIC_RecByte(void);
void iic_write(unsigned char addr,unsigned char dat);//eeprom写操作
unsigned char iic_read(unsigned char addr);//eeprom读操作
void pcf8951_dac(unsigned char dat);//pcf8951_dac输出
void eeprom_init(void);
void Delay3ms() ; //3ms延时
#endif