找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 9006|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

求大神畫主程序流程圖,各分程序的流程圖

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
50黑幣

#include <reg52.h>
#define uchar unsigned char  //無符號(hào)字符型 宏定義 變量范圍0~255
#define uint  unsigned int  //無符號(hào)整型 宏定義 變量范圍0~65535
#include <intrins.h>
#include "eepom52.h"
sbit SCL=P1^4;  //SCL定義,連接ADC0832SCL腳
sbit DO=P1^3;  //DO定義,連接ADC0832DO腳
sbit CS=P1^5;  //CS定義,連接ADC0832CS腳
sbit beep = P3^3;  //蜂鳴器

//這三個(gè)引腳參考資料
sbit rs=P1^0;  //1602數(shù)據(jù)/命令選擇引腳 H:數(shù)據(jù)       L:命令
sbit rw=P1^1;  //1602讀寫引腳          H:數(shù)據(jù)寄存器   L:指令寄存器
sbit e =P1^2;  //1602使能引腳          下降沿觸發(fā)
sbit c_send   = P1^6;  //超聲波發(fā)射
sbit c_recive = P1^7;  //超聲波接收
uchar flag_hc_value;        //超聲波中間變量
long distance;             //距離
uint set_d;                 //距離
bit flag_csb_juli;          //超聲波超出量程
uint  flag_time0;           //用來保存定時(shí)器0的時(shí)候的
bit flag_300ms = 1 ;
uchar guangxian;            //光線的顯示變量
uchar set_gx;     //設(shè)置光線的強(qiáng)弱的變量
uchar value;
uchar flag_alarm;       //報(bào)警變量
static int  miao = 0,fen=45;//學(xué)習(xí)時(shí)間
uchar xuexi_start;   //開始學(xué)習(xí)標(biāo)志位
uchar menu_1;//菜單設(shè)計(jì)變量
/******************把設(shè)置數(shù)據(jù)保存到單片機(jī)內(nèi)部eepom中******************/
void write_eepom_12()
{
SectorErase(0x2000);
byte_write(0x2000, set_d % 256);//低8位
byte_write(0x2001, set_d / 256);//高8位距離分解寫入
byte_write(0x2002, set_gx);
byte_write(0x2057, value);
}
/******************把數(shù)據(jù)從單片機(jī)內(nèi)部eepom中讀出來*****************/
void read_eepom12()
{
set_d = byte_read(0x2001);
set_d  =set_d * 256 + byte_read(0x2000);  
set_gx = byte_read(0x2002);
value    = byte_read(0x2057);
}
/**************開機(jī)自檢eepom初始化*****************/
void init_eepom()
{
read_eepom12();  //先讀出保存的數(shù)據(jù)
if(value != 2)  //新的單片機(jī)初始單片機(jī)內(nèi)問EEPOM
{
  set_d = 15;//設(shè)置超聲波的距離
  value = 2;
  set_gx = 4;
  write_eepom_12();
}
}

/********************************************************************
* 名稱 : delay()
* 功能 : 延時(shí),延時(shí)時(shí)間大概為5US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay_uint(uint q)
{
while(q--);
}
/********************************************************************
* 名稱 : bit Busy(void)
* 功能 : 這個(gè)是一個(gè)讀狀態(tài)函數(shù),讀出函數(shù)是否處在忙狀態(tài)
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
bit busy(void)
{
bit busy_flag = 0;
rs = 0;
rw = 1;
e = 1;
delay_uint(3);
busy_flag = (bit)(P0 & 0x80);
e = 0;
return busy_flag;
}
/********************************************************************
* 名稱 : write_com(uchar com)
* 功能 : 1602命令函數(shù)
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
void write_com(uchar com)
{
while(busy());
e=0;
rs=0;
rw=0;
P0=com;
delay_uint(3);
e=1;
delay_uint(25);
e=0;
}
/********************************************************************
* 名稱 : write_data(uchar dat)
* 功能 : 1602寫數(shù)據(jù)函數(shù)
* 輸入 : 需要寫入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void write_data(uchar dat)
{
while(busy());
e=0;
rs=1;
rw=0;
P0=dat;
delay_uint(3);
e=1;
delay_uint(25);
e=0;
}
/***********************lcd1602上顯示兩位十進(jìn)制數(shù)************************/
void write_sfm2(uchar hang,uchar add,uchar date)
{
if(hang==1)   
  write_com(0x80+add);
else
  write_com(0x80+0x40+add); //第二行地址   
write_data(0x30+date/10%10); //十位
write_data(0x30+date%10); //個(gè)位
}
/***********************lcd1602上顯示超聲波距離************************/
void write_sfm_csb(uchar hang,uchar add,uint date)
{
if(hang==1)   
  write_com(0x80+add);
else
  write_com(0x80+0x40+add);   
write_data(0x30+date/100%10);
write_data('.');
write_data(0x30+date/10%10);
write_data(0x30+date%10);
}

/********************************************************************
* 名稱 : init_1602()
* 功能 : 1602初始化,請(qǐng)參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void init_1602()
{
write_com(0x38); //設(shè)置16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
write_com(0x0c); //開顯示,不顯示光標(biāo)
write_com(0x06); //地址加1,當(dāng)寫入數(shù)據(jù)的時(shí)候光標(biāo)右移
}
/********************************************************************
* 名稱 : write_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個(gè)字符開始顯示"ab cd ef" ,調(diào)用該函數(shù)如下
    write_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數(shù)據(jù)
* 輸出 : 無
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
if(hang==1)   
  write_com(0x80+add);
else
  write_com(0x80+0x40+add);
  while(1)               
  {
   if(*p == '\0')  break;
   write_data(*p);
   p++;
  }
}
uchar key_can;
/********************獨(dú)立按鍵程序*****************/
void key()
{
static uchar key_new;
key_can = 20;   //按鍵值還原
if((P3 & 0xf0) != 0xf0)   //按鍵值按下
{
  delay_uint(50);  //按鍵消抖
  if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
  {    //確認(rèn)按鍵按下
   key_new = 0;//標(biāo)志位清0
   switch(P3 & 0xf0)
   {
    case 0xe0:  key_can = 1;  break;  //左邊第1個(gè)
    case 0xd0:  key_can = 2;  break;  //左邊第2個(gè)
    case 0xb0:  key_can = 3;  break;  //左邊第3個(gè)
    case 0x70:  key_can = 4;  break;  //左邊第4個(gè)
   }
//   write_sfm2(2,0,key_can);   
  }
}
else
  key_new = 1;
}

/***********讀數(shù)模轉(zhuǎn)換數(shù)據(jù)********************************************************/
//請(qǐng)先了解ADC0832模數(shù)轉(zhuǎn)換的串行協(xié)議,再來讀本函數(shù),主要是對(duì)應(yīng)時(shí)序圖來理解,本函數(shù)是模擬0832的串行協(xié)議進(jìn)行的
      //  1  0  0 通道
      //  1  1  1 通道
unsigned char ad0832read(bit SGL,bit ODD)
{
unsigned char i=0,value=0,value1=0;  
  SCL=0;
  DO=1;
  CS=0;  //開始
  SCL=1;  //第一個(gè)上升沿
  SCL=0;
  DO=SGL;
  SCL=1;   //第二個(gè)上升沿
  SCL=0;
  DO=ODD;
  SCL=1;    //第三個(gè)上升沿
  SCL=0;    //第三個(gè)下降沿
  DO=1;
  for(i=0;i<8;i++)
  {
   SCL=1;
   SCL=0; //開始從第四個(gè)下降沿接收數(shù)據(jù)
   value<<=1;
   if(DO)
    value++;      
  }
  for(i=0;i<8;i++)
  {   //接收校驗(yàn)數(shù)據(jù)
   value1>>=1;
   if(DO)
    value1+=0x80;
   SCL=1;
   SCL=0;
  }
  CS=1;
  SCL=1;
  if(value==value1)    //與校驗(yàn)數(shù)據(jù)比較,正確就返回?cái)?shù)據(jù),否則返回0
   return value;
return 0;
}
/*********************小延時(shí)函數(shù)*****************************/
void delay()
{
_nop_();              //執(zhí)行一條_nop_()指令就是1us
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();  
}
/*********************超聲波測距程序*****************************/
void send_wave()
{
c_send = 1;             //10us的高電平觸發(fā)
delay();
c_send = 0;  
TH0 = 0;            //給定時(shí)器0清零
TL0 = 0;
TR0 = 0;      //關(guān)定時(shí)器0定時(shí)
flag_hc_value = 0;
while(!c_recive);    //當(dāng)c_recive為零時(shí)等待
TR0=1;
while(c_recive)        //當(dāng)c_recive為1計(jì)數(shù)并等待
{
  flag_time0 = TH0 * 256 + TL0;
  if((flag_hc_value > 1) || (flag_time0 > 65000))      //當(dāng)超聲波超過測量范圍時(shí),顯示3個(gè)888
  {
   TR0 = 0;
   flag_csb_juli = 2;
   distance = 888;
   flag_hc_value = 0;
   return ;
  }
  else
  {
   flag_csb_juli = 1;   
  }  
}
if(flag_csb_juli == 1)
{
  TR0=0;        //關(guān)定時(shí)器0定時(shí)
  distance = TH0;          //讀出定時(shí)器0的時(shí)間
  distance = distance * 256 + TL0;
  distance +=( flag_hc_value * 65536);//算出超聲波測距的時(shí)間  得到單位是ms
  distance *= 0.017;               // 0.017 = 340M / 2 = 170M = 0.017M 算出來是米
  if(distance > 350)     //距離 = 速度 * 時(shí)間
  {
   distance = 888;     //如果大于3.5m就超出超聲波的量程
  }
}  
}
/*********************定時(shí)器0、定時(shí)器1初始化******************/
void time_init()   
{
EA  = 1;     //開總中斷
TMOD = 0X11;   //定時(shí)器0、定時(shí)器1工作方式1
ET0 = 1;    //開定時(shí)器0中斷
TR0 = 1;    //允許定時(shí)器0定時(shí)
ET1 = 1;    //開定時(shí)器1中斷
TR1 = 1;    //允許定時(shí)器1定時(shí)
}
/*******************按鍵執(zhí)行函數(shù)******************/
void key_with()
{
if(menu_1 == 0)
{
  if(key_can == 1)
  {
      miao = 0;fen=45;
   xuexi_start = 1;  //開始學(xué)習(xí)   
  }
  if(key_can == 2)
  {
   xuexi_start = 0;  //暫停學(xué)習(xí)
   beep = 1;
  }
  if(key_can == 3)
  {
      xuexi_start = 1;  //繼續(xù)學(xué)習(xí)
  }
}
if(key_can == 4)
{
  menu_1 ++;
  if(menu_1 == 1)
  {
   write_string(1,0,"1.xsb:    m     ");
   write_string(2,0,"2.gm:  %        ");
   write_sfm_csb(1,6,set_d);//設(shè)置距離參數(shù)
   write_sfm2(2,5,set_gx);  //設(shè)置光線的參數(shù)
   write_com(0x80+0);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍
  }
  if(menu_1 == 2)
  {
   write_com(0x80+0x40+0);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍  
  }
  if(menu_1 >= 3)
  {
   menu_1 = 0;
   write_string(1,0,"csb:    m gm:  %");
   write_string(2,0,"   Time   :      ");
   write_com(0x0c);     //關(guān)閉顯示
  }   
}
if(menu_1 == 1)   //設(shè)置超聲波參數(shù)
{
  if(key_can == 3)  //
  {
    set_d ++;       //加超聲波距離報(bào)警數(shù)據(jù)
   write_sfm_csb(1,6,set_d);
   if(set_d >= 100)
    set_d = 100;
   write_com(0x80);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍  
  }
  if(key_can == 2)  //
  {
    set_d --;       //減超聲波距離報(bào)警數(shù)據(jù)
   if(set_d <= 10)
    set_d = 10;
   write_sfm_csb(1,6,set_d);
   write_com(0x80);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍  
  }
  write_eepom_12();     //保存數(shù)據(jù)
}
if(menu_1 == 2)
{
  if(key_can == 3)  //
  {
    set_gx ++;       //加光線報(bào)警數(shù)據(jù)
   write_sfm2(2,5,set_gx);
   if(set_gx >= 100)
    set_gx = 100;
   write_com(0x80+0x40);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍  
  }
  if(key_can == 2)  //
  {
    set_gx --;       //減光線報(bào)警數(shù)據(jù)
   if(set_gx <= 1)
    set_gx = 1;
   write_sfm2(2,5,set_gx);
   write_com(0x80 + 0x40);              //將光標(biāo)移動(dòng)到秒個(gè)位
   write_com(0x0f);                //顯示光標(biāo)并且閃爍  
  }
  write_eepom_12();     //保存數(shù)據(jù)
}
key_can = 20;
}
/*********************報(bào)警函數(shù)***************************/
void clock_beep()
{
static uchar value1,value2,value3;
// static uint time_value;

if(xuexi_start == 1)
{ if(set_gx >= guangxian)   //距離光線報(bào)警
{
  value2 ++;
  if(value2 >= 2)    //循環(huán)2次都是報(bào)警  增強(qiáng)抗干擾
  {
   flag_alarm = 2;
  }  
}else
  value2 = 0;
  if(distance <= set_d)   //距離報(bào)警
  {
   value1 ++;
   if(value1 >= 2)    //循環(huán)2次都是報(bào)警  增強(qiáng)抗干擾
   {
    flag_alarm = 1;
   }  
  }else
   value1 = 0;     
  if((miao == 0) && (fen == 0))   //時(shí)間報(bào)警
  {
      xuexi_start = 0;  //休息時(shí)間到了,停止學(xué)習(xí)
   flag_alarm = 3;
  }

}  
if(flag_alarm != 0)
{
  value3 ++;
  beep = ~beep; //報(bào)警
  if(value3 > 6)
  {
   value3 = 0;
   beep = 1; //取消報(bào)警
   flag_alarm = 0;  
  }   
}     
}
/********************************************************************
* 名稱 : Main()
* 功能 : 主函數(shù)
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Main()
{
init_1602();   //液晶初始化
time_init();   //定時(shí)器初始化
init_eepom();  //EEPROM初始化
// beep = 0;
write_string(1,0,"csb:    m gm:  %");  //讓第一行第0個(gè)字符顯示csb
write_string(2,0,"   Time   :      ");
while(1)
{
  key();      //按鍵識(shí)別函數(shù)
  if(key_can < 10)
   key_with();    //按鍵處理函數(shù)
  if(flag_300ms == 1)
  {   
   flag_300ms = 0;
   clock_beep();          //報(bào)警函數(shù)
   if(menu_1 == 0)
   {
    send_wave();   //超聲波測距離
    write_sfm_csb(1,4,distance);
    guangxian = ad0832read(1,0); //采集光線
    guangxian = guangxian * 100 / 255;
    write_sfm2(1,13,guangxian);  //值越大光線就越強(qiáng)

//    write_sfm2(2,3,shi);  //顯示時(shí)鐘
    write_sfm2(2,8,fen);  //顯示分鐘
    write_sfm2(2,11,miao);  //值越秒鐘
   }
  }
}
}

/*********************定時(shí)器0中斷服務(wù)程序 用做超聲波測距的************************/
void time0_int() interrupt 1  
{         
flag_hc_value ++;   // TH0 TL0 到65536后溢出中斷
}
/*********************定時(shí)器1中斷服務(wù)程序************************/
void time1_int() interrupt 3
{
static uint value;    //定時(shí)10ms中斷一次
TH1 = 0x3c;
TL1 = 0xb0;     //50ms初值
value++;
if(value % 6 == 0)
{
  flag_300ms = 1;   
}
if(value >= 20)
{
  value = 0 ;
  if(xuexi_start == 1)
  {
   miao--;    //減1秒鐘
   if(miao <= -1)
   {
    miao = 59;
    fen --;    //減1分鐘
    if(fen < -1)
    {
     fen = 0;
   
    }
   }
  }
}
}

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:631459 發(fā)表于 2019-10-28 15:43 | 只看該作者
#include "eepom52.h"這個(gè)頭文件是什么啊,在哪里找
回復(fù)

使用道具 舉報(bào)

板凳
ID:155507 發(fā)表于 2019-10-29 23:47 | 只看該作者
應(yīng)該是控制 eeprom的頭文件

  1. //eepom52.h
  2. #ifndef _EEPOM52_H_
  3. #define _EEPOM52_H_
  4. #include <intrins.h>
  5. #define uchar unsigned char
  6. #define uint unsigned int

  7. /********AT89C51扇區(qū)分布*******
  8. 第一扇區(qū):1000H--11FF
  9. 第二扇區(qū):1200H--13FF
  10. 第三扇區(qū):1400H--15FF
  11. 第四扇區(qū):1600H--17FF
  12. 第五扇區(qū):1800H--19FF
  13. 第六扇區(qū):1A00H--1BFF
  14. 第七扇區(qū):1C00H--1DFF
  15. 第八扇區(qū):1E00H--1FFF
  16. *****************/

  17. /********AT89C52扇區(qū)分布*******
  18. 第一扇區(qū):2000H--21FF
  19. 第二扇區(qū):2200H--23FF
  20. 第三扇區(qū):2400H--25FF
  21. 第四扇區(qū):2600H--27FF
  22. 第五扇區(qū):2800H--29FF
  23. 第六扇區(qū):2A00H--2BFF
  24. 第七扇區(qū):2C00H--2DFF
  25. 第八扇區(qū):2E00H--2FFF
  26. *****************/


  27. #define RdCommand 0x01 //定義ISP的操作命令
  28. #define PrgCommand 0x02
  29. #define EraseCommand 0x03
  30. #define Error 1
  31. #define Ok 0
  32. #define WaitTime 0x01 //定義CPU的等待時(shí)間
  33. sfr ISP_DATA=0xe2;  //寄存器申明
  34. sfr ISP_ADDRH=0xe3;
  35. sfr ISP_ADDRL=0xe4;
  36. sfr ISP_CMD=0xe5;
  37. sfr ISP_TRIG=0xe6;
  38. sfr ISP_CONTR=0xe7;

  39. /* ================ 打開 ISP,IAP 功能 ================= */
  40. void ISP_IAP_enable(void)
  41. {

  42.          EA = 0;       /* 關(guān)中斷   */
  43.          ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
  44.          ISP_CONTR = ISP_CONTR | WaitTime;    /* 寫入硬件延時(shí) */
  45.          ISP_CONTR = ISP_CONTR | 0x80;        /* ISPEN=1  */

  46. }
  47. /* =============== 關(guān)閉 ISP,IAP 功能 ================== */
  48. void ISP_IAP_disable(void)
  49. {

  50.          ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
  51.          ISP_TRIG = 0x00;
  52.          EA   =   1;   /* 開中斷 */

  53. }
  54. /* ================ 公用的觸發(fā)代碼 ==================== */
  55. void ISPgoon(void)
  56. {

  57.          ISP_IAP_enable();   /* 打開 ISP,IAP 功能 */
  58.          ISP_TRIG = 0x46;    /* 觸發(fā)ISP_IAP命令字節(jié)1 */
  59.          ISP_TRIG = 0xb9;    /* 觸發(fā)ISP_IAP命令字節(jié)2 */
  60.          _nop_();

  61. }
  62. /* ==================== 字節(jié)讀 ======================== */
  63. unsigned char byte_read(unsigned int byte_addr)
  64. {

  65.         EA = 0;
  66.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
  67.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  68.          ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */
  69.          ISP_CMD   = ISP_CMD | RdCommand; /* 寫入讀命令 */
  70.          ISPgoon();       /* 觸發(fā)執(zhí)行  */
  71.          ISP_IAP_disable();    /* 關(guān)閉ISP,IAP功能 */
  72.          EA  = 1;
  73.          return (ISP_DATA);    /* 返回讀到的數(shù)據(jù) */

  74. }
  75. /* ================== 扇區(qū)擦除 ======================== */
  76. void SectorErase(unsigned int sector_addr)
  77. {

  78.          unsigned int iSectorAddr;
  79.          iSectorAddr = (sector_addr & 0xfe00); /* 取扇區(qū)地址 */
  80.          ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
  81.          ISP_ADDRL = 0x00;
  82.          ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */
  83.          ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
  84.          ISPgoon();       /* 觸發(fā)執(zhí)行  */
  85.          ISP_IAP_disable();    /* 關(guān)閉ISP,IAP功能 */

  86. }
  87. /* ==================== 字節(jié)寫 ======================== */
  88. void byte_write(unsigned int byte_addr, unsigned char original_data)
  89. {

  90.          EA  = 0;
  91. //         SectorErase(byte_addr);
  92.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
  93.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  94.          ISP_CMD  = ISP_CMD & 0xf8;    /* 清低3位 */
  95.          ISP_CMD  = ISP_CMD | PrgCommand;  /* 寫命令2 */
  96.          ISP_DATA = original_data;   /* 寫入數(shù)據(jù)準(zhǔn)備 */
  97.          ISPgoon();       /* 觸發(fā)執(zhí)行  */
  98.          ISP_IAP_disable();     /* 關(guān)閉IAP功能 */
  99.          EA =1;

  100. }


  101. #endif       

復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

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