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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

STC89C52RC單片機控制兩塊PCF8591進行七路模擬量采集,程序調試不顯示。

[復制鏈接]
跳轉到指定樓層
樓主
ID:496131 發表于 2019-4-19 12:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
  1. #include<reg52.h>
  2. #include<stdio.h>
  3. #include <intrins.h>
  4. #include "PCF8591.H"

  5. #define uchar unsigned char
  6. #define uint  unsigned int

  7. #define  PCF8591 0x90    //寫數據地址,PCF8591 地址 ,把PCF8591定義成0x90
  8. //第二PCF8591程序
  9. #define  AddWr 0x92    //PCF8591 地址
  10. #define Data  P0    //數據端口
  11. bit ack;                 /*應答標志位*/
  12. sbit RS = P3^0;//Pin4
  13. sbit RW = P3^1; //Pin5
  14. sbit E  = P3^2;//Pin6
  15. unsigned char TempData[8];
  16. unsigned char  FirstLine[16]="Voltage:        ";
  17. unsigned char  SecondLine[16] ="Current:        ";
  18. unsigned char AD_CHANNEL1; // 定義函數中間變量
  19. unsigned char ADtemp;    //定義中間變量
  20. bit P2CF8591_SendByte(unsigned char addr,unsigned char channel);
  21. unsigned char P2CF8591_RcvByte(unsigned char addr);
  22. void disp(void);
  23. void InitLcd();
  24. void mDelay();
  25. sbit scl=P1^1;       //I2C  時鐘
  26. sbit sda=P1^0;       //I2C  數據

  27. sbit ENTER = P3^3;        //手動與自動切換
  28. sbit UP = P3^4;                //上
  29. sbit DOWN = P3^5;        //下
  30. sbit LEFT = P3^6;        //左
  31. sbit RIGHT = P3^7;        //右

  32. sbit LED1 = P1^2;
  33. sbit LED2 = P1^3;
  34. uchar Motor_Up[4]={0x08,0x04,0x02,0x01};
  35. uchar Motor_Down[4]={0x01,0x02,0x04,0x08};


  36. uchar Motor_Left[4]={0x10,0x20,0x40,0x80};
  37. uchar Motor_Right[4]={0x80,0x40,0x20,0x10};

  38. unsigned char AD_CHANNEL;  //定義中間變量
  39. //延時函數
  40. void Delay_ms(uint jj)
  41. {
  42.         uint ii;
  43.         while(jj--)
  44.                 for(ii=0;ii<125;ii++);
  45. }
  46. void UART_Init(void)
  47. {
  48.      TMOD = 0x20;   //定時器模式選擇
  49.      PCON = 0x00;
  50.      SCON = 0x50;                        
  51.      TH1 = 0xFd;    //設置波特率 9600
  52.      TL1 = 0xFd;
  53.      TR1 = 1;                //啟動定時器1
  54.          ES = 1;                //開串口中斷
  55.          EA = 1;                //開總中斷               
  56. }
  57. /********************************************************************
  58. * 名稱   : PSend_Hex()
  59. * 功能   : 發送字符串函數,可控制發送長度
  60. * 變量   : 無
  61. * 返回值 : 無
  62. ********************************************************************/
  63. void Send_Hex(unsigned char *p,unsigned char num)
  64. {
  65.            while(num--)   //剩余發送的字符數
  66.         {
  67.         SBUF = *p; //將要發送的數據賦給串口緩沖寄存器
  68.                 while(!TI);//等待發送結束
  69.                 TI = 0;    //軟件清零
  70.                 p++;       //指針加一
  71.         }        
  72. }
  73. void main()           //函數功能:主函數
  74. {         
  75. //        unsigned char ADtemp;                //定義中間變量

  76.         uchar AD_Up,AD_Down,AD_Left,AD_Right;
  77.         uchar i,j,k;
  78.         uchar Table[6];
  79.         Delay_ms(2000);
  80.         UART_Init();        //定時中斷函數

  81.         InitLcd();                   //1602初始化
  82.         while(1)
  83.         {
  84.             disp();
  85.                 if(!ENTER)         //手動與自動切換
  86.                 {
  87.                         Delay_ms(20);
  88.                         while(!ENTER);
  89.                         k++;        
  90.                 }
  91.                 if(k%2 == 0) //如果按鍵被按下
  92.                 {
  93.                 LED1 = 1;
  94.                 LED2 = 0;
  95.                 for(i=0;i<8;i++)
  96.                 {
  97.                         switch(AD_CHANNEL)
  98.                         {
  99.                                 case 0: PCF8591_ISendByte(PCF8591,0x41);
  100.                                 AD_Up=PCF8591_IRcvByte(PCF8591)*2;  //ADC0 模數轉換1
  101.                                 break;  
  102.                                 
  103.                                 case 1: PCF8591_ISendByte(PCF8591,0x42);
  104.                                 AD_Down=PCF8591_IRcvByte(PCF8591)*2;  //ADC1  模數轉換2
  105.                                 break;  
  106.                                 case 2: PCF8591_ISendByte(PCF8591,0x43);
  107.                                 AD_Left=PCF8591_IRcvByte(PCF8591)*2;  //ADC2 模數轉換3
  108.                                 break;  
  109.                                 
  110.                                 case 3: PCF8591_ISendByte(PCF8591,0x40);
  111.                                 AD_Right=PCF8591_IRcvByte(PCF8591)*2;  //ADC3  模數轉換4
  112.                                 break;
  113.                         }

  114.                         Send_Hex(Table,4);
  115.                         if(++AD_CHANNEL>3)
  116.                         {
  117.                          AD_CHANNEL=0;
  118.                         Table[0] = AD_Up;
  119.                         Table[1] = AD_Down;
  120.                         Table[2] = AD_Left;
  121.                         Table[3] = AD_Right;
  122.                          }

  123.                 }        
  124.                 }
  125.                 if(AD_CHANNEL1=0)          //第二PCF8591程序
  126.                 {
  127.                         P2CF8591_SendByte(AddWr,1);
  128.                         ADtemp = P2CF8591_RcvByte(AddWr);  //ADC0 模數轉換1        
  129.                         TempData[0]=(ADtemp*10/51)/10;             //處理0通道電壓顯示
  130.                         TempData[1]=(ADtemp*10/51)%100;             //處理0通道電壓顯示
  131.                         TempData[2]=((ADtemp*10)%51)/5;
  132.                         TempData[3]=((ADtemp*10)%51)%5;
  133.                 }                                                                    
  134.                 else //(AD_CHANNEL1=1)
  135.                 {        
  136.                         P2CF8591_SendByte(AddWr,0);
  137.                         ADtemp=P2CF8591_RcvByte(AddWr);  //ADC1  模數轉換2
  138.                         TempData[4]=ADtemp/51;//處理1通道電壓顯示
  139.                           TempData[6]=(ADtemp%51)/5;         
  140.                 }                        
  141.            if(++AD_CHANNEL1>2) AD_CHANNEL1=0;
  142.            disp();         
  143.            
  144.                 if(k%2 == 1)        //如果按鍵沒有被按下
  145.                 {
  146.                         LED1 = 0;
  147.                         LED2 = 1;
  148.                         AD_Up = 0;        //上
  149.                         AD_Down = 0;//下
  150.                         AD_Left = 0;//左
  151.                         AD_Right = 0;//右        
  152.                 }               
  153.         ///////根據光敏電阻A/D采樣結果,進行兩兩比較//////////
  154.          
  155.                 if(((AD_Up<AD_Down)&&(AD_Down-AD_Up>10))||(!UP))//上轉
  156.                 {
  157.                         for(i=0;i<10;i++)
  158.                         {
  159.                                 for(j=0;j<4;j++)
  160.                                 {
  161.                                         P2=Motor_Up[j];
  162.                                         Delay_ms(10);
  163.                                 }               
  164.                         }        
  165.                 }
  166.                 //////////////////上下光敏電阻A/D值比較////////////////////
  167.                 if(((AD_Up>AD_Down)&&(AD_Up-AD_Down>10))||(!DOWN))//下轉
  168.                 {
  169.                         for(i=0;i<10;i++)
  170.                         {
  171.                                 for(j=0;j<4;j++)
  172.                                 {
  173.                                         P2=Motor_Down[j];
  174.                                         Delay_ms(10);
  175.                                 }               
  176.                         }
  177.                 }
  178.                 //////////////左右光敏電阻A/D值比較///////////////
  179.                 if(((AD_Left<AD_Right)&&(AD_Right-AD_Left>10))||(!LEFT))//左轉
  180.                 {
  181.                         for(i=0;i<10;i++)
  182.                         {
  183.                                 for(j=0;j<4;j++)
  184.                                 {
  185.                                         P2=Motor_Left[j];
  186.                                         Delay_ms(10);
  187.                                 }               
  188.                         }
  189.                
  190.                 }
  191.                 ////////////////////左右光敏電阻A/D值比較//////////////////
  192.                 if(((AD_Left>AD_Right)&&(AD_Left-AD_Right>10))||(!RIGHT))//右轉
  193.                 {
  194.                         for(i=0;i<10;i++)
  195.                         {
  196.                                 for(j=0;j<4;j++)
  197.                                 {
  198.                                         P2=Motor_Right[j];
  199.                                         Delay_ms(10);
  200.                                 }               
  201.                         }
  202.                 }
  203.                 ////////////////////////////////////
  204.                 Delay_ms(100);//延時,可適當修改
  205.         }
  206. /*        switch(AD_CHANNEL1)          //第二PCF8591程序
  207.                 {
  208.                         case 0: P2CF8591_SendByte(AddWr,1);
  209.                              ADtemp = P2CF8591_RcvByte(AddWr);  //ADC0 模數轉換1        
  210.                                  TempData[0]=(ADtemp*10/51)/10;             //處理0通道電壓顯示
  211.                                  TempData[1]=(ADtemp*10/51)%100;             //處理0通道電壓顯示
  212.                                  TempData[2]=((ADtemp*10)%51)/5;
  213.                                  TempData[3]=((ADtemp*10)%51)%5;
  214.                                                                                    
  215.                                  break;  
  216.                         
  217.                         case 1: P2CF8591_SendByte(AddWr,0);
  218.                              ADtemp=P2CF8591_RcvByte(AddWr);  //ADC1  模數轉換2
  219.                                  TempData[4]=ADtemp/51;//處理1通道電壓顯示
  220.                                    TempData[6]=(ADtemp%51)/5;
  221.                                  break;  
  222.                         
  223.                         
  224.                 }                        
  225.            if(++AD_CHANNEL1>2) AD_CHANNEL1=0;
  226.            disp();          */
  227. }

  228. //第二個模塊程序

  229. /*******************************************************************
  230.                      起動總線函數               
  231. 函數原型: void  Start_I2c();  
  232. 功能:     啟動I2C總線,即發送I2C起始條件.  
  233. ********************************************************************/
  234. void Start_I2c()
  235. {
  236.   sda=1;         /*發送起始條件的數據信號*/
  237.   _nop_();
  238.   scl=1;
  239.   _nop_();        /*起始條件建立時間大于4.7us,延時*/
  240.   _nop_();
  241.   _nop_();
  242.   _nop_();
  243.   _nop_();   
  244.   sda=0;         /*發送起始信號*/
  245.   _nop_();        /* 起始條件鎖定時間大于4μs*/
  246.   _nop_();
  247.   _nop_();
  248.   _nop_();
  249.   _nop_();      
  250.   scl=0;       /*鉗住I2C總線,準備發送或接收數據 */
  251.   _nop_();
  252.   _nop_();
  253. }

  254. /*******************************************************************
  255.                       結束總線函數               
  256. 函數原型: void  Stop_I2c();  
  257. 功能:     結束I2C總線,即發送I2C結束條件.  
  258. ********************************************************************/
  259. void Stop_I2c()
  260. {
  261.   sda=0;      /*發送結束條件的數據信號*/
  262.   _nop_();       /*發送結束條件的時鐘信號*/
  263.   scl=1;      /*結束條件建立時間大于4μs*/
  264.   _nop_();
  265.   _nop_();
  266.   _nop_();
  267.   _nop_();
  268.   _nop_();
  269.   sda=1;      /*發送I2C總線結束信號*/
  270.   _nop_();
  271.   _nop_();
  272.   _nop_();
  273.   _nop_();
  274. }

  275. /*******************************************************************
  276.                  字節數據發送函數               
  277. 函數原型: void  I2C_SendByte(UCHAR c);
  278. 功能:     將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
  279.           此狀態位進行操作.(不應答或非應答都使ack=0)     
  280.            發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
  281. ********************************************************************/
  282. void  I2C_SendByte(unsigned char  c)
  283. {
  284. unsigned char  i;

  285. for(i=0;i<8;i++)  /*要傳送的數據長度為8位*/
  286.     {
  287.      if((c<<i)&0x80)sda=1;   /*判斷發送位*/
  288.        else  sda=0;               
  289.      _nop_();
  290.      scl=1;               /*置時鐘線為高,通知被控器開始接收數據位*/
  291.       _nop_();
  292.       _nop_();             /*保證時鐘高電平周期大于4μs*/
  293.       _nop_();
  294.       _nop_();
  295.       _nop_();         
  296.      scl=0;
  297.     }

  298.     _nop_();
  299.     _nop_();
  300.     sda=1;                /*8位發送完后釋放數據線,準備接收應答位*/
  301.     _nop_();
  302.     _nop_();   
  303.     scl=1;
  304.     _nop_();
  305.     _nop_();
  306.     _nop_();
  307.     if(sda==1)ack=0;     
  308.        else ack=1;        /*判斷是否接收到應答信號*/
  309.     scl=0;
  310.     _nop_();
  311.     _nop_();
  312. }

  313. /*******************************************************************
  314.                  字節數據接收函數               
  315. 函數原型: UCHAR  I2C_RcvByte();
  316. 功能:        用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
  317.           發完后請用應答函數應答從機。  
  318. ********************************************************************/   
  319. unsigned char   I2C_RcvByte()
  320. {
  321.   unsigned char  retc=0,i;
  322.   sda=1;                     /*置數據線為輸入方式*/
  323.   for(i=0;i<8;i++)
  324.       {
  325.         _nop_();           
  326.         scl=0;                  /*置時鐘線為低,準備接收數據位*/
  327.         _nop_();
  328.         _nop_();                 /*時鐘低電平周期大于4.7μs*/
  329.         _nop_();
  330.         _nop_();
  331.         _nop_();
  332.         scl=1;                  /*置時鐘線為高使數據線上數據有效*/
  333.         _nop_();
  334.         _nop_();
  335.         retc=retc<<1;
  336.         if(sda==1)retc=retc+1;  /*讀數據位,接收的數據位放入retc中 */
  337.         _nop_();
  338.         _nop_();
  339.       }
  340.   scl=0;   
  341.   _nop_();
  342.   _nop_();
  343.   return(retc);
  344. }

  345. /********************************************************************
  346.                      應答子函數
  347. 函數原型:  void Ack_I2c(bit a);
  348. 功能:      主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
  349. ********************************************************************/
  350. void Ack_I2c(bit a)
  351. {  
  352.   if(a==0)
  353.   {
  354.   sda=0;
  355.     _nop_();
  356.   _nop_();
  357.   _nop_();      
  358.   scl=1;
  359.   _nop_();
  360.   _nop_();                    /*時鐘低電平周期大于4μs*/
  361.   _nop_();
  362.   _nop_();
  363.   _nop_();  
  364.   scl=0;                     /*清時鐘線,住I2C總線以便繼續接收*/
  365.   _nop_();
  366.   _nop_();   
  367.   sda=1;
  368.     _nop_();
  369.   _nop_();   

  370.   }              /*在此發出應答或非應答信號 */
  371.   else
  372. {  sda=1;                                  /*0為發出應答,1為非應答信號 */
  373.   _nop_();
  374.   _nop_();
  375.   _nop_();      
  376.   scl=1;
  377.   _nop_();
  378.   _nop_();                    /*時鐘低電平周期大于4μs*/
  379.   _nop_();
  380.   _nop_();
  381.   _nop_();  
  382.   scl=0;                     /*清時鐘線,住I2C總線以便繼續接收*/
  383.   _nop_();
  384.   _nop_();
  385.   sda=0;
  386.       _nop_();
  387.   _nop_();   

  388.   }   
  389. }

  390. /************************************************************
  391. * 函數名        : Pcf8591_SendByte
  392. * 函數功能                : 寫入一個控制命令
  393. * 輸入          : addr(器件地址),channel(轉換通道)
  394. * 輸出                 : 無
  395. ************************************************************/
  396. bit P2CF8591_SendByte(unsigned char addr,unsigned char channel)
  397. {
  398.    Start_I2c();              //啟動總線
  399.    I2C_SendByte(addr);            //發送器件地址
  400.    if(ack==0)return(0);
  401.    I2C_SendByte(0x40|channel);              //發送控制字節
  402.    if(ack==0)return(0);
  403.    Stop_I2c();               //結束總線
  404.    return(1);
  405. }

  406. /************************************************************
  407. * 函數名               : PCF8591_RcvByte
  408. * 函數功能           : 讀取一個轉換值
  409. * 輸入          :
  410. * 輸出          : dat
  411. ************************************************************/
  412. unsigned char P2CF8591_RcvByte(unsigned char addr)
  413. {  
  414.    unsigned char dat;

  415.    Start_I2c();          //啟動總線
  416.    I2C_SendByte(addr+1);      //發送器件地址
  417.    if(ack==0)return(0);
  418.    dat=I2C_RcvByte();          //讀取數據0

  419.    Ack_I2c(1);           //發送非應答信號
  420.    Stop_I2c();           //結束總線
  421.    return(dat);
  422. }

  423. /******************************************************************/
  424. /*                   1602液晶屏相關函數                           */
  425. /******************************************************************/
  426. void DelayUs(unsigned char us)//delay us
  427. {
  428. unsigned char uscnt;
  429. uscnt=us>>1;/* Crystal frequency in 12MHz*/
  430. while(--uscnt);
  431. }
  432. /******************************************************************/
  433. void DelayMs(unsigned char ms)//delay Ms
  434. {
  435. while(--ms)
  436.    {
  437.      DelayUs(250);
  438.      DelayUs(250);
  439.          DelayUs(250);
  440.          DelayUs(250);
  441.    }
  442. }
  443. void WriteCommand(unsigned char c)
  444. {
  445.         DelayMs(5);//short delay before operation
  446.         E=0;
  447.         RS=0;
  448.         RW=0;
  449.         _nop_();
  450.         E=1;
  451.         Data=c;
  452.         E=0;
  453. }
  454. /****************************************************************/
  455. void WriteData(unsigned char c)
  456. {
  457. DelayMs(5);   //short delay before operation
  458. E=0;
  459. RS=1;
  460. RW=0;
  461. _nop_();
  462. E=1;
  463. Data=c;
  464. E=0;
  465. RS=0;
  466. }
  467. /*********************************************************************/
  468. void ShowChar(unsigned char pos,unsigned char c)
  469. {
  470. unsigned char p;
  471. if (pos>=0x10)
  472.     p=pos+0xb0; //是第二行則命令代碼高4位為0xc
  473. else
  474.     p=pos+0x80; //是第二行則命令代碼高4位為0x8
  475. WriteCommand (p);//write command
  476. WriteData (c);   //write data
  477. }
  478. /*************************************************************************/
  479. void ShowString (unsigned char line,char *ptr)
  480. {
  481. unsigned char l,i;
  482. l=line<<4;
  483. for (i=0;i<16;i++)
  484.   ShowChar (l++,*(ptr+i));//循環顯示16個字符
  485. }
  486. /*********************************************************************/
  487. void InitLcd()
  488. {
  489. DelayMs(15);
  490. WriteCommand(0x38); //display mode
  491. WriteCommand(0x38); //display mode
  492. WriteCommand(0x38); //display mode
  493. WriteCommand(0x06); //顯示光標移動位置
  494. WriteCommand(0x0c); //顯示開及光標設置
  495. WriteCommand(0x01); //顯示清屏

  496. }

  497. void disp(void)
  498. {
  499.    unsigned char i=0;
  500.    while(FirstLine[i]!=' ')
  501.    {
  502.            ShowString(0,FirstLine);
  503.         i++;
  504.    }
  505.         FirstLine[8]= '0'+TempData[0];
  506.         FirstLine[9]= '0'+TempData[1];
  507.         FirstLine[10]='.';
  508.         FirstLine[11]='0'+TempData[2];
  509.         FirstLine[12]='0'+TempData[3];
  510.         FirstLine[14]='V';
  511.                
  512.         ShowString(0,FirstLine);
  513.         
  514.         while(SecondLine[i]!=' ')
  515.         {
  516.                    ShowString(1,SecondLine);
  517.                 i++;
  518.         }
  519.         SecondLine[8]='0'+TempData[4];
  520.         SecondLine[11]='0'+TempData[6];
  521.         SecondLine[10]='.';
  522.         SecondLine[14]='V';
  523.         
  524.         ShowString(1,SecondLine);
  525. }
  526. /*------------------------------------------------
  527.                     延時程序
  528. ------------------------------------------------*/
  529. void mDelay(unsigned char j)
  530. {
  531.   unsigned int i;
  532.   for(;j>0;j--)
  533.      {
  534.           for(i=0;i<125;i++)
  535.              {;}
  536.           }
  537.   }
復制代碼

程序修改.rar

124.98 KB, 下載次數: 37

仿真

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

使用道具 舉報

沙發
ID:496131 發表于 2019-4-19 22:11 | 只看該作者
自己修改成功啦,謝謝各位高手
回復

使用道具 舉報

板凳
ID:465737 發表于 2020-1-30 14:28 | 只看該作者
請問一下,您這個是怎樣解決問題的呢,我遇到了差不多的問題,單片機不工作
回復

使用道具 舉報

地板
ID:648281 發表于 2020-1-30 19:29 | 只看該作者
ljw8005 發表于 2020-1-30 14:28
請問一下,您這個是怎樣解決問題的呢,我遇到了差不多的問題,單片機不工作

你好!
具體是什么現象呢?拍照或截圖說明情況
回復

使用道具 舉報

5#
ID:1084659 發表于 2023-7-24 18:23 | 只看該作者
你好想問一下怎么解決的
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 九九久久精品视频 | 一区精品国产欧美在线 | 亚洲视频在线免费观看 | 日韩在线播放视频 | 久久久久精| 亚洲精品国产综合区久久久久久久 | 久久久久国产精品 | 99婷婷| 91一区二区在线观看 | 日韩国产精品一区二区三区 | 成人在线观看亚洲 | 操人网 | 7777久久 | 久久成人人人人精品欧 | 高清国产一区二区 | 中文字幕乱码一区二区三区 | 国产精品久久片 | 超碰97人人人人人蜜桃 | 久久看看 | 精品视频一区二区三区在线观看 | 精品视频一区二区三区 | 欧洲国产精品视频 | 亚洲高清免费 | 操人网站| 国产日韩欧美综合 | 日韩三级在线观看 | 综合九九| 欧美日韩综合 | 久久精品中文字幕 | 精产国产伦理一二三区 | 亚洲第一福利视频 | 亚洲一区二区在线视频 | 欧洲一级黄| 黄色大片在线免费观看 | 色伊人| 九九天堂网 | 九色 在线 | 日本欧美国产 | 国产男女视频 | 日日夜夜天天 | 91精品国产99久久 |