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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

關于51單片機采樣問題

[復制鏈接]
跳轉到指定樓層
樓主
ID:51758 發表于 2013-8-5 15:35 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
問題概述如下:我要用51單片機采樣外部的紅外信號數據,用定時器0定時26us進行采樣,然后將采樣的數值存入數組,但現在發現采樣出來的數值和理論值差距有點大,比如說理論值是0.56ms,采樣出來的值有可能只有0.30ms,這個問題出在哪里?
代碼如下:#include<reg52.h>
#include<intrins.h>

typedef unsigned int uint;
typedef unsigned char uchar;
sbit  Txd_Port = P1^0;                         //發射腳
sbit remotein = P3^2;                        //遙控信號輸入口
sbit Txd_key = P1^1;                    //發射鍵
sbit Txd_key1 = P1^2;                        //發射鍵2
sbit scl = P3^6;                //I2C時鐘信號線
sbit sda = P3^7;                                //I2C數據線
unsigned short data count1 = 0;
uchar idata remotedata[80];                   //存脈沖寬度數據用         數組較大,放在idata里 ,只能用指針讀寫
uchar int_flag = 0;                                        // 紅外接收中斷是否產生
uchar Time1_Flag = 0;


sbit test0 = P0^0;
sbit test1 = P0^1;
sbit test2 = P0^2;
sbit test3 = P0^3;
sbit test4 = P0^4;
sbit test5 = P0^5;
sbit test6 = P0^6;
sbit test7 = P0^7;

/***************************************
延時2個_nop_
***************************************/
void flash(void)
{
        _nop_();
        _nop_();
}
/**************************************
Delay_1ms   延時1MS

**************************************/
void Delay_1ms(uint i)
{
        uint x, j;
        for(j=0; j<i; j++)
        for(x=0; x<=148; x++)
        ;       
}
/********************************************************************
* 名稱 : x24c02_init()
* 功能 : 24c02初始化子程序
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void x24c02_init(void)
{
        scl = 1;
        flash();
        sda = 1;
        flash();
}

/********************************************************************
* 名稱 : start(void)
* 功能 : 啟動I2C總線
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void start(void)
{
        scl = 1;
        flash();
        sda = 1;
        flash();
        sda = 0;
        flash();
        scl = 0;
        flash();
}

/********************************************************************
* 名稱 : stop()
* 功能 : 停止I2C總線
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void stop()
{
        scl = 0;
        flash();
        sda = 0;
        flash();
        scl = 1;
        flash();
        sda = 1;
        flash();
}

/********************************************************************
* 名稱 : writex()
* 功能 : 寫一個字節
* 輸入 : j(需要寫入的值)
* 輸出 : 無
***********************************************************************/
void writex(uchar j)
{  
        uchar i,temp;
        temp = j;
        for(i=0; i<8; i++)
        {
                scl = 0;
                flash();
                sda = (bit)(temp & 0x80);
                flash();
                scl = 1;
                flash();
                temp = temp << 1;
        }
        scl = 0;
        flash();
}

/********************************************************************
* 名稱 : readx()
* 功能 : 讀一個字節
* 輸入 : 無
* 輸出 : 讀出的值
***********************************************************************/
uchar readx(void)
{
        uchar i, j, k = 0;
        for(i=0; i<8; i++)
        {
                scl = 1;
                flash();               
                if(sda == 1)
                {
                        j = 1;
                }
                else j = 0;
                k = (k << 1) | j;
                scl = 0;
                flash();
        }
        return(k);
}

/********************************************************************
* 名稱 : ack()
* 功能 : I2C總線時鐘
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void ack(void)
{
        scl = 1;
        flash();
        flash();
        scl = 0;
        flash();
}

/********************************************************************
* 名稱 : x24c02_read()
* 功能 : 從24c02中讀出值
* 輸入 : address(要在這個地址讀取值)
* 輸出 : 從24c02中讀出的值
***********************************************************************/
uchar x24c02_read(uchar address)
{
        uchar i;
        start();
        writex(0xa0);
        ack();
        writex(address);
        ack();
        start();
        writex(0xa1);
        ack();
        i = readx();
        sda = 1;           //no ack
        ack();
        stop();
        return(i);
}

/********************************************************************
* 名稱 : x24c02_write()
* 功能 : 想24c02中寫入數據
* 輸入 : address(地址) , info(值)
* 輸出 : 無
***********************************************************************/
void x24c02_write(uchar address, uchar info)
{
        start();
        writex(0xa0);
        ack();
        writex(address);
        ack();
        writex(info);
        ack();
        stop();
}


/**************************************
函數名稱:矩陣鍵盤
用法:矩陣端口接P2口
***************************************/
int Detect_key_down(void)                  
{
        uchar temp = 0x00;
        P2 = 0xfe;
        temp = P2;
        switch (temp) {
                case 0xee: return 0;
                case 0xde: return 1;
                case 0xbe: return 2;
                case 0x7e: return 3;
                default: break;
        }
        P2 = 0xfd;
        temp = P2;
        switch (temp) {
                case 0xed: return 4;
                case 0xdd: return 5;
                case 0xbd: return 6;
                case 0x7d: return 7;
                default: break;
        }
        P2 = 0Xfb;
        temp = P2;
                switch (temp) {
                case 0xeb: return 8;
                case 0xdb: return 9;
                case 0xbb: return 10;
                case 0x7b: return 11;
                default: break;
        }
        P2 = 0Xf7;
        temp = P2;
        switch (temp) {
                case 0xe7: return 12;
                case 0xd7: return 13;
                case 0xb7: return 14;
                case 0x77: return 15;
                default: break;
        }
        return 16;
} //end  KEY
/**************************************
函數功能:紅外線產生中斷函數
用法:紅外線接收口接P3^2
****************************************/
void IR_RexFlag()  interrupt  0                                    
{
        EX0 = 0;
        int_flag = 1;
        TR0 = 1;
        count1 = 0;                                           //開定時器0   26us
}
void Time0_init()
{
        TH0 = 0Xe7;                           //38KHz載波    26us
        TL0 = 0Xe7;
        ET0 = 1;              //開中斷
}
void  Time0_26us() interrupt 1
{
         Txd_Port = 1;
         TR1 = 1;
         count1++;
         test4 = 0;
}
void Time1_init()
{
        TH1 = 0Xf9;                           //8us
        TL1 = 0Xf9;
        //ET1 = 1;
}
void Time1_9us() interrupt 3
{
        TR1 = 0;              //關定時器
        Txd_Port = Time1_Flag;
        test3 = 0;
}
void TR0_Count(unsigned short count)                   //26us*count,有信號
{
        Time1_Flag = 0;
        count1 = 0;
        TR0 = 1;
        while(count1<count);
        TR0 = 0;
}
void TR0_Count1(unsigned short count)
{                                                                                          //26*count,無信號
        Time1_Flag = 1;
        count1 = 0;
        TR0 = 1;
        while(count1<count);
        TR0 = 0;
}
void Com_Init(void)                                                                //串口打印初始化
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;                       
     TH1 = 0xFd;
     TL1 = 0xFd;
     TR1 = 1;                       
}
int main(void)
{
        uchar count_flag = 0;       
        uchar IR_First = 0;                    //紅外線接收開啟中斷標志
        uchar key_again = 0;                                  //按第二個按鍵的其實條件
        char n_elements = 80;
        uint data1 = 0;                       //記錄數組里面的數據
        uchar *P = 0;                                                //將idata的數組存到E2PROM里面
        //uchar sec = 0;                                                //數組元素
        uchar last_in = 0;                                          // 默認輸入為低電平
        uchar key_value;                                        //存放按鍵值
//        uchar close_T0 = 0;
        uchar key_down_flag = 0;                        //按鍵抬起的標記(按鍵已經按下過了)
        uchar *pArray = 0;                                           //接收指針
        unsigned short *pArray1 = 0;
        uchar *PTex = 0;                                          //發射指針
        unsigned short *PTex1 = 0;
        uchar *PE = &remotedata[0];                        //數組存入E2PROM的指針
        uchar up_down = 0;                                                                //標記紅外線的9MS低電平,4.5MS高電平的引導碼
        uchar Key_down = 1;
        uchar i = 0;
        uchar j = 0;
        uchar k = 0;
        unsigned short remoteout = 0;

        //for(i=0;i<80;i++)           //清空數組內存
        //{
        //        remotedata[i] = 0x00;
        //}
        x24c02_init();                //初始化I2C總線

        test0 = 1;
        test1 = 1;
        test2 = 1;
        test3 = 1;
        test4 = 1;
        test5 = 1;
        test6 = 1;
        test7 = 1;


          EA = 1;
          TMOD = 0X22;              //8位自動重裝
        IT0 = 1;                                  //脈沖觸發方式,負跳變有效
          Time0_init();
          Time1_init();


        while(1)
        {
                key_value = Detect_key_down();
                if (key_value == 16)
                {        // 沒有按鍵按下,或者按鍵已經UP
                       
                    if (key_down_flag == 1)       
                        {                 // 按鍵1抬起       
                                P = &remotedata[0];
                                for(i=0;i<80;i++)                                 //數組寫入E2PROM
                                {
                                        x24c02_write(i,*P);
                                        P++;
                                        Delay_1ms(5);                                          //每一次寫數據后要進入E2PROM內部寫周期,最大時長為5ms
                                }
                                 key_down_flag = 0;
                                    IR_First = 0;
                                //TR1 = 0;
                        //        if(close_T0 == 0)
                        //        {
                        //                TR0 = 0;        //        關定時器0
                        //                TR1 = 0;
                        //                close_T0 = 1;
                        //        }
                                //PTex = &remotedata[0];
                                //PTex1 = (unsigned short*)&remotedata[0];
                        }       
                        if(key_down_flag == 2)
                        {        //如果按鍵2抬起
                                P = &remotedata[0];
                                for(i=80;i<160;i++)                                 //數組寫入E2PROM
                                {
                                        x24c02_write(i,*P);
                                        P++;
                                        Delay_1ms(5);
                                        test0 = 0;                                          //每一次寫數據后要進入E2PROM內部,寫周期最大時長為5ms
                                }
                                 key_down_flag = 0;
                                //int_flag = 0;                         //紅外線標志
                                //last_in = 0;                                         //高低電平翻轉標志
                                //up_down = 0;                                         //9ms,4.5ms判斷標志
                                //pArray = &remotedata[0];
                                //pArray1 = (unsigned short*)&remotedata[0];
                                //TR0 = 0;                                                  //一次接收完成以后定時器關閉
                                //TR1 = 0;
                        }
                               


                                if(Txd_key == 0)
                                  {
                                        PE = &remotedata[0];
                                        Com_Init();
                                        while(Txd_key ==0);
                                        for(i=0;i<80;i++)
                                        {
                                                *PE= x24c02_read(i);                                          
                                                SBUF = *PE;
                                           while(!TI)
                                           {
                                                           ;
                                           }
                                           TI = 0;
                                          // Delay_1ms(5);
                                           PE++;
                                        }
                                }
                                if(Txd_key1 == 0)
                                 {
                                        PE = &remotedata[0];
                                        Com_Init();
                                        while(Txd_key1 ==0 );
                                        for(i=0;i<80;i++)
                                        {
                                                *PE        = x24c02_read(80+i);                                          
                                                SBUF = *PE;
                                                  while(!TI)
                                                  {
                                                           ;
                                                  }
                                                  TI = 0;
                                                  Delay_1ms(5);
                                                  PE++;
                                        }
                                }                                                
                                 
                /*        if(Txd_key == 0)                           //發射0鍵按下         
                        {
                                PE = &remotedata[0];
                                for(i=0;i<80;i++)
                                {
                                        *PE++ = x24c02_read(i);
                                //        remotedata[i] = x24c02_read(i);
                                }
                                ET1 = 1;               //開啟定時器1中斷    接收的時候不用定時器1;
                                PTex = &remotedata[0];
                                PTex1 = (unsigned short*)&remotedata[0];
                                data1 = (*PTex1);
                                TR0_Count(data1);           //9MS低電平
                                PTex1++;
                                data1 = (*PTex1);           //4.5MS高電平
                                TR0_Count1(data1);
                                PTex1++;
                                PTex = (uchar*)PTex1;
                                test0 = 0;

                                for(j=0;j<n_elements-4;j++)
                                {
                                        data1 = (*PTex);
                                        TR0_Count(data1);          //發信號
                                        PTex++;
                                        data1 = (*PTex);          
                                        TR0_Count1(data1);          //不發信號
                                        PTex++;
                                        test1 = 0;
                                        if(*PTex == 0)
                                        {
                                                Txd_Port = 1;
                                                test2 = 0;
                                        }
                                }
                                TR0_Count1(200);                                        //兩組數據之間50ms的時間間隔
                        }
                        if(Txd_key1 == 0)                           //發射鍵1按下         
                        {
                                PE = &remotedata[0];
                                for(i=0;i<80;i++)
                                {
                                        *PE++ = x24c02_read(i+80);
                                //        remotedata[i] = x24c02_read(i);
                                }
                        //        ET1 = 1;               //開啟定時器1中斷    接收的時候不用定時器1;
                                PTex = &remotedata[0];
                                PTex1 = (unsigned short*)&remotedata[0];
                                data1 = (*PTex1);
                                TR0_Count(data1);           //9MS低電平
                                PTex1++;
                                data1 = (*PTex1);           //4.5MS高電平
                                TR0_Count1(data1);
                                PTex1++;
                                PTex = (uchar*)PTex1;
                                test0 = 0;

                                for(j=0;j<n_elements-4;j++)
                                {
                                        data1 = (*PTex);
                                        TR0_Count(data1);          //發信號
                                        PTex++;
                                        data1 = (*PTex);          
                                        TR0_Count1(data1);          //不發信號
                                        PTex++;
                                        test1 = 0;
                                        if(*PTex == 0)
                                        {
                                                Txd_Port = 1;
                                                test2 = 0;
                                        }
                                }
                                TR0_Count1(200);                                        //兩組數據之間50ms的時間間隔
                        }                                        */       
                        //key_down_flag = 0;               
                        IE0 = 0;                                                         //當按鍵還沒有按下的時候不能產生中斷                       
                }
                 else                                                                   //接受模塊
                 {
                        if (key_value == 0)
                        {
                                if(IR_First == 0)                  //每次紅外線到來時就開一次中斷
                                 {
                                        pArray = &remotedata[0];
                                        pArray1 = (unsigned short*)&remotedata[0];
                                        EX0 = 1;                         //開外中斷0;
                                        IR_First++;
                                }
                                if (key_down_flag == 0)
                                {
                                        key_down_flag = 1;
                                }                           
                            if (int_flag == 1)                                   // 有數據傳送
                            {       
                                        if (remotein == 0)                           //如果是低電平
                                        {
                                                if (last_in == 1)                  //等待它翻轉成高電平
                                                {                                 
                                                        if (up_down == 1)        //如果是第一次           4.5MS
                                                        {                 
                                                                *pArray1++ = count1;
                                                                 pArray = (unsigned char*)pArray1;
                                                                 count1 = 0;
                                                                 up_down++;
                                                        }
                                                        else
                                                    {       
                                                                *pArray++ = count1;          
                                                                count1 = 0;
                                                           }
                                                        last_in = 0;
                                                }
                                        }
                                        else
                                        {
                                                if (last_in == 0)
                                                {
                                                        // 9MS
                                                        if (up_down == 0)
                                                        {                
                                                                *pArray1++ = count1;
                                                                 //pArray = (unsigned char*)pArray1;
                                                                 count1 = 0;
                                                                 up_down++;
                                                        }
                                                        else
                                                        {       
                                                                *pArray++ = count1;
                                                                count1 = 0;
                                                        }
                                                        last_in = 1;
                                                }
                                    }
                            }
                        }
                         
                        if (key_value == 1)
                        {
                                if(IR_First == 0)
                                {
                                        int_flag = 0;                         //紅外線標志
                                        last_in = 0;                                         //高低電平翻轉標志
                                        up_down = 0;                                         //9ms,4.5ms判斷標志
                                        pArray = &remotedata[0];
                                        pArray1 = (unsigned short*)&remotedata[0];

                                        //TR0 = 0;                                                  //一次接收完成以后定時器關閉
                                        test1 = 0;
                                        //TR0 = 0;
                                        //TR1 = 0;
                                        EX0 = 1;  
                                        Time0_init();
                                          //Time1_init();
                                        IR_First ++;
                                }
                                if (key_down_flag == 0)
                                {
                                        key_down_flag = 2;
                                        test2 = 0;
                                }                                          
                                   if (int_flag == 1)                   // 有數據傳送
                                   {       
                                        if (remotein == 0)           //如果是低電平
                                        {
                                                if (last_in == 1)  //等待它翻轉成高電平
                                                {                                 
                                                        if (up_down == 1)        //如果是第一次           4.5MS
                                                        {                 
                                                                *pArray1++ = count1;
                                                                 pArray = (unsigned char*)pArray1;
                                                                 test3 = 0;
                                                                 count1 = 0;
                                                                 up_down++;
                                                        }
                                                        else
                                                    {       
                                                                *pArray++ = count1;          
                                                                count1 = 0;
                                                                test7 = 0;
                                                           }
                                                        last_in = 0;
                                                }
                                        }
                                        else
                                        {
                                                if (last_in == 0)
                                                {
                                                        // 9MS
                                                        if (up_down == 0)
                                                        {                
                                                                *pArray1++ = count1;
                                                                // pArray = (unsigned char*)pArray1;
                                                                 count1 = 0;
                                                                 up_down++;
                                                                 test5 = 0;
                                                        }
                                                        else
                                                        {       
                                                                *pArray++ = count1;
                                                                count1 = 0;
                                                                test6 = 0;
                                                        }
                                                        last_in = 1;
                                                }
                                    }
                            }
                        }
                }
        }                       
        return 0;
}

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 精品国产一区二区三区久久狼黑人 | 亚洲综合国产 | 国产精品久久久久久吹潮日韩动画 | 色天天综合 | 999久久 | 久久久久国产视频 | 午夜免费观看 | 伊人导航| 一区二区免费 | 免费精品一区 | 人人人干| 国产中文字幕亚洲 | 国产视频观看 | 国产欧美在线 | 丝袜一区二区三区 | 久久久久久综合 | 国产美女h视频 | 欧美寡妇偷汉性猛交 | 国产精品一区久久久 | 在线观看国产精品视频 | 男人的天堂在线视频 | 国产一级在线观看 | 欧美日韩电影免费观看 | 亚洲综合一区二区三区 | av中文字幕在线观看 | 在线精品一区二区三区 | 国产一区二区三区四区在线观看 | 天天操夜夜操免费视频 | 999www视频免费观看 | 91n成人 | 91中文字幕在线 | 欧美日韩高清在线一区 | 一级免费毛片 | 视频一区二区在线 | 久久人人爽人人爽人人片av免费 | 91麻豆产精品久久久久久夏晴子 | 国产精品美女久久久 | 久久宗合色 | 91欧美精品成人综合在线观看 | 99精品99 | 91久久久久 |