|
在第一個(gè)AT89C52單片機(jī)上,通過速度公式v=s/t計(jì)算出速度V。通過定義發(fā)送函數(shù)和接收函數(shù)實(shí)現(xiàn)速度信息V的傳遞并在第二個(gè)單片機(jī)中運(yùn)用第一個(gè)單片機(jī)計(jì)算出的速度進(jìn)行運(yùn)算推導(dǎo)時(shí)間然后進(jìn)行倒計(jì)時(shí)。通過對(duì)程序的逐部分檢驗(yàn)發(fā)現(xiàn)主要問題是SBUF傳遞的速度數(shù)值V在0-255可以準(zhǔn)確傳遞但是一旦超過一個(gè)字節(jié)范圍即0-255就會(huì)失真。
查閱書籍發(fā)現(xiàn)大多是利用for循環(huán)依次發(fā)送定義數(shù)組內(nèi)已知的數(shù)。那么如何定義發(fā)送和接收函數(shù)才能實(shí)現(xiàn)依次發(fā)送時(shí)間不定的速度量的個(gè)位、十位、百位和小數(shù)點(diǎn)位哪?
具體程序如下:
發(fā)送程序:
/************************************************************************************** *
*按下K1按鍵 開始計(jì)時(shí)
*按下K2按鍵 計(jì)時(shí)結(jié)束計(jì)算速度
***************************************************************************************/
#include "reg52.h" //此文件中定義了單片機(jī)的一些特殊功能寄存器
#include<intrins.h> //左右移函數(shù),頭文件
#include<absacc.h> //訪問絕對(duì)地址頭文件
sbit k1=P1^0; //按鍵1開始計(jì)時(shí)
sbit k2=P1^1; //按鍵2終止計(jì)時(shí)開始計(jì)算速度
sbit dian=P0^7; //小數(shù)點(diǎn)
unsigned char xiao=0,ge=0,shi=0,bai=0; //定義數(shù)碼管顯示的個(gè)位和十位
unsigned int num=0,sec=0,m=0,v=0,t=0,t1=0,t2=0,t3=0;//定義ms、s、時(shí)間總數(shù)和速度
unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數(shù)碼管段控口
/*******************************************************************************
* 函 數(shù) 名 : delay
* 函數(shù)功能 : 延時(shí)函數(shù)
*******************************************************************************/
void delay(unsigned int i)
{
while(i--); // 去抖延時(shí)
}
/*******************************************************************************
* 函 數(shù) 名 : Timer0Init
* 函數(shù)功能 : 定時(shí)器0初始化
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Timer0Init(void) //10微秒@12.000MHz
{
TMOD|=0X01;//選擇為定時(shí)器0模式,工作方式1,僅用TR0打開啟動(dòng)。
TL0 = (65536-10000)%256; //設(shè)置定時(shí)初值
TH0 = (65536-10000)/256; //設(shè)置定時(shí)初值
ET0=1;//打開定時(shí)器0中斷允許
EA=1;//打開總中斷
TR0=1;//打開定時(shí)器
}
/*******************************************************************************
* 函 數(shù) 名 : display
* 函數(shù)功能 : 速度顯示函數(shù)
*******************************************************************************/
/******速度顯示函數(shù)******/
void display() //列車一般情況下列車的平均速度為300km/h約等于83m/s
{
ge=v%10; //求個(gè)位
bai=v/100; //求百位
shi=(v-100*bai)/10; //求十位
xiao=(v-100*bai-10*shi-ge)/0.1; //求小數(shù)位
P2=0xf7; //選擇數(shù)碼管1,輸入位選信號(hào)
P0=table[xiao]; //數(shù)碼管段選信號(hào),顯示小數(shù)位數(shù)值
delay(15);
P2=0xfb; //選擇數(shù)碼管2,輸入位選信號(hào)
P0=table[ge]; //數(shù)碼管段選信號(hào),顯示個(gè)位數(shù)值
dian=1; //小數(shù)點(diǎn)點(diǎn)亮
delay(15);
P2=0xfd; //選擇數(shù)碼管3,輸入位選信號(hào)
P0=table[shi]; //數(shù)碼管段選信號(hào),顯示十位數(shù)值
delay(15);
P2=0xfe; //選擇數(shù)碼管4,輸入位選信號(hào)
P0=table[bai]; //數(shù)碼管段選信號(hào),顯示百位數(shù)值
delay(15);
}
/*******************************************************************************
* 函 數(shù) 名 : keypros
* 函數(shù)功能 : 按鍵處理函數(shù),判斷按鍵是否按下并
*******************************************************************************/
void keypros()
{
if(k1==0) //檢測(cè)按鍵K1是否按下
{
delay(1000); //消除抖動(dòng) 一般大約1ms
if(k1==0) //再次判斷按鍵是否按下
{
num++;
TL0 = (65536-1000)%256; //設(shè)置定時(shí)初值
TH0 = (65536-1000)/256; //設(shè)置定時(shí)初值
if(num==1000) //時(shí)間到達(dá)1s
{
num=0; //重新從1ms開始計(jì)時(shí)
sec++; //累計(jì)1S
}
}
}
}
/*****發(fā)送*********/
void Send ()
{ unsigned char dat ;
dat=v; //速度中間量
SBUF=dat; //發(fā)速度
while(TI==0); //串行通信口中斷
TI=0; //手動(dòng)賦初值
}
/*******************************************************************************
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
*******************************************************************************/
void main()
{
Timer0Init(); //定時(shí)器0初始化
TMOD=0x20; //定時(shí)器1工作于方式2
SCON=0x50; //定時(shí)器串口工作方式1允許接收
PCON=0x00; //波特率9600
TH1=0XFD; //根據(jù)規(guī)定給定時(shí)器T1賦值
TL1=0XFD; //根據(jù)規(guī)定給定時(shí)器T1賦值
TR1=1; //啟動(dòng)定時(shí)器T1
while(1)
{
keypros(); //按鍵處理函數(shù)
}
}
/*******************************************************************************
* 函 數(shù) 名 : void Timer0() interrupt 1
* 函數(shù)功能 : 定時(shí)器0中斷函數(shù)
*******************************************************************************/
void Timer0() interrupt 1
{
TL0 = (65536-10000)%256; //設(shè)置定時(shí)初值
TH0 = (65536-10000)/256; //設(shè)置定時(shí)初值
if(k2==0) //檢測(cè)按鍵K2是否按下
{
delay(1000); //消除抖動(dòng) 一般大約1ms
if(k2==0) //再次判斷按鍵是否按下
{
v=5000/(1000*sec+num)*3.6; //速度公式求列車速度單位為km/h
while(1)
{
display(); //顯示函數(shù)
Send ();
}
}
}
while(!k2); //檢測(cè)按鍵是否松開
}
接收程序:
/************************************************************************************** *
*按下K1按鍵 開始計(jì)時(shí)
*按下K2按鍵 計(jì)時(shí)結(jié)束計(jì)算速度
***************************************************************************************/
#include "reg52.h" //此文件中定義了單片機(jī)的一些特殊功能寄存器
#include<intrins.h> //左右移函數(shù),頭文件
#include<absacc.h> //訪問絕對(duì)地址頭文件
sbit k3=P3^5; //抬桿
sbit dian=P0^7; //小數(shù)點(diǎn)
unsigned char xiao=0,ge=0,shi=0,bai=0,count=0; //定義數(shù)碼管顯示的個(gè)位和十位
unsigned int v=0,t=0,t1=0,t2=0,t3=0,t4=0;//定義ms、s、時(shí)間總數(shù)和速度
unsigned char code table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//數(shù)碼管段控口
/*******************************************************************************
* 函 數(shù) 名 : Init
* 函數(shù)功能 : 初值函數(shù)
*******************************************************************************/
/******初值函數(shù)******/
void Init(void)
{
TMOD=0x01;
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
TR0=1;
ET0=1;
EA=1;
}
/*******************************************************************************
* 函 數(shù) 名 : timer
* 函數(shù)功能 : 中斷函數(shù)
*******************************************************************************/
/******中斷函數(shù)******/
void timer0(void) interrupt 1
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
count++;
if(count>19)
{
count=0;
t3--;
}
}
/*******************************************************************************
* 函 數(shù) 名 : delay
* 函數(shù)功能 : 延時(shí)函數(shù)
*******************************************************************************/
/******延時(shí)函數(shù)******/
void delay(unsigned int i)
{
while(i--); // 延時(shí)
}
/*****時(shí)間顯示函數(shù)*********/
void display()
{
ge=t3%10; //求個(gè)位
bai=t3/100; //求百位
shi=(t3-100*bai)/10; //求十位
xiao=(t3-100*bai-10*shi-ge)/0.1; //求小數(shù)位
P2=0xf7; //選擇數(shù)碼管1,輸入位選信號(hào)
P0=table[xiao]; //數(shù)碼管段選信號(hào),顯示小數(shù)位數(shù)值
delay(15);
P2=0xfb; //選擇數(shù)碼管2,輸入位選信號(hào)
P0=table[ge]; //數(shù)碼管段選信號(hào),顯示個(gè)位數(shù)值
dian=1; //小數(shù)點(diǎn)點(diǎn)亮
delay(15);
P2=0xfd; //選擇數(shù)碼管3,輸入位選信號(hào)
P0=table[shi]; //數(shù)碼管段選信號(hào),顯示十位數(shù)值
delay(15);
P2=0xfe; //選擇數(shù)碼管4,輸入位選信號(hào)
P0=table[bai]; //數(shù)碼管段選信號(hào),顯示百位數(shù)值
delay(15);
}
/*******************************************************************************
* 函 數(shù) 名 : Receive
* 函數(shù)功能 : 接收函數(shù)
*******************************************************************************/
unsigned char Receive(void)
{
unsigned char dat;
while(RI==0);
RI=0;
dat=SBUF;
return dat;
}
/*******************************************************************************
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
*******************************************************************************/
void main()
{
TMOD=0X20; //定時(shí)器1工作于方式2
SCON=0X50; //定時(shí)器串口工作方式1允許接收
PCON=0x00; //波特率9600
TH1=0XFD; //根據(jù)規(guī)定給定時(shí)器T1賦值
TL1=0XFD; //根據(jù)規(guī)定給定時(shí)器T1賦值
TR1=1; //啟動(dòng)定時(shí)器T1
REN=1; //允許接收
v=Receive();
t=5.5*3600/v; //計(jì)算到達(dá)安全位置時(shí)間,單位h.小時(shí)到微妙t1=t*60*60*1000*1000; t2=t1/1000000; //多少秒
t3=t+10; //在原定實(shí)踐基礎(chǔ)上處于安全考慮延長(zhǎng)10s后所需要的時(shí)間
while(1)
{ k3=0; //抬桿落下
EA=1; //開中斷
Init(); //賦初值
while(t3!=0) //計(jì)時(shí)不為0
{
display(); //顯示函數(shù)
}
while(t3==0) //計(jì)時(shí)為0
{
k3=1; //抬桿抬起
while(1); //終止
}
}
}
|
|