/******************************************************************************* *
* 硬件介绍:单片机 89C52RC+ 12864标准字库液晶屏+ HC-SR04超声波模块 电子元件均由淘宝购于深圳
单片机用国产宏晶的STC89C52RC 通俗一点其功能是12M CPU(最高24M),256bt内存,8kb硬盘,32个I/O口和6个中断
* 硬件布局:逆行快车
* 软件编程:随你吧
* 编程语言:C语言
* 作品时间:2014年4月12日
* 作品介绍:非接触式测距 距离小的30厘米 声音报警 报警后,距离大于40厘米解除报警 报警声可变(距离越近越急促) 测距范围3CM-600CM 分辨率1CM 。
由于是新手上路,能力有限, 现在还不会在12864上显示大字体,只会显示字库带的字符汉字和自定义图形,上一份工作就职于 海 尔售后, 图片也是用的海尔的**
作品最早实现测距的时候,没有报警功能,这个还是按照汽车的倒车雷达的思路添加上去的,算是自己对自己作品的一个小小的软件升级吧,本来还想加上PWM调整LCD 亮度,一键添加/解除报警功能 ,可惜在电脑前坐的时间长了,心里过于烦躁,还是早早的交了试卷吧.以后有空了再自己添加。这是学习编程以来,独立完成的第一个实用作品, 之前学习的按键操作,LED,PWM,IIC等等,都还没有应用到实际的程序中来,这也是我在人工智能和设备自动化方面迈出的第一步,所以想记录下来,留作记念。
* 涉及知识点: 定时计数器中断的应用, 外部中断的应用(用GATE位配合外部中断进行正脉冲宽度测量) 12864液晶屏的驱动程序 12864显示字符和图片的方式
********************************************************************************/
#include <reg52.h> //载入52头文件
#define uchar unsigned char //伪定义
#define uint unsigned int //伪定义
uint bai,shi,ge,time,s; //定义千位 百位 十位 个位 时间 长度
//函数声明
void write_12864com(uchar com); //写指令
void write_12864dat(uchar dat); //写数据
void init (); //液晶屏初始化
void clr_screen(); // 清屏
void display1(); // 显示函数1
void display2(); // 显示函数2
unsigned char code haierphoto[];
unsigned char code haier[] ;
uchar code ling[];
void photodisplay(uchar *bmp);
void conut() ; //计算距离函数
void delay (uint t); //12864用延时,省去了忙检测函数
void delay20us(void); //发射超声波用延时
void delay1ms(int c); //蜂鸣器发声用延时函数
bit flag=1;
void beeb ();
uchar code table1[]={" 程序初始化中 "};
uchar table[]={'0','1','2','3','4','5','6','7','8','9'};
/************* 12864LCD引脚定义 *************/
#define LCD_data P0 //数据口
sbit rs = P2^5; //寄存器选择输入
sbit rw = P2^6; //液晶读/写控制
sbit e = P2^7; //液晶使能控制
sbit BEEB= P2^1; // P2.0接蜂鸣器
//sbit psb = P2^2; //串/并方式控制
//sbit rst = P3^7; //液晶复位端口
//超声波引脚定义
sbit trig = P3^0; //产生脉冲引脚
sbit echo = P3^2; //回波引脚
void main (void) //程序从这里开始
{
delay(20); // 稍作延时,等待各端口电平稳定
init(); // 液晶屏初始化
photodisplay(haierphoto);
delay(40000); // 开机画面保持的时间长度
clr_screen(); // 清除显示
photodisplay(haier);
delay(40000); // 开机画面保持的时间长度
clr_screen(); // 清除显示
display2(); // 显示开机画面
delay(20000); // 开机画面保持的时间长度
clr_screen(); // 清除显示
TMOD=0X09; // 定时计数器0 工作在定时状态,工作方式16位,且受门控GATE位的控制
EA=1; //允许总中断
ET0=1; //允许定时计数器0中断 这个代码没有用,它只计数,根本没有申请中断的可能
IT0=1; //外部中断0的触发方式为下降沿触发
while (1) //程序进入死循环,一直执行以下代码
{
EX0=1 ; //暂时关闭外部中断0,防止干扰
trig=0; // 拉低超声波发射端,准备发射超声波
trig=1; // 发射超声波
delay20us(); //发射超声波的时间为20US (大于10US,模块就能正常发射)
trig=0; // 关闭发射端。
while(echo==0); //超声波的接收端如果没有收到回波,则一直等待,收到回波后再接着执行以下代码
TR0=1; //( 执行这条语句的时候已经收到回波)定时器0开始定时
delay (200); //调用延时函数200次 (这个时间一定要大于回波的持续时间) 在此代码期间,外部中断0已向CPU申请中断
TR0=0; //停止定时器0工作这条语句其实没用,因为在上一条语句中,程序转到的外部中断0的函数中,外部中断0中已经有一条这个语句
s =time/58; // 距离S=时间除以58,因为 声音的速度是每秒约340米,超声波从发射到接收是一个来回的距离,所以距离S=时间T乘以340除以2
// S=340T/2,换成 2S=340T 换成2S/340=T 换成 2/340XS=T 2/340保留小数后四位 换成 0.0058S=T 换成S=T/0.0058
// S缩小100倍是厘米 换成 S/100=T/0.0058/100 , T换成微秒 最后得 S=T/58
if(s>600) // 如果测得的距离大于600CM
{ bai=0; // 则在液晶屏上显示 000
shi=0;
ge=0;
}
else // 如果测得的距离小于600CM 则接着往下执行
{
bai=s%1000/100; // 取出百位值
shi=s%100/10; // 取出十位值
ge=s%10; //取出个位值
display1(); //在液晶屏上显示距离
if(s>30)
delay (5000); //CPU处理太快了,如果大于30CM就在此在空转20000次
beeb(); // 调用发声函数
delay(100); // 显示距离的保持时间
}
}
}
/**********以下是各个子函数,主程序已经完毕 ***************/
void int0 () interrupt 0 // 外部中断0函数
{
TR0=0; // 定时器0停止工作
time=TH0*256+TL0; // 取出定时器的值保存到time里
TH0=0; // 清除定时器的高8位 准备下一轮测距
TL0=0; // 清除定时器的低8位
EX0=0; // 自己把自己关闭,防止干扰
}
/* 定时器0中断 */
void timer0() interrupt 1 //这个函数屁用没有,因为它的定时值不可能满,永远无法向CPU申请中断
{
TH0=0; //清空定时器1的高8位
TL0=0; //清空定时器1的低8位
}
void display1() // 显示函数
{
write_12864com (0x80); //写指令函数,在这里其实写的是地址
write_12864dat (table[bai]); // 写数据 显示百位
write_12864dat (table[shi]); // 显示十位
write_12864dat (table[ge]); // 显示个位
}
void display2() //显示开机画面函数
{
uchar i;
write_12864com (0x88);
for (i=0;i<16;i++)
{
write_12864dat (table1[i]);
}
}
void clr_screen() // 清屏函数
{
write_12864com (0X34); //扩充指令操作
delay(5);
write_12864com (0x30); //基本指令操作
delay(5);
write_12864com (0x01); //清屏
delay(5);
}
//写指令函数
void write_12864com(uchar com)
{
rs=0;
rw=0;
delay(1);
e=1;
P0=com;
delay(10);
e=0;
delay (2);
}
//写数据函数
void write_12864dat(uchar dat)
{
rs=1;
rw=0;
delay(1);
e=1;
P0=dat;
delay(10);
e=0;
delay (2);
}
//初始化
void init ()
{
delay (100);
write_12864com(0x30);
delay (3);
write_12864com(0x30);
delay (1);
write_12864com(0x0c);
delay (3);
write_12864com(0x01);
delay (250);
write_12864com(0x06);
delay(10);
}
void delay (uint t) //延时函数 50US 12864用
{
uchar j;
for(t;t>0;t--)
for(j=19;j>0;j--);
}
void delay20us(void) //误差 0us 发射超声波用
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=7;a>0;a--);
}
void delay1ms(int c) //误差 0us 1MS延时
{
unsigned char a,b,d;
for(d=c;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
void beeb() // 蜂鸣器函数
{
char i;
i=s;
if(s<=30) //小于30CM 蜂鸣器开始工作
flag=0;
if(flag==0)
{
if (s>=40) // 如果蜂鸣器已经开始工作,需要距离大于40CM蜂鸣器才能停止工作
{
flag=1;
BEEB=1;
}
}
if(flag==0) //这一段用于产生方波,方波的频率和距离S成反比 ,也就是距离越近,频率越高,频率越高,蜂鸣器发声越急促
{
BEEB=0; //从我的元件盒里找了一个8550,属于PNP型,也就是低电平导通,这个正好和8050相反
delay1ms(i*4);
BEEB=1; //高电平三极管截止,停止发声
delay1ms(i*5);
}
}
// 图形显示
void photodisplay(uchar *bmp)
{
uchar i,j;
write_12864com(0x34); //写数据时,关闭图形显示
for(i=0;i<32;i++)
{
write_12864com(0x80+i); //先写入水平坐标值
write_12864com(0x80); //写入垂直坐标值
for(j=0;j<16;j++) //再写入两个8位元的数据
write_12864dat(*bmp++);
delay(1);
}
for(i=0;i<32;i++)
{
write_12864com(0x80+i);
write_12864com(0x88);
for(j=0;j<16;j++)
write_12864dat(*bmp++);
delay(1);
}
write_12864com(0x36); //写完数据,开图形显示
}
/////////////////////////////////////////////////////////////////////////
// 以下数据显示的是 海尔兄弟 **
// 用百度下载图片,用PHOTOSHOP修改后用WINDOS自带的画图保存,再用取模软件获取的数据
// 图片尺寸: 128 * 64 //
/////////////////////////////////////////////////////////////////////////
unsigned char code haierphoto[] = // 数据表
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF8,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xC0,0x00,0x00,0x05,0xE0,0x38,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0xFF,0xFF,0xFC,0x00,0x00,0x3F,0xFF,0xFF,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0x80,0x1F,0xFF,0xFF,0xFF,0xC0,0x00,0x00,
0x00,0x00,0x00,0x07,0xFF,0xFF,0xFF,0xFF,0xE0,0x7F,0xFF,0xFF,0xFF,0xC0,0x00,0x00,
0x00,0x00,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xFB,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
0x00,0x00,0x00,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0,0x00,
0x00,0x00,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
0x00,0x00,0x03,0xFF,0xFF,0xFF,0xF1,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,
0x00,0x00,0x03,0xFF,0xFF,0xFF,0xC0,0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,
0x00,0x00,0x03,0xFF,0xFF,0xFF,0x80,0x1F,0xFF,0xFD,0xFF,0xFF,0xFF,0xFF,0xE0,0x00,
0x00,0x07,0xE3,0xFF,0xFF,0xFF,0x00,0x03,0xFF,0xFB,0x1C,0xBF,0xFF,0xFF,0xF0,0x00,
0x00,0x0C,0x1B,0xFF,0xFF,0xFF,0x00,0x7C,0xFF,0xBC,0x00,0x3F,0xFC,0xFF,0xF0,0x00,
0x00,0x08,0x0B,0xFF,0xFF,0xFF,0x83,0xE0,0x7E,0xFC,0x00,0x1F,0xE0,0x7F,0xF0,0x00,
0x00,0x08,0x09,0xFF,0xE0,0x7E,0x03,0xFC,0x7F,0xFC,0x00,0x0E,0x00,0x7F,0xF0,0x00,
0x03,0xFE,0x19,0xFF,0xC0,0x00,0x02,0x70,0x77,0x18,0x00,0x7E,0xC0,0x7F,0xF0,0x00,
0x06,0x19,0x88,0xFF,0x06,0xF0,0x03,0xF0,0x14,0xF0,0x00,0xFF,0x00,0xFF,0xE0,0x00,
0x08,0x00,0xC8,0xFE,0x09,0xF4,0x02,0x00,0x38,0x02,0x00,0x4E,0x80,0xFF,0xE0,0x00,
0x0B,0x80,0x46,0x7F,0x02,0x78,0x02,0x00,0x28,0x06,0x00,0x7C,0x00,0xFF,0xC0,0x00,
0x1B,0x7E,0xC0,0xFF,0x03,0xF8,0x00,0x80,0x44,0x04,0x00,0x00,0x00,0xFF,0x80,0x00,
0x18,0xF0,0x80,0x0F,0x80,0x40,0x07,0x00,0xC6,0x07,0xC6,0x00,0x00,0xFF,0x00,0x00,
0x08,0x0D,0x80,0x00,0xFF,0x80,0x00,0x03,0x87,0x83,0xFE,0x00,0x01,0xFF,0x00,0x00,
0x08,0x01,0x00,0x00,0x07,0xE0,0x00,0x3C,0x00,0x60,0x00,0x00,0x0F,0xE0,0x00,0x00,
0x05,0xFE,0x00,0x00,0x00,0x1F,0xFF,0xE0,0x00,0x3F,0xC0,0x40,0x70,0x00,0x00,0x00,
0x03,0xFE,0x00,0x00,0x00,0x00,0xE0,0x00,0x01,0x80,0x7F,0xFF,0xF0,0x00,0x00,0x00,
0x00,0x01,0xF0,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x0C,0x30,0x0C,0x00,0x00,0x00,
0x00,0x00,0x1F,0xFF,0x80,0x00,0x00,0x00,0x00,0x80,0x10,0x18,0x03,0x00,0x00,0x00,
0x00,0x00,0x04,0x00,0xFF,0x80,0x00,0x00,0x00,0x80,0x20,0x2C,0x00,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x80,0x30,0x08,0x40,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x80,0x33,0xD8,0x40,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x80,0x78,0x38,0x58,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x80,0x40,0x07,0xF0,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x80,0x20,0x00,0x08,0xC0,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x00,0x00,0x80,0x18,0x00,0x00,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x07,0x80,0x07,0xFC,0x01,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFF,0xFF,0x80,0x00,0x03,0xFE,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xE0,0x00,0x03,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x9F,0xFF,0xFE,0xFF,0xFF,0xFF,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x01,0xFF,0xF8,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0F,0xE0,0xFF,0xFF,0xF9,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x80,0xDF,0xFE,0x01,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x00,0xC3,0xE0,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0xC0,0xC0,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0C,0x00,0x80,0xE0,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x18,0x00,0x81,0x20,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x30,0x00,0x83,0x10,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xC8,0x00,0x82,0x08,0x00,0x80,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x20,0x01,0x04,0x01,0x84,0x06,0x00,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x60,0x03,0x04,0x00,0x8C,0x02,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x40,0x02,0x04,0x00,0x84,0x02,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x40,0x04,0x04,0x00,0x84,0x03,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0x18,0x04,0x01,0x84,0x01,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0x30,0x02,0x01,0x08,0x01,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x20,0x02,0x03,0x18,0x01,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x20,0x03,0x01,0x10,0x01,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x80,0x30,0x03,0x00,0xF8,0x01,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x01,0x00,0x38,0x02,0x00,0x1C,0x0E,0x00,0x40,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0x00,0x78,0x06,0x00,0x06,0x1C,0x00,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x03,0xFF,0xF8,0x03,0xFF,0xFC,0x1F,0xFF,0x80,0x00,0x00,0x00
};
/////////////////////////////////////////////////////////////////////////
// Bitmap点阵数据表 //
// 图片: C:\..1111111.bmp,横向取模左高位,数据排列:从左到右从上到下 //
// 图片尺寸: 128 * 64 //
/////////////////////////////////////////////////////////////////////////
unsigned char code haier[] = // 数据表
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};
|