程序更新//2016年12月27日21點
修復bug
程序更新//2016年12月26日23點
修復閃爍問題
增加開機初始化顯示-AA-
增加超聲波模塊檢測 未收到信號時顯示-EE-
距離異常顯示----更改為-EE-
如大家發(fā)現(xiàn)bug記得給我留言!!
源文件還未更新
交流群中有源文件免費下載往下看群號
也不能完全說是原創(chuàng) 別人都做爛了
第一次在數(shù)碼之家發(fā)帖支持下哦
文章最后有程序源文件
可直接下載到單片機接上模塊使用
上電一直掃描 距離并顯示出來
因為我用的模塊是必須一直掃描才能顯示
所以測遠距離時候會一閃一閃的
程序限制4-300CM測量距離實際上最長可達到5.7M
具體修改限制的方法可留言問我
技術(shù)交流群533743590新群求zhichi么么噠
圖片
數(shù)碼管模塊簡介
1.采用2片595驅(qū)動數(shù)碼管,需要單片機3路IO口,根據(jù)數(shù)碼管動態(tài)掃描原理進行顯示;
2.寬工作電壓3.3V到5V;
3.PCB板尺寸:71mm*22mm
4.數(shù)碼管型號:0.36 4位共陽
超聲波模塊簡介
接線方式,VCC、trig(控制端)、 echo(接收端)、 GND地線
本產(chǎn)品使用方法:一個控制口發(fā)一個10US以上的高電平,就可以在接收口等待高電平輸出.一有
輸出就可以開定時器計時,當此口變?yōu)榈碗娖綍r就可以讀定時器的值,此時就為此次測距的時間,
方可算出距離.如此不斷的周期測,就可以達到你移動測量的值了~~
模塊工作原理:
(1)采用IO觸發(fā)測距,給至少10us的高電平信號;
(2)模塊自動發(fā)送8個40khz的方波,自動檢測是否有信號返回;
(3)有信號返回,通過IO輸出一高電平,高電平持續(xù)的時間就是
超聲波從發(fā)射到返回的時間.測試距離=(高電平時間*聲速(340M/S))/2
代碼區(qū)
/*
*************街角賣幸福原創(chuàng)****************************
*************轉(zhuǎn)載請注明出處*****************************
----------技術(shù)交流群533743590-------------------------
------------本人QQ1979466583------------------------
對應接線
數(shù)碼管模塊 型號【HC595驅(qū)動的8位數(shù)碼管】
SCLK-P1.2
RCLk-P1.1
DIO-P1.0
超聲波模塊 型號【HC-SR04】
echo--P3.2
trig--P3.3
*/
#include <AT89X51.H> //頭文件
unsigned char code fseg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char code segbit[]={0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char disbuf[8]={0,0,0,0,0,0,0,0};
//-----------------------------------------------------------------------------
// 函數(shù)原形定義
#define uchar unsigned char
#define uint unsigned int
void main (void); // 主函數(shù)
void LED4_Display (void); // LED顯示
void LED_OUT(uchar X); // LED單字節(jié)串行移位函數(shù)
void delayms(uint); //延時子函數(shù) ms
void jisuan(void);
unsigned char code LED_0F[]; // LED字模表
sbit DIO=P1^0; //串行數(shù)據(jù)輸入
sbit RCLK=P1^1; //時鐘脈沖信號——上升沿有效
sbit SCLK=P1^2; //打入信號————上升沿有效
sbit echo=P3^2; //echo
sbit trig=P3^3; //trig
//-----------------------------------------------------------------------------
// 全局變量
uchar LED[8]; //用于LED的8位顯示緩存
uint temp;
uint temp1;
uint a,b; //定義一個變量a,b 后者用于判斷是否收到信號
//
// 主程序
//
void main(void) //主函數(shù)開始
{
uint f;
echo=0; //先拉低echo,trig引腳
trig=0;
f=500;
while(f>0); //啟動延時 消除第一次上電產(chǎn)生的波動
{
LED[3]=16;
LED[2]=15;
LED[1]=15;
LED[0]=16;
f--;
}
EA=1; //開總中斷
TMOD=0x11; //設(shè)置定時器為方式1
ET0=1; //允許定時器中斷 這里主要是防止超聲波模塊未發(fā)送信號
ET1=1;
while(1)
{
echo=0;//a賦值
a=0;
b=1;
TH0=0; //定時器裝初值
TL0=0;
TH1=(65536-25000)/256; //定時器裝初值
TL1=(65536-25000)%256;
trig=1; //trig送高
LED4_Display (); // 延時3ms
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
trig=0; //trig送低
TR1=1;
while(echo==0); //等待echo變?yōu)楦唠娖?/font>
if(b==1) 判斷是否收到信號
{
TR1=0; //關(guān)定時器1
EX0=1; //開外部中斷
TR0=1; //啟動定時器
while(a==0); //注意這里! 前面給a賦0 程序停在這里等待中斷
//本來是在這里加上掃描屏幕程序的 發(fā)現(xiàn)有重大BUG索性刪除
}
else
{
LED[3]=16;
LED[2]=15;
LED[1]=15;
LED[0]=16;
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
LED4_Display ();
}
}
}
void waibu() interrupt 0 //外部中斷服務子程序
{
temp=TH0; //取出定時器的值
temp1=TL0;
EX0=0; //關(guān)閉外部中斷
TR0=0; //關(guān)閉定時器
jisuan(); //運行計算子程序
a=1; //a賦值1 程序回到剛才的 while(a) 中因為a的值已變?yōu)?,程序從頭開始
}
void time1() interrupt 1 //定時器中斷服務子程序
{
TH0=0; //重裝初值
TL0=0;
}
void time2() interrupt 3
{
TR1=0;
TH0=(65536-25000)/256; //定時器裝初值
TL0=(65536-25000)%256;
b=0;
echo=1;
}
void jisuan(void) //計算子程序
{
uint c,d; //定義一個變量c,d 用來判斷距離
c=0; //賦值0
d=0; //給b重新賦值
LED4_Display (); //掃描一下數(shù)碼管
temp=(temp<<8)+temp1; //TH0 TL0合并
temp=temp/5; //我沒有精確計算 直接除5得出大概值
if(temp>40) //判段距離是否過近
{
c=1;
}
LED4_Display (); //掃描一下數(shù)碼管
if(temp<40)
{
c=0;
}
LED4_Display ();
if(temp<3000) //判斷距離是否過遠
{
d=1;
}
LED4_Display ();
if(temp>3000)
{
d=0;
}
c=c&d; //與運算
if(c==1) //判斷距離是否正常
{
LED[3]=temp/1000; //數(shù)值分離顯示
LED[2]=temp%1000/100;
LED[1]=(temp%1000%100/10)+20; //這個為什么要加上20呢? 因為這是個位 需要顯示小數(shù)點
LED[0]=temp%1000%100%10;
}
if(c==0) //判斷距離是否正常
{
LED[3]=16;
LED[2]=14;
LED[1]=14;
LED[0]=16;
}
}
void delayms(uint xms) //延時子函數(shù) ms
{
uint i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
//下面的程序是hc595模塊顯示程序
//每個模塊的程序可以到資料的例程中移植
//*******************************************************//
void LED4_Display (void) //屏幕掃描子函數(shù)
{
unsigned char code *led_table; // 查表指針
uchar i;
//顯示第1位
led_table = LED_0F + LED[0];
i = *led_table;
LED_OUT(i);
LED_OUT(0x01);
RCLK = 0;
RCLK = 1;
//顯示第2位
led_table = LED_0F + LED[1];
i = *led_table;
LED_OUT(i);
LED_OUT(0x02);
RCLK = 0;
RCLK = 1;
//顯示第3位
led_table = LED_0F + LED[2];
i = *led_table;
LED_OUT(i);
LED_OUT(0x04);
RCLK = 0;
RCLK = 1;
//顯示第4位
led_table = LED_0F + LED[3];
i = *led_table;
LED_OUT(i);
LED_OUT(0x08);
RCLK = 0;
RCLK = 1;
}
void LED_OUT(uchar X)
{
uchar i;
for(i=8;i>=1;i--)
{
if (X&0x80) DIO=1; else DIO=0;
X<<=1;
SCLK = 0;
SCLK = 1;
}
}
//下面是顯示數(shù)組
unsigned char code LED_0F[] =
{// 0 1 2 3 4 5 6 7 8 9 A b C d E F - .
0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x8C,0xBF,0xC6,0xA1,0x86,0x8e,0xbf,0x7f,0x00,0x00,
// 20 21 22 23 24 25 26 27 28 29 30
0x40,0x79,0x24,0x30,0x19,0x12,0x12,0x78,0x00,0x10,0xbf,
};
|