找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5294|回復(fù): 4
收起左側(cè)

求助!STC89C52用超聲波測距串口顯示,但是顯示亂碼是怎么回事?

[復(fù)制鏈接]
ID:445357 發(fā)表于 2018-12-13 08:36 | 顯示全部樓層 |閱讀模式
現(xiàn)在在做畢業(yè)設(shè)計(jì) 想用超聲波檢測車位 現(xiàn)在檢測到的數(shù)據(jù)傳到串口全是亂碼怎么回事??


附上代碼:


/******************************************************************************/
/*  NAME : HC-SR04 超聲波模塊測距PC端串口顯示程序    */
/*  MCU:STC89C52                                     */
/*  晶振:11.0592MHz                                 */
/*  接線:  TRIG ---- P1.2                           */
/*          ECH0 ---- P1.1                           */
/*  串口波特率9600                                   */
/***********************************************************************************************************/          
#include <reg52.h>  
#include <intrins.h>
#include <stdio.h>



void InitIRQ(void);
void Conut(void);
void delayms(unsigned int ms);
void StartModule();       
typedef unsigned char u8;

#define uchar unsigned  char
#define uint  unsigned   int  


sbit TX  = P1^2; //產(chǎn)生脈沖引腳       
sbit RX  = P1^1; //回波引腳
sbit led = P2^0;

unsigned int  time=0;
float         Distance=0;//距離
bit           flag =0;   //中斷溢出標(biāo)志
       
/********************************************************/
void main()
{
        InitIRQ();
        while(1)
  {
         StartModule();
         while(!RX);                //當(dāng)超聲波模塊接收口輸出低電平則等待
         TR0=1;                //開啟計(jì)數(shù)
         while(RX);                        //當(dāng)RX為1計(jì)數(shù)并等待
         TR0=0;                                  //關(guān)閉計(jì)數(shù)
   Conut();                          //讀取定時器的值,計(jì)算
         delayms(60);       
        }
}

/*********** 中斷寄存器設(shè)置初始化 ***********/
void InitIRQ(void)
{
        TMOD=0x20;  //T/C工作方式寄存器 0010 0001
                    //T0 :GATE=0; 定時模式; 工作方式1,16位T/C; 計(jì)數(shù)器溢出中斷,用于判定超出測距范圍
                    //T1 :GATE=0; 定時模式; 工作方式2,8位可自動重載T/C; 用于串口通信 波特率發(fā)生器
        SCON=0x50;  //串行口控制寄存器  0101 0000
                    //SM0 SM1:工作方式1;10位異步收發(fā);波特率由定時器T1控制
                    //SM2: 多機(jī)通信控制位,方式0和方式1為非多機(jī)通信,設(shè)置0
                    //REN: 串行口接收允許位,允許串行口接收數(shù)據(jù)
                    //TB8:方式0和方式1中該位不用
                    //RB8: 方式0和方式1中該位不用
                    //TI: 發(fā)送中斷標(biāo)志位。串行發(fā)送停止位時,由內(nèi)部硬件置1,向CPU發(fā)中斷申請,必須由軟件清0
                     //RI: 接收中斷標(biāo)志位。串行接收停止位時,由內(nèi)部硬件置1,向CPU發(fā)中斷申請,必須由軟件清0
        TH0=0;      //T0初始化,,用于判斷測距溢出,最大65.536 ms
        TL0=0;        
        TH1=0xFD;   //T1初始化  設(shè)定波特率9600 (波特率計(jì)算參考文檔)
        TL1=0xFD;   
       
        ET0=1;      //T0中斷允許
        TR0=1;      //開啟定時器0
        TR1=1;      //開啟定時器1
        //ES=1;     //串口允許中斷
                    /*
                                                          可刪除,我的理解是:在系統(tǒng)正常運(yùn)行情況下,串口發(fā)送完成則置位TI=1,
                                                          向CPU請求中斷,在我們軟件人為的直接設(shè)置TI=1的情況下可以直接向CPU
                                                          請求中斷了,已經(jīng)跳過了“允許”那一步
                                                                并且最好刪除!
                                                                因?yàn)門I為中斷標(biāo)志位如果程序使用了串口中斷,那么每次調(diào)用printf都
                                                                會進(jìn)入中斷,因此在使用printf前要禁用中斷
                                                        */
        TI=1;       /*
                     發(fā)送中斷標(biāo)志 ☆直接使用printf必須加此語句才能發(fā)送
               在KEILC中,printf在傳輸數(shù)據(jù)前需要確保前一個數(shù)據(jù)傳輸
                                                         結(jié)束,也就是TI=1,否則將處于等待狀態(tài)
                                                         因?yàn)閜rintf函數(shù)會調(diào)用putchar函數(shù),而putchar函數(shù)會判斷TI,
                                                         不為1則等待(相當(dāng)于死機(jī)),為1則清0,發(fā)送完成后又自動置1
                                                         因此第一次運(yùn)行printf時檢查TI=1則進(jìn)行發(fā)送,發(fā)送完成后
                                                         發(fā)送中斷標(biāo)志位TI又自動置1
                                                         */
  EA=1;       //開啟總中斷
}

/*********** 觸發(fā)超聲波模塊 ***********/
void  StartModule() //超聲波模塊Trig控制端給大于10us的高電平觸發(fā)模塊測距       
{
          TX=1;     
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          _nop_();
          //_nop_();
          //_nop_();
          //_nop_();
          //_nop_();
          //_nop_();
          TX=0;
}

/*********** 定時器T0計(jì)數(shù) ***********/
void Conut(void)
{
         time=TH0*256+TL0;
         TH0=0;
         TL0=0;
         Distance = (time*1.87)/100;  //CM  (見代碼最后注釋)
         if(flag==1)                    //超出測量
         {
          flag=0;
          printf("%f",Distance);
         }
         if(Distance<20){
                 led = 0;
         }else{
                 led = 1;
         }
          //printf("Distance = %f CM\n",Distance);
}
/********************************************************/
void delayms(unsigned int ms)
{
        unsigned char i=100,j;
        for(;ms;ms--)
        {
                while(--i)
                {
                        j=10;
                        while(--j);
                }
        }
}
/*********** 定時器T0中斷服務(wù)函數(shù) ***********/
void Timer0IRQ() interrupt 1 //T0中斷用來計(jì)數(shù)器溢出,超過測距范圍
{
    flag=1;       
}
void Usart() interrupt 4                  //T0中斷用來計(jì)數(shù)器溢出,超過測距范圍
  {
            
                u8 receiveData;
       
                receiveData=SBUF;        //出去接收到的數(shù)據(jù)
                RI = 0;                //清除接收中斷標(biāo)志位
                SBUF=receiveData;        //將接收到的數(shù)據(jù)放入到發(fā)送寄存器
                while(!TI);                         //等待發(fā)送數(shù)據(jù)完成
                TI=0;                                                         //中斷溢出標(biāo)志
  }


//紅色這塊我加與不加都是亂碼

/*12分頻:就是f/12,假設(shè)(接晶振12MHz)輸入信號頻率12MHz,12分頻后,則輸出1MHz
        *時鐘周期周期變?yōu)樵瓉淼?2倍, T=1/1MHz=1us
        *即單片機(jī)內(nèi)部的加1計(jì)數(shù)器在加1這個過程中 ,寄存器要完成這個動作,是一個機(jī)器周期
        *時鐘周期為1/12MHz=1/12us
        *機(jī)器周期=12個時鐘周期=1us,也就是計(jì)數(shù)器每加1需要的時間問1us
        *單片機(jī)中的部件都是在晶振12分頻后的一個機(jī)器周期在跑
        *時鐘周期 = 晶振頻率的倒數(shù),即1/fosc
        *機(jī)器周期 = 12 * 時鐘周期 = 12/fosc
        ------------------------------------------------------
        |距離計(jì)算公式
        |2S(m) = t(s) * 344(m/s)
        |S(m)  = t(s) * 172(m/s)
        |S(cm) = t(us) * 0.0172(cm/us)
        |      = t(us) * 1/58
        |t在晶振位12MHz時等于計(jì)數(shù)值(機(jī)器周期1us),但晶振為11.0592MHz時
        |t(us) = 計(jì)數(shù) * (12/11.0592) * (1/58)
        |      = 計(jì)數(shù) * 0.0187
        |      = (計(jì)數(shù) * 1.87)/100
        ------------------------------------------------------
        */

16進(jìn)制顯示

16進(jìn)制顯示

字符顯示亂碼

字符顯示亂碼
回復(fù)

使用道具 舉報

ID:445357 發(fā)表于 2018-12-13 08:36 | 顯示全部樓層
波特率也設(shè)置對的啊
回復(fù)

使用道具 舉報

ID:277550 發(fā)表于 2018-12-13 11:06 | 顯示全部樓層


晶振是否和代碼的對應(yīng)的。
回復(fù)

使用道具 舉報

ID:445357 發(fā)表于 2018-12-14 10:11 | 顯示全部樓層
devcang 發(fā)表于 2018-12-13 11:06
晶振是否和代碼的對應(yīng)的。

我換了塊板子燒寫一樣的代碼就OK了,可能是板子的問題
回復(fù)

使用道具 舉報

ID:437026 發(fā)表于 2018-12-14 11:53 來自手機(jī) | 顯示全部樓層
顯示亂碼如果顯示器沒問題,說明你程序錯了
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表