亚洲春色中文字幕久久久-三上亚,一吻二脱三床四吻胸,国产真实伦对白视频全集,在线毛片观看,精品成品入口黄网,国产毛aⅴ片久久久,亚洲AV色香蕉一区二区三区老师,萧皇后A级艳片,色情日本视频更新,99久久亚洲精品日本无码
標題:
單片機超聲波程序(帶詳細注釋)Proteus仿真圖
[打印本頁]
作者:
狂奔向公交
時間:
2025-1-5 11:09
標題:
單片機超聲波程序(帶詳細注釋)Proteus仿真圖
這是我之前做的基于STM32的超聲波測距系統,
附件里面包含了keil仿真代碼以及Proteus仿真工程
請大家多多指教
屏幕截圖 2025-01-05 110902.png
(87.36 KB, 下載次數: 0)
下載附件
2025-1-5 11:09 上傳
單片機源程序如下:
//頭文件包含
#include <reg52.h> //提供單片機寄存器地址
#include <intrins.h> //提供_nop_()函數
unsigned int code duan_ma[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, //0~9
0x77,0x7c,0x39,0x5e,0x79,0x71}; //A~F
unsigned int dis_buf[4]; //顯示緩存的數組
unsigned int S = 0; //距離緩存變量
unsigned long time = 0; //時間緩存變量
unsigned int S_H = 400, S_L = 10; //S_H:報警上限值,默認400cm,S_L:報警下限值,默認10cm
//引腳定義
sbit BEEP = P3^7; //蜂鳴器控制端口,低電平有效,無源蜂鳴器
#define digDuan P0 //數碼管段控制端口,高電平有效
sbit digWei1 = P2^4; //第1位數碼管控制端口,低電平有效
sbit digWei2 = P2^5; //第2位數碼管控制端口,低電平有效
sbit digWei3 = P2^6; //第3位數碼管控制端口,低電平有效
sbit digWei4 = P2^7; //第4位數碼管控制端口,低電平有效
sbit KEY1 = P1^0; //設置鍵
sbit KEY2 = P1^1; //加鍵
sbit KEY3 = P1^2; //減鍵
sbit Ttig = P1^3; //觸發信號控制端口
sbit Echo = P1^4; //回響信號接收端口
/* 定時器0和1初始化,定時1ms */
void InitTimer0(void)
{
TMOD = 0x11; //配置定時器0為工作方式1,定時器1位工作方式1
TH0 = 0;
TL0 = 0;
TH1 = 0x0EC; //定時5ms
TL1 = 0x78;
EA = 1; //打開總中斷
ET1 = 1; //打開定時器0中斷
TR1 = 1; //打開定時器1
TR0 = 0; //打開定時器0
}
/*
* 數碼管掃描
* *dat:以數組的方式傳值,使用的時候直接填入數組名即可
*/
void dig_scan(unsigned int *dat)
{
static unsigned char i = 0; //循環變量
/* 數碼管掃描處理 */
digDuan = 0x00; //消隱
digWei1 = 1;
digWei2 = 1;
digWei3 = 1;
digWei4 = 1;
switch(i)
{
case 0:
{
digWei1 = 0; //選通第1位數碼管
digDuan = dat[0]; //顯示第1位數碼管的內容
break;
}
case 1:
{
digWei2 = 0; //選通第2位數碼管
digDuan = dat[1]; //顯示第2位數碼管的內容
break;
}
case 2:
{
digWei3 = 0; //選通第3位數碼管
digDuan = dat[2] + 0x80; //顯示第3位數碼管的內容,順便也顯示小數點
break;
}
case 3:
{
digWei4 = 0; //選通第4位數碼管
digDuan = dat[3]; //顯示第4位數碼管的內容
break;
}
default: break;
}
++i; //數碼管位選變量循環
if(i >= 4)
i = 0;
}
/* 按鍵延時函數,單位:ms */
static void key_delayms(unsigned int ms)
{
unsigned char a,b,c;
while(--ms)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/* 按鍵掃描 */
unsigned char key_scan(void)
{
if(KEY1 == 0) //如果按鍵1按下
{
key_delayms(10); //延時10ms,去除按鍵抖動
if(KEY1 == 0) //再判斷一次按鍵按下
{
return 1; //輸出鍵值1
}
}
if(KEY2 == 0) //如果按鍵2按下
{
key_delayms(10); //延時10ms,去除按鍵抖動
if(KEY2 == 0) //再判斷一次按鍵按下
{
return 2; //輸出鍵值2
}
}
if(KEY3 == 0) //如果按鍵3按下
{
key_delayms(10); //延時10ms,去除按鍵抖動
if(KEY3 == 0) //再判斷一次按鍵按下
{
return 3; //輸出鍵值3
}
}
return 0; //如果沒有按鍵按下,則輸出0
}
/* 啟動超聲波程序 */
void StartModule(void)
{
Ttig = 1; //啟動一次模塊
_nop_(); //延時一段時間,至少10us以上
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Ttig = 0;
}
/* 延時,單位:ms */
void delayms(unsigned int ms)
{
unsigned char a,b,c;
while(--ms)
{
for(c=1;c>0;c--)
for(b=142;b>0;b--)
for(a=2;a>0;a--);
}
}
/* 計算測距 */
void count(void)
{
StartModule(); //啟動一次超聲波
while(!Echo); //等待超聲波模塊輸出IO拉高
TR0 = 1; //開啟定時器計時
while(Echo); //等待超聲波模塊輸出IO拉低
TR0 = 0; //關閉定時器計時
/* 計算距離 */
time = TH0 * 256 + TL0; //得到的時間,專業寫法應該是這樣:time = TH0 << 8 | TL0
TH0 = 0; //定時計數器清零
TL0 = 0;
S = (time * 1.7) / 100; //算出來是M
}
/* 顯示距離 */
void dis_distance(void)
{
dis_buf[3] = 0x00;
dis_buf[2] = duan_ma[S / 100 %10]; //取出百位數,并在數碼管的第3位顯示,從右往左數
dis_buf[1] = duan_ma[S / 10 %10]; //取出十位數,并在數碼管的第2位顯示,從右往左數
dis_buf[0] = duan_ma[S % 10]; //取出個位數,并在數碼管的第1位顯示,從右往左數
}
/* 設置報警功能 */
void key_fuction(void)
{
unsigned char mode_flag = 1; //模式切換標記位,1:設置上限值,2:設置下限值,3:退出
while(1)
{
if(key_scan() == 1)
{
BEEP = 0; //按鍵提示音
delayms(50);
BEEP = 1;
delayms(1000);
++mode_flag;
if(mode_flag >= 3) //如果滿3了,則退出
break;
}
if(key_scan() == 2) //如果加鍵按下
{
BEEP = 0; //按鍵提示音
delayms(50);
BEEP = 1;
delayms(1000);
if(mode_flag == 1) //設置上限值
{
++S_H;
if(S_H > 400)
S_H = 2;
}
if(mode_flag == 2) //設置下限值
{
++S_L;
if(S_L > 400)
S_L = 2;
}
}
if(key_scan() == 3) //如果減鍵按下
{
BEEP = 0; //按鍵提示音
delayms(50);
BEEP = 1;
delayms(1000);
if(mode_flag == 1) //設置上限值
{
--S_H;
if(S_H < 2)
S_H = 400;
}
if(mode_flag == 2) //設置下限值
{
--S_L;
if(S_L < 2)
S_L = 400;
}
}
/* 報警設置顯示 */
if(mode_flag == 1) //顯示設置上限值內容
{
dis_buf[3] = 0x76; //第4位數碼管顯示字母 H
dis_buf[2] = duan_ma[S_H / 100 % 10]; //顯示百位數
dis_buf[1] = duan_ma[S_H / 10 % 10]; //顯示十位數
dis_buf[0] = duan_ma[S_H % 10]; //顯示個位數
}
if(mode_flag == 2) //顯示設置下限值內容
{
dis_buf[3] = 0x38; //第4位數碼管顯示字母 L
dis_buf[2] = duan_ma[S_L / 100 % 10]; //顯示百位數
dis_buf[1] = duan_ma[S_L / 10 % 10]; //顯示十位數
dis_buf[0] = duan_ma[S_L % 10]; //顯示個位數
}
}
}
/* 主函數 */
void main(void)
{
digDuan = 0x40; //顯示"----"
digWei1 = 0;
digWei2 = 0;
digWei3 = 0;
digWei4 = 0;
delayms(1000); //延時大約1s
InitTimer0(); //定時器0初始化
while(1)
{
count(); //計算距離
if(S>=S_H || S<=S_L) //如果超出設定的范圍,則顯示"---"
{
dis_buf[3] = 0x00;
dis_buf[2] = 0x40; //顯示"---"
dis_buf[1] = 0x40;
dis_buf[0] = 0x40;
BEEP = 0; //蜂鳴器鳴叫
delayms(1000);
}
else
{
BEEP = 1; //關閉蜂鳴器
dis_distance(); //顯示距離
}
if(key_scan() == 1) //如果按下設置鍵,則進入設置報警功能
{
BEEP = 0; //按鍵提示音
delayms(50);
BEEP = 1;
delayms(100);
key_fuction(); //進入設置報警功能
}
}
}
/* 定時器0中斷服務函數,5ms進一次本中斷,用于數碼管掃描 */
void Timer1Interrupt(void) interrupt 3
{
TH1 = 0x0EC; //定時5ms,重新賦值
TL1 = 0x78;
dig_scan(dis_buf); //數碼管顯示距離
}
復制代碼
Proteus8.17仿真程序:
單片機超聲波.zip
(149.3 KB, 下載次數: 0)
2025-1-5 11:07 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
作者:
songxia8013
時間:
2025-1-6 12:18
這是51單片機,不是STM32單片機。
作者:
210703zxh
時間:
2025-5-23 15:31
我用proteus的超聲模塊不知為什么一直沒有回波?
歡迎光臨 (http://www.denmoz.com/bbs/)
Powered by Discuz! X3.1