久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8975|回復: 2
打印 上一主題 下一主題
收起左側

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

[復制鏈接]
跳轉到指定樓層
樓主
50黑幣

#include <reg52.h>
#define uchar unsigned char  //無符號字符型 宏定義 變量范圍0~255
#define uint  unsigned int  //無符號整型 宏定義 變量范圍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;  //蜂鳴器

//這三個引腳參考資料
sbit rs=P1^0;  //1602數據/命令選擇引腳 H:數據       L:命令
sbit rw=P1^1;  //1602讀寫引腳          H:數據寄存器   L:指令寄存器
sbit e =P1^2;  //1602使能引腳          下降沿觸發
sbit c_send   = P1^6;  //超聲波發射
sbit c_recive = P1^7;  //超聲波接收
uchar flag_hc_value;        //超聲波中間變量
long distance;             //距離
uint set_d;                 //距離
bit flag_csb_juli;          //超聲波超出量程
uint  flag_time0;           //用來保存定時器0的時候的
bit flag_300ms = 1 ;
uchar guangxian;            //光線的顯示變量
uchar set_gx;     //設置光線的強弱的變量
uchar value;
uchar flag_alarm;       //報警變量
static int  miao = 0,fen=45;//學習時間
uchar xuexi_start;   //開始學習標志位
uchar menu_1;//菜單設計變量
/******************把設置數據保存到單片機內部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);
}
/******************把數據從單片機內部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);
}
/**************開機自檢eepom初始化*****************/
void init_eepom()
{
read_eepom12();  //先讀出保存的數據
if(value != 2)  //新的單片機初始單片機內問EEPOM
{
  set_d = 15;//設置超聲波的距離
  value = 2;
  set_gx = 4;
  write_eepom_12();
}
}

/********************************************************************
* 名稱 : delay()
* 功能 : 延時,延時時間大概為5US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void delay_uint(uint q)
{
while(q--);
}
/********************************************************************
* 名稱 : bit Busy(void)
* 功能 : 這個是一個讀狀態函數,讀出函數是否處在忙狀態
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
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命令函數
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/
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寫數據函數
* 輸入 : 需要寫入1602的數據
* 輸出 : 無
***********************************************************************/
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上顯示兩位十進制數************************/
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); //個位
}
/***********************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初始化,請參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void init_1602()
{
write_com(0x38); //設置16*2顯示,5*7點陣,8位數據接口
write_com(0x0c); //開顯示,不顯示光標
write_com(0x06); //地址加1,當寫入數據的時候光標右移
}
/********************************************************************
* 名稱 : write_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
    write_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
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;
/********************獨立按鍵程序*****************/
void key()
{
static uchar key_new;
key_can = 20;   //按鍵值還原
if((P3 & 0xf0) != 0xf0)   //按鍵值按下
{
  delay_uint(50);  //按鍵消抖
  if(((P3 & 0xf0) != 0xf0) && (key_new == 1))
  {    //確認按鍵按下
   key_new = 0;//標志位清0
   switch(P3 & 0xf0)
   {
    case 0xe0:  key_can = 1;  break;  //左邊第1個
    case 0xd0:  key_can = 2;  break;  //左邊第2個
    case 0xb0:  key_can = 3;  break;  //左邊第3個
    case 0x70:  key_can = 4;  break;  //左邊第4個
   }
//   write_sfm2(2,0,key_can);   
  }
}
else
  key_new = 1;
}

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

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

}  
if(flag_alarm != 0)
{
  value3 ++;
  beep = ~beep; //報警
  if(value3 > 6)
  {
   value3 = 0;
   beep = 1; //取消報警
   flag_alarm = 0;  
  }   
}     
}
/********************************************************************
* 名稱 : Main()
* 功能 : 主函數
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Main()
{
init_1602();   //液晶初始化
time_init();   //定時器初始化
init_eepom();  //EEPROM初始化
// beep = 0;
write_string(1,0,"csb:    m gm:  %");  //讓第一行第0個字符顯示csb
write_string(2,0,"   Time   :      ");
while(1)
{
  key();      //按鍵識別函數
  if(key_can < 10)
   key_with();    //按鍵處理函數
  if(flag_300ms == 1)
  {   
   flag_300ms = 0;
   clock_beep();          //報警函數
   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);  //值越大光線就越強

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

/*********************定時器0中斷服務程序 用做超聲波測距的************************/
void time0_int() interrupt 1  
{         
flag_hc_value ++;   // TH0 TL0 到65536后溢出中斷
}
/*********************定時器1中斷服務程序************************/
void time1_int() interrupt 3
{
static uint value;    //定時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空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

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

使用道具 舉報

板凳
ID:155507 發表于 2019-10-29 23:47 | 只看該作者
應該是控制 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扇區分布*******
  8. 第一扇區:1000H--11FF
  9. 第二扇區:1200H--13FF
  10. 第三扇區:1400H--15FF
  11. 第四扇區:1600H--17FF
  12. 第五扇區:1800H--19FF
  13. 第六扇區:1A00H--1BFF
  14. 第七扇區:1C00H--1DFF
  15. 第八扇區:1E00H--1FFF
  16. *****************/

  17. /********AT89C52扇區分布*******
  18. 第一扇區:2000H--21FF
  19. 第二扇區:2200H--23FF
  20. 第三扇區:2400H--25FF
  21. 第四扇區:2600H--27FF
  22. 第五扇區:2800H--29FF
  23. 第六扇區:2A00H--2BFF
  24. 第七扇區:2C00H--2DFF
  25. 第八扇區: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的等待時間
  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;       /* 關中斷   */
  43.          ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
  44.          ISP_CONTR = ISP_CONTR | WaitTime;    /* 寫入硬件延時 */
  45.          ISP_CONTR = ISP_CONTR | 0x80;        /* ISPEN=1  */

  46. }
  47. /* =============== 關閉 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. /* ================ 公用的觸發代碼 ==================== */
  55. void ISPgoon(void)
  56. {

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

  61. }
  62. /* ==================== 字節讀 ======================== */
  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();       /* 觸發執行  */
  71.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
  72.          EA  = 1;
  73.          return (ISP_DATA);    /* 返回讀到的數據 */

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

  78.          unsigned int iSectorAddr;
  79.          iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
  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();       /* 觸發執行  */
  85.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */

  86. }
  87. /* ==================== 字節寫 ======================== */
  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;   /* 寫入數據準備 */
  97.          ISPgoon();       /* 觸發執行  */
  98.          ISP_IAP_disable();     /* 關閉IAP功能 */
  99.          EA =1;

  100. }


  101. #endif       

復制代碼
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精选久久 | 伊人久久免费视频 | 久色一区 | 一区二区三区成人 | 午夜黄色影院 | 91高清在线观看 | 欧美综合久久久 | 亚洲成人精品 | 国产精品99久久久久久久久久久久 | 国产又爽又黄的视频 | 中文字幕一区二区不卡 | 成人在线观看中文字幕 | 青娱乐国产 | 色婷婷久久久久swag精品 | 精品视频免费在线 | 中文字幕不卡视频在线观看 | 人人人艹 | 日韩久久精品 | 久久综合影院 | 日日综合| 欧美精品国产精品 | 欧美亚洲国产日韩 | 中文字幕av在线播放 | 欧洲av在线 | 国产精品伦理一区二区三区 | 欧美日韩在线免费 | 看a网站| 日本精品一区二区 | 亚洲精品一区二区在线观看 | 亚洲欧美日韩激情 | 中文字幕一区二区三区精彩视频 | 中国美女av| 黄色大片免费网站 | 欧美一级二级三级 | 日日噜| 激情av网站 | 亚洲a网| 羞羞视频网站在线观看 | 日日日操 | 国产毛片久久久久久久久春天 | 久久久www成人免费无遮挡大片 |