痞酷網_PIGOO

 找回密碼
 立即註冊
!!! [系統偵測到廣告阻擋軟體] !!!

如果您覺得痞酷網對您有些許幫助,或者您認同痞酷網的理想,

那麼希望您將痞酷網設定為白名單.

並請在上論壇的時候,動動您的手指,用行動支持我們.

謝謝!
查看: 4145|回復: 20

拆板子運用之 GPS 時鐘以及相關經驗

  [複製鏈接]
發表於 2012-10-16 02:24:06 | 顯示全部樓層 |閱讀模式
本帖最後由 antlu 於 2012-10-16 02:28 AM 編輯

上次把 電子遊戲機的板子切下來之後就一直想要把它拿來使用,裡面用的是 MC14511和 ULN2003,卻發生了許多插曲!! 因為我買了兩片所以可以相互驗證問題的所在!! 首先 MC14511 是把 BCD轉成七段顯示,而以前的七段顯示使用查表法把各段用8BIT送出,而這次的板子裡面有兩個,所以直接把BCD送到 DATA PORT就可以了!! 不料16進位與10進位還需要作一些轉換,還有 第一片板子顯示的時候居然出了"怪"現象,正常計數亂顯示!! 搞的我信心大失,於是決定切另一片板子,(這又花了一些時間),之後印證了第一片板子的 MC14511可能出了問題,但是第二片板子亮度卻變的很弱!! 這幾天就是找時間買新的 MC14511(沒買到!!),後來把MC14511 重新"裝回去"居然又正常了!!(觀察中...) 還有發生的怪問題是 "時間不準","時間凍結","時間停頓" 的現象,時間不準 經過更換了一個(都是舊的) 32768 之後解決了,卻會 時間偶發凍結的現象後來更換了另一個 32768石英之後還把洞洞版的絕緣清除了一下,時間不再凍結了!! 但是電源拔掉之後時間好像會停頓,目前不知道原因!! 先前也在其他地方發生過(目前懷疑是 DS1302出問題!!) 最後!! 就是幫她找一個家作一個"殼",剛好之前在"大創39圓店"買了一個壓克力容器,非常適合就把它組裝起來... 另外一個板子也一併給裝箱!!

451a03 [800].JPG

451c01 [800].JPG

451c02 [800].JPG

451c03 [800].JPG

451d01 [800].JPG

451d02 [800].JPG

451d05 [800].JPG

451d06 [800].JPG

451b02 [800].JPG

451b03 [800].JPG

451b05 [800].JPG

電阻放在IC座下方
451b06 [800].JPG

451b07 [800].JPG


3.3V轉換
451b08 [800].JPG

451b09 [800].JPG


程式


/*-----------------------------------------------
  20121008 要改寫程式lcm改為14511 7段加上DS1302 作為 REALTIME CLOCK, 當 GPS信號為 A 時候 更新 DS1302裡面的資料,平常由 DS1302來計時,要校正的時候,只要把 GPS 供電,這時候GPS信號達到水準就可以.
  強迫校時 時間約 25分鐘讀取 gps 訊號 baud rate 4800 1010 發生 字段顯示異常!! 可能是硬體問題!! 層別是顯示板不良!!
------------------------------------------------*/

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
sbit SCK=P1^4;        //ds1302 時鐘       
sbit SDA=P1^5;               
sbit RST=P1^6;
sbit FCUPSW=P1^7;//強迫gps 更新ds1302時間LO動作
bit ReadTimeFlag;//定义读时间标志
bit SetFlag;     //更新时间标志位
bit rec;
unsigned char REV_DATA,Gok;//GPS_ST 存放 a v 狀態
unsigned char FCUDT;//強迫更新時間計時 15分
unsigned char CLCK[6];//GPS hr min sec store
unsigned char GPS_AV;//GPS 信號 A強  V弱
unsigned char YMD[6];//年月日存放
unsigned char dca,dcb,dcc,ms2,ms3;// time counter SEC MIN HR
unsigned char time_buf1[8];//空年月日时分秒周 extern
unsigned char TempData[12];
unsigned char Ds1302_Read_Byte(unsigned char addr) ;
unsigned char code Digi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//

//----------------************----------------------------
#define DataPort P0
#define ScanPort P2
//DS1302复位脚
#define RST_CLR        RST=0//电平置低
#define RST_SET        RST=1//电平置高
#define IO_CLR        SDA=0//电平置低
#define IO_SET        SDA=1//电平置高
#define IO_R        SDA  //电平读取
#define SCK_CLR        SCK=0//时钟信号
#define SCK_SET        SCK=1//电平置高
#define ds1302_sec_add                        0x80                //秒数据地址
#define ds1302_min_add                        0x82                //分数据地址
#define ds1302_hr_add                        0x84                //时数据地址
#define ds1302_date_add                        0x86                //日数据地址
#define ds1302_month_add                0x88                //月数据地址
#define ds1302_day_add                        0x8a                //星期数据地址
#define ds1302_year_add                        0x8c                //年数据地址
#define ds1302_control_add                0x8e                //控制数据地址
#define ds1302_charger_add                0x90                                          
#define ds1302_clkburst_add                0xbe
extern unsigned char time_buf[8] ;//空年月日时分秒周
void Ds1302_Write_Byte(unsigned char addr, unsigned char d);
void Ds1302_Write_Time(void) ;
void Ds1302_Read_Time(void)  ;
void Ds1302_Init(void);
void DelayMs(unsigned char t);
void Init_Timer0(void);//定时器初始化
void UART_Init(void);
void GPS_Write(void);//把 GPS 的時間寫入 DS1302
void Display(void);//MC14511 轉換 65536' 06 55 36
/*------------------------------------------------
              串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
    SCON  = 0x50;                        // SCON: 模式 1, 8-bit UART, 使能接收  
   TMOD |= 0x20;               // TMOD: timer 1, mode 2, 8-bit 重装----4800 only
   TH1   = 0xfa;               // TH1:  重装值 GPS 4800 波特率 晶振 11.0592MHz ---4800 only
   // T2CON = 0x34;  // timer2 parameter set ---38400 only
   // RCAP2H = 0xff; //set uart baud rate 38400---38400 only
   //RCAP2L = 0xf7;//  --------------------------38400 only
   // ET2 = 1;// enable timer2 overflow flag -----38400 only
   //TR2 = 1;// timer2 enable  ------------------38400 only            
   TR1   = 1;                  // TR1:  timer 1 打开 ------------------ ?4800 only                        
    EA    = 1;                  //打开总中断
    ES    = 1;                  //打开串口中断
}

/*------------------------------------------------
                    定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01;          //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响                     
//TH0=0x00;              //给定初值
//TL0=0x00;
EA=1;            //总中断打开
ET0=1;           //定时器中断打开
TR0=1;           //定时器开关打开
}
/*------------------------------------------------
                 定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
TH0=(65536-3010)/256;                  //重新赋值 3ms
TL0=(65536-3010)%256;  
   ms2++;// 3ms setflag
   Display();
   if(ms2>150)//150*3=450
    {
     ms2=0;
         ReadTimeFlag=1;
     ms3++;//----450ms-----------------
    }
   if(ms3>3)// .45*4=1.8s
     {
      ms3=0;
          dca++;//dca=1.8sec count
     }
   if(dca>34)//1min
         {       
      dcb++;
          dca=0;
          if(FCUPSW==0)//P1^1 sw lo動作
          {
            FCUDT++;//強迫更新時間 108sec
          }
         }
   if(dcb>59)//1hr
     {
      dcb=0;
      }
}



//GPS 部分

void UART_SER (void) interrupt 4 //來自GPS 程式
{
     if(RI)                        //判断是接收中断产生
     {
          RI=0;                      //标志位清零
          REV_DATA =SBUF;                 //读入缓冲区的值
      rec=1;
         }
   if(TI)  //如果是发送标志位,清零
     TI=0;
}


void CLCKFL(unsigned char CLCKCT)//填入6個時 分 秒資料
{
  unsigned char ct=0;
  rec=0;//必要的
   while(CLCKCT>ct)//儲存數量
   {
    while(rec==0);
        if(rec==1)
         {
          CLCK[ct]=REV_DATA-0x30;
      rec=0;
          ct++;
          }
        }
}

//0819 填入6個年月日資料
void YMDFL(unsigned char YMDCT)
{
  unsigned char yt=0;
  rec=0;//必要的
   while(YMDCT>yt)//儲存數量
   {
    while(rec==0);
        if(rec==1)
         {
          YMD[yt]=REV_DATA-0x30;
      rec=0;
          yt++;
          }
        }
}


//0819 跳過幾個逗號

void JPDM(unsigned char DM)
{
  rec=0;
  while(DM)//>dmt
   {
    while(rec==0);
//        if (rec==1)
         {
     if(REV_DATA == ',')
         {
         rec=0;
         DM--;//dmt++
         }
         }
   }
}


void GPS_Write(void)//把 GPS 的時間寫入 DS1302
    {
                time_buf1[3]=YMD[0]*10+YMD[1];//日
        time_buf1[2]=YMD[2]*10+YMD[3];// 月  
                time_buf1[1]=YMD[4]*10+YMD[5];//  年
        time_buf1[4]=CLCK[0]*10+CLCK[1];//HR
                time_buf1[5]=CLCK[2]*10+CLCK[3];// min
                time_buf1[6]=CLCK[4]*10+CLCK[5];// sec
        Ds1302_Write_Time();
    }






unsigned char  Get_Gps(void)//改寫 gps 讀取程式 把 Gok=GPRMC_K() 取消
{
unsigned char TT;
  if(rec==1)
    {
    if(REV_DATA == '$')
     {
      rec=0;
     }
         }
         else
         {
         return 0;
         }
         while(rec==0);
     if(REV_DATA == 'G')
                  {
          rec=0;
          }
         while(rec==0);      
     if(REV_DATA == 'P')           
                {
        rec=0;
        }
         while(rec==0);        
     if(REV_DATA == 'R')//一路比較下去全部要相同 "GPRMC,"           
                  {
          rec=0;
          }
                   else
          {
                 return 0;     
           }
                     while(rec==0);        
          if(REV_DATA == 'M')//一路比較下去全部要相同 "GPRMC,"   
           {      
                        rec=0;     
           }
                     while(rec==0);      
          if(REV_DATA == 'C')//一路比較下去全部要相同 "GPRMC,"           
                   {
                 rec=0;
            }
          while(rec==0);     
          if(REV_DATA == ',')//一路比較下去全部要相同 "GPRMC,"
                   {
             rec=0;
             }
                  else
                    {
              return 0;
            }

    CLCKFL(6);//取 時分秒

    JPDM(1);
        while(rec==0);
        {
    GPS_AV = REV_DATA;
        }
   
    JPDM(7);//跳過8個逗號
        YMDFL(6);//取 年月日

  TT=CLCK[0]*10+CLCK[1]+8;
  if(TT>23)
     TT-=24;
         CLCK[0]=TT/10;
         CLCK[1]=TT%10;

  return 1;
  
  }

/*
void DelayUs2x(unsigned char t)
{   
while(--t);
}

void DelayMs(unsigned char t)
{
     
while(t--)
{
     DelayUs2x(245);
         DelayUs2x(245);
}
}
*/

unsigned char time_buf[8] ;                         //空年月日时分秒周
/*------------------------------------------------
           向DS1302写入一字节数据
------------------------------------------------*/
void Ds1302_Write_Byte(unsigned char addr, unsigned char d)
{

        unsigned char i;
        RST_SET;       
       
        //写入目标地址:addr
        addr = addr & 0xFE;     //最低位置零
        for (i = 0; i < 8; i ++)
            {
                if (addr & 0x01)
                    {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                addr = addr >> 1;
                }
       
        //写入数据:d
        for (i = 0; i < 8; i ++)
           {
                if (d & 0x01)
                    {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                d = d >> 1;
                }
        RST_CLR;                                        //停止DS1302总线
}
/*------------------------------------------------
           从DS1302读出一字节数据
------------------------------------------------*/

unsigned char Ds1302_Read_Byte(unsigned char addr)
{

        unsigned char i;
        unsigned char temp;
        RST_SET;       

        //写入目标地址:addr
        addr = addr | 0x01;//最低位置高
        for (i = 0; i < 8; i ++)
            {
             
                if (addr & 0x01)
                   {
                        IO_SET;
                        }
                else
                    {
                        IO_CLR;
                        }
                SCK_SET;
                SCK_CLR;
                addr = addr >> 1;
                }
       
        //输出数据:temp
        for (i = 0; i < 8; i ++)
            {
                temp = temp >> 1;
                if (IO_R)
                   {
                        temp |= 0x80;
                        }
                else
                   {
                        temp &= 0x7F;
                        }
                SCK_SET;
                SCK_CLR;
                }
       
        RST_CLR;        //停止DS1302总线
        return temp;
}

/*------------------------------------------------
           向DS1302写入时钟数据
------------------------------------------------*/
void Ds1302_Write_Time(void)
{
     
    unsigned char i,tmp;
        for(i=0;i<8;i++)
            {                  //BCD处理
                tmp=time_buf1/10;
                time_buf=time_buf1%10;
                time_buf=time_buf+tmp*16;
            }
        Ds1302_Write_Byte(ds1302_control_add,0x00);                        //关闭写保护
        Ds1302_Write_Byte(ds1302_sec_add,0x80);                                //暂停
        //Ds1302_Write_Byte(ds1302_charger_add,0xa9);                        //涓流充电
        Ds1302_Write_Byte(ds1302_year_add,time_buf[1]);                //年
        Ds1302_Write_Byte(ds1302_month_add,time_buf[2]);        //月
        Ds1302_Write_Byte(ds1302_date_add,time_buf[3]);                //日
        Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);                //周
        Ds1302_Write_Byte(ds1302_hr_add,time_buf[4]);                //时
        Ds1302_Write_Byte(ds1302_min_add,time_buf[5]);                //分
        Ds1302_Write_Byte(ds1302_sec_add,time_buf[6]);                //秒
        Ds1302_Write_Byte(ds1302_day_add,time_buf[7]);                //周
        Ds1302_Write_Byte(ds1302_control_add,0x80);                        //打开写保护
}

/*------------------------------------------------
           从DS1302读出时钟数据
------------------------------------------------*/
void Ds1302_Read_Time(void)  
{
               unsigned char i,tmp;
        time_buf[1]=Ds1302_Read_Byte(ds1302_year_add);                //年
        time_buf[2]=Ds1302_Read_Byte(ds1302_month_add);                //月
        time_buf[3]=Ds1302_Read_Byte(ds1302_date_add);                //日
        time_buf[4]=Ds1302_Read_Byte(ds1302_hr_add);                //时
        time_buf[5]=Ds1302_Read_Byte(ds1302_min_add);                //分
        time_buf[6]=(Ds1302_Read_Byte(ds1302_sec_add))&0x7F;//秒
        time_buf[7]=Ds1302_Read_Byte(ds1302_day_add);                //周


        for(i=0;i<8;i++)
           {           //BCD处理
                tmp=time_buf/16;
                time_buf1=time_buf%16;
                time_buf1=time_buf1+tmp*10;
           }
}

/*------------------------------------------------
                DS1302初始化
------------------------------------------------*/
void Ds1302_Init(void)
{
       
        RST_CLR;                        //RST脚置低
        SCK_CLR;                        //SCK脚置低
    Ds1302_Write_Byte(ds1302_sec_add,0x00);                                 
}




void Normal_dsp(void)//正常顯示模式 放在主程式裡
{
          
    if(ReadTimeFlag==1) //定时读取ds1302 定时时间到 则标志位置1,处理过时间参数标志位清零
     {
     ReadTimeFlag=0;  //标志位清零
     Ds1302_Read_Time();//读取时间参数
     //for 14511 need add BCD transfer
TempData[0]=0x20;
TempData[1]=time_buf1[1]/10<<4|time_buf1[1]%10;//y               
TempData[2]=time_buf1[2]/10<<4|time_buf1[2]%10;//time_buf1[2]/10<<4|time_buf1[2]%10;
TempData[3]=time_buf1[3]/10<<4|time_buf1[3]%10;//time_buf1[3]/10<<4|time_buf1[3]%10; //m  //加入"-"
TempData[4]=time_buf1[4]/10<<4|time_buf1[4]%10;
TempData[5]=time_buf1[5]/10<<4|time_buf1[5]%10; //d
TempData[6]=time_buf1[6]/10<<4|time_buf1[6]%10;
   }       
}

void Display(void)//MC14511 轉換 65536' 06 55 36
{
unsigned char disi;
DataPort=TempData[disi]; //取位码 年 月 日 時 分 秒
ScanPort=Digi[disi]; //取显示数据,段码
disi ++;
if(7== disi)   //检测8位扫描完全结束
disi =0;
}



void main (void)
{
Init_Timer0();        //定时器0初始化
Ds1302_Init();        //ds1302初始化
UART_Init();          //串口初始化
Ds1302_Read_Time();   //首次读取时间
//if((time_buf1[2]+time_buf1[7])==0) //如果所有参数都为0,写入一个初始值
//   Ds1302_Write_Time();

while (1)         //主循环
  {     
           Gok= Get_Gps();//取GPS信號
       if(Gok==1)
        {
         
          if(GPS_AV=='A')
           {
            GPS_Write();
                        Gok=0;
           }
         }
        if(FCUDT==30)//此一動作為長久收不到4個衛星信號強迫寫入時間30min.
                {
         GPS_Write();
         FCUDT=0;
                }


            Normal_dsp();//一般正常的顯示
   }
}




評分

2

查看全部評分

發表於 2012-10-18 03:17:32 | 顯示全部樓層
金利害  
有個小問題,2012怎變成2014?
 樓主| 發表於 2012-10-18 15:00:49 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-18 03:17 AM static/image/common/back.gif
金利害  
有個小問題,2012怎變成2014?

哈哈哈!! 有照片有真相!! 我也不知道ㄟ !! 剛剛又看了一下 2012 ... 會不會"靈異現象",先前 因為14511問題困擾我好一陣子,一直沒買到 14511 只好用舊的把它 除錫 加IC座再放回去!! 會不會就這樣出問題!! 拍照十沒特別注意就這樣出現"未來時間"...難怪 有人建議作"回到未來"的時間顯示... 感謝提醒!!
發表於 2012-10-18 16:06:50 | 顯示全部樓層
MC14511跟CD4511是一樣的東西,可以互換使用,
CD4511應該比較好買.....
 樓主| 發表於 2012-10-18 19:58:05 | 顯示全部樓層
ysc 發表於 2012-10-18 04:06 PM static/image/common/back.gif
MC14511跟CD4511是一樣的東西,可以互換使用,
CD4511應該比較好買.....

YSC大:
  因為後來一直沒有異常,所以就將就用了!! 感謝提供相關訊息!!
發表於 2012-10-18 20:08:56 | 顯示全部樓層
個人是比較愛用 MC14543, LED 共陰共陽任君選擇,
還有 /LE 接腳可讓 data bus 共用.
發表於 2012-10-18 21:43:18 | 顯示全部樓層
antlu大,我覺得程式改一下,4511跟2003就可以省掉不到,也可以幫你節省成本及縮小電路板面積,
我再想ds1302也是不是可以省掉。多個焦電式紅外線感測電路也不錯,附近有人才顯示數字,
沒人就讓cpu及相關電路進入省電模式,畢竟這種一年365天的,也會吃掉不少電,尤其7段顯示是
很大顆吃12v特的那種。
 樓主| 發表於 2012-10-18 23:52:13 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-18 09:43 PM static/image/common/back.gif
antlu大,我覺得程式改一下,4511跟2003就可以省掉不到,也可以幫你節省成本及縮小電路板面積,
我再想ds13 ...

oldhan & 單晶片微電腦兩位大:
    感謝提出寶貴建議!!
   我這個時鐘主要是拆板(50圓)零件,我都是用萬用板對於焊線很花時間,所以利用拆板省力也練習自己的程式能力,家裡目前有 15個時鐘在跑!! 因為個人嗜好(看到就爽!!),現在想要把 紅外線遙控程式 瘦身改寫,因為先前是COPY 實驗版的程式,發現太佔RAM導致 無法把溫度顯示給併進去!!
  還有功力不足,所以有閃爍問題,要省4511 2003 也會比較困難!!
發表於 2012-10-20 11:30:38 | 顯示全部樓層
一般都把掃瞄程式寫進中斷裏,會閃的話再微調中斷的時間,調短即可。
 樓主| 發表於 2012-10-20 15:59:26 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-20 11:30 AM static/image/common/back.gif
一般都把掃瞄程式寫進中斷裏,會閃的話再微調中斷的時間,調短即可。

單晶片微電腦大:
   雖然 學習從模仿開始,但是離"創作"距離看來頗大的.... 最近為了把 紅外線接收的那一段COPY來的程式,瘦身,搞的灰頭土臉!!  因為他用了 irdata[33] 把RAM吃掉許多... 自己寫才發現 外部中断還搞不清楚,還有 時間的計算...
請問: 外部中断是中断一次就執行一次服務程式吧!! 那麼 第一次 引導波5ms ON/OFF 還OK 接下來的 560us/560us   560us/1960us 信號陸續來 32個 是不是也要執行32次中斷,..這樣對顯示 以及對GPS接收都會造成影響... 頭大了!!  這樣有"妙招"嗎?
發表於 2012-10-20 19:20:08 | 顯示全部樓層
紅外線接收可以寫在主程式裏,無起始信號就跳開,有起始信號才跳進執行,同時關閉所有中斷,
確定接收碼無誤,再執行GPS及DS1302的相關程式。執行完,有年月日時間數據後,再打開中斷顯示。
感覺這顆單晶片平常還很閒的。  
有說錯請包涵。
 樓主| 發表於 2012-10-21 00:22:17 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-20 07:20 PM static/image/common/back.gif
紅外線接收可以寫在主程式裏,無起始信號就跳開,有起始信號才跳進執行,同時關閉所有中斷,
確定接收碼無 ...

單晶片微電腦大:
      謝謝提供寶貴意見!! 寫程式和作文一般,要創意,要簡潔,也要天份!! 爲了興趣頭髮發白也甘願!!!
發表於 2012-10-21 00:49:24 | 顯示全部樓層
可以染黑n_006|
 樓主| 發表於 2012-10-21 13:25:26 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-21 12:49 AM static/image/common/back.gif
可以染黑

單晶片微電腦大:
   這一陣子改程式"老鼠抓龜,無從著手" 請問 http://goods.ruten.com.tw/item/show?21103242690820 這一套可以 用在C上面 模擬嗎? 我現在改程式 看不到 摸不到 只能用顯示的現象判斷可能問題... 還是您有其他模擬器可以建議的,我是初學者 很多專用術語也不太懂...
  記得之前 LEGION大有提到,只是找不到那一篇文章...
發表於 2012-10-21 14:12:11 | 顯示全部樓層
antlu大
沒想到你還在糾結在時鐘這塊區域里
那個模擬器也是能用的,不過是模擬mpc82g516的mcu
和stc差不多,也是1t的mcu,也是有內含AD
若沒什麼特殊用途時只要注意DELAY的問題,89C或89S系列也都是一樣的
模擬器只要稍作注意不同處,大概都沒什麼問題的,注意PIN31腳的接法就可以了
 樓主| 發表於 2012-10-21 16:40:01 | 顯示全部樓層
legion 發表於 2012-10-21 02:12 PM static/image/common/back.gif
antlu大
沒想到你還在糾結在時鐘這塊區域里
那個模擬器也是能用的,不過是模擬mpc82g516的mcu

LEGION大:
   感謝您發聲!! 我是因為要"轉型" 到紅外線遙控以及計頻的區域,最近想要把 遙控植入電扇,但是 原來的遙控程式多佔用了 33個RAM記憶空間,所以要改寫,只是中斷部分以及時間部分還很陌生,又摸不著!! 所以想用近接的工具,來減少摸索時間!! 就請您把以前那一篇再傳給我,感謝!!  
PS: 我要的是可以用在 8951 的C程式,可以看到目前機器停的位址以及變數的內容...
發表於 2012-10-21 19:52:37 | 顯示全部樓層
antlu 發表於 2012-10-21 01:25 PM static/image/common/back.gif
單晶片微電腦大:
   這一陣子改程式"老鼠抓龜,無從著手" 請問 http://goods.ruten.com.tw/item/show?2110 ...

還不至於 看不到 摸不到。副程式先測,都ok了,再結合成一個主程式,
很多軟體都看得到執行的過程,組語或c 都看得到才對。
寫程式有一定的的程序在,一步一步來。

發表於 2012-10-21 21:46:15 | 顯示全部樓層
antlu大
中斷的部份不管是觸發用或作為時間用,其實好好的把原理根底打好
算是蠻簡單的東西,並沒有想像中那麼難
現在模擬器很便宜,那個模擬器當時也順手買了一個,
和以前隨便就上萬的ice比起來,這個還真是便宜
這類的ice其實在硬體上還蠻方便的,
c也好組合語言也好,ice的目地就是讓你設個中斷或單步執行時
能看到現行電路及mcu實際的所有動作狀態
設好中斷點,就能看到包含int0-int2的狀態還有所有暫存和記憶體狀態
所以除了1T和12T之間的差異外,其他倒是沒有麼問題
 樓主| 發表於 2012-10-21 23:00:50 | 顯示全部樓層
legion 發表於 2012-10-21 09:46 PM static/image/common/back.gif
antlu大
中斷的部份不管是觸發用或作為時間用,其實好好的把原理根底打好
算是蠻簡單的東西,並沒有想像中那 ...

LEGION大:
   可否再次建議一下,上次你買的 模擬器的賣家資訊!!  感謝!!
 樓主| 發表於 2012-10-21 23:01:36 | 顯示全部樓層
單晶片微電腦 發表於 2012-10-21 07:52 PM static/image/common/back.gif
還不至於 看不到 摸不到。副程式先測,都ok了,再結合成一個主程式,
很多軟體都看得到執行的過程,組語 ...

單晶片微電腦 大:
   感謝建議!!
 樓主| 發表於 2012-10-22 00:43:40 | 顯示全部樓層
最後發現一些問題點 irtime 沒歸零!! 終於把 unsigned char irdata[33];去掉了!!

void EX0init(void)
{
IT0=1;//外部中斷0下降緣觸發 INT0(P3^2)遙控器的脈衝時間
EX0=1;
}

void EX0_isr(void) interrupt 0 //遙控器的脈衝處理
{
  static bit startflag;
  if(startflag==1)//脈衝出現之後
  {
   if(irtime<63&&irtime>=33)//引導碼長度要在 6.5~13.5之間
      {
           Q=0;//把計數歸零
       IRBYC=0;//位元歸零
           }       
        if(irtime>7)//假如是1 時間為2.2ms
         {
          TTemp|=0x80;//因為遙控脈衝從0bit先送7bit最後送出,所以時間長約2.2ms則為1,1.2ms為0
          }
        TTemp>>=1;//右移一位
        IRBYC++;
        if(IRBYC>=8)//右移8位
           {
       IRcord[Q]=TTemp;//把資料存入 IRcord[0~3]
           IRBYC=0;
           TTemp=0;
           Q++;//4個字
           }
         if(Q==4)
           {
            irok=1;//接收完成設定旗標
            Q=0;
                }
                irtime=0;//每收一個位元就把計數歸零
         }
         else
         {
      startflag=1;//第一次脈衝出現
          irtime=0;
         }
}

您需要登錄後才可以回帖 登錄 | 立即註冊

本版積分規則

關閉

站長小叮嚀上一條 /1 下一條

禁閉室|手機版|連繫我們|痞酷網電子技術論壇

GMT+8, 2024-5-5 12:45 AM , Processed in 0.119018 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

© 2001-2023 Discuz! Team.