8051時鐘與串傳輸問題? |
答題得分者是:src
|
aaa65568
一般會員 ![]() ![]() 發表:3 回覆:5 積分:1 註冊:2007-08-05 發送簡訊給我 |
我用kiel c 寫出8051時鐘的程式(Timer 0 ),如果我要按鍵按下時將現在時間全部串列傳輸(Timer 1) 至另一個8051,那這兩個8051的程式要怎麼編寫呢?
我有附程式檔!! 編輯記錄
aaa65568 重新編輯於 2008-02-04 19:55:58, 註解 無‧
|
src
高階會員 ![]() ![]() ![]() ![]() 發表:1 回覆:94 積分:154 註冊:2005-08-23 發送簡訊給我 |
[code c#] //將TX(P3.1)接到另一顆8051的RX(P3.0) //程式部分修改如下 //char d[]="00:00:00";// 宣告顯示區陣列變數 //char c[]="2007/12/05";// 宣告顯示區陣列變數 //將顯示陣列變數傳到另一顆8051 bit TX_FLAG; //宣告串列傳輸允許旗標 char *Index; //宣告指標變數 main() /* 主程式 */ { IE=0x82; TMOD=0x01; // 啟用Timer 0 中斷 TH0=(56636-50000)/256; // 填入計時量 TL0=(56636-50000)%6; // 填入計時量 TR0=1; // 啟動Timer 0 SCON=0X50; //設定串列傳輸模式1及致能接收 ES=1; //串列中斷致能 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 TX_FLAG=1; //允許傳輸 InitialLCD(); /* 初始化LCD */ while(1) { transfer(); WriteIns(0x80); WriteString(10,c); /* 寫入字串MSG0至LCD中 */ WriteIns(0xc0); WriteString(8,d); /* 寫入字串MSG0至LCD中 */ if(scanner()==1) { AdjustTime(); } if(scanner()==2) { Index=c; //指標變數=年月日陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); //判斷是否傳輸完畢 TX_FLAG=0; SBUF=*Index ; } Index=d; //指標變數=十分秒陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); TX_FLAG=0; SBUF=*Index ; } } } } /* main */ void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ TI=0; /* 已傳送完畢,清除TI=0 */ TX_FLAG=1; //傳送完畢允許下次傳送 else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ } } /* SCON_int */ //接收端的程式 #include char d[]="00:00:00";// 宣告顯示區陣列變數 char c[]="2007/12/05";// 宣告顯示區陣列變數 bit RX_FLAG; //宣告串列接收完成旗標 bit First_Flag; bit Second_Flag; // char *Index; //宣告指標變數 main() /* 主程式 */ { IE=0x90; //致能中斷 SCON=0X50; //設定串列傳輸模式1及致能接收 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 while(1) { if(RX_FLAG==1) { RX_FLAG=0; /*在此處理收到的資料*/ } } } /* main */ void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ TI=0; /* 已傳送完畢,清除TI=0 */ else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ if(First_Flag==0) { First_Flag=1; Index=c; *Index =SBUF; } else { if(Second_Flag==0) { *Index =SBUF; if(Index==c 10) { Second_Flag=1; Index=d; } } else { *Index =SBUF; if(Index==d 8) { First_Flag=0; Second_Flag=0; RX_FLAG=1; } } } } } /* SCON_int */ ===================引 用 aaa65568 文 章=================== 我用kiel c 寫出8051時鐘的程式(Timer 0 ),如果我要按鍵按下時將現在時間全部串列傳輸(Timer 1) 至另一個8051,那這兩個8051的程式要怎麼編寫呢? 我有附程式檔!!
編輯記錄
src 重新編輯於 2008-02-01 23:11:56, 註解 無‧
|
aaa65568
一般會員 ![]() ![]() 發表:3 回覆:5 積分:1 註冊:2007-08-05 發送簡訊給我 |
===================引 用 src 文 章=================== 不好意思.....我想請問一下: (1)在接收程式中的First_Flag與Second_Flag這兩個位元所代表的意義是什麼? (2)接收中有寫到/*在此處理收到的資料*/;是指可以處理我接收到的時間嗎? (3)還有我看不太懂接收的中斷副程式,可以幫我解說一下嗎? (4)因為我不太了解串列傳輸,如果可以的話,可以幫我說明串列傳輸的傳輸方式嗎? 謝謝!! --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- [code c#] //將TX(P3.1)接到另一顆8051的RX(P3.0) //程式部分修改如下 //char d[]="00:00:00";// 宣告顯示區陣列變數 //char c[]="2007/12/05";// 宣告顯示區陣列變數 //將顯示陣列變數傳到另一顆8051 bit TX_FLAG; //宣告串列傳輸允許旗標 char *Index; //宣告指標變數 main() /* 主程式 */ { IE=0x82; TMOD=0x01; // 啟用Timer 0 中斷 TH0=(56636-50000)/256; // 填入計時量 TL0=(56636-50000)%6; // 填入計時量 TR0=1; // 啟動Timer 0 SCON=0X50; //設定串列傳輸模式1及致能接收 ES=1; //串列中斷致能 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 TX_FLAG=1; //允許傳輸 InitialLCD(); /* 初始化LCD */ while(1) { transfer(); WriteIns(0x80); WriteString(10,c); /* 寫入字串MSG0至LCD中 */ WriteIns(0xc0); WriteString(8,d); /* 寫入字串MSG0至LCD中 */ if(scanner()==1) { AdjustTime(); } if(scanner()==2) { Index=c; //指標變數=年月日陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); //判斷是否傳輸完畢 TX_FLAG=0; SBUF=*Index ; } Index=d; //指標變數=十分秒陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); TX_FLAG=0; SBUF=*Index ; } } } } /* main */ void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ TI=0; /* 已傳送完畢,清除TI=0 */ TX_FLAG=1; //傳送完畢允許下次傳送 else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ } } /* SCON_int */ //接收端的程式 #include char d[]="00:00:00";// 宣告顯示區陣列變數 char c[]="2007/12/05";// 宣告顯示區陣列變數 bit RX_FLAG; //宣告串列接收完成旗標 bit First_Flag; bit Second_Flag; // char *Index; //宣告指標變數 main() /* 主程式 */ { IE=0x90; //致能中斷 SCON=0X50; //設定串列傳輸模式1及致能接收 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 while(1) { if(RX_FLAG==1) { RX_FLAG=0; /*在此處理收到的資料*/ } } } /* main */ void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ TI=0; /* 已傳送完畢,清除TI=0 */ else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ if(First_Flag==0) { First_Flag=1; Index=c; *Index =SBUF; } else { if(Second_Flag==0) { *Index =SBUF; if(Index==c 10) { Second_Flag=1; Index=d; } } else { *Index =SBUF; if(Index==d 8) { First_Flag=0; Second_Flag=0; RX_FLAG=1; } } } } } /* SCON_int */ [/code] ===================引 用 aaa65568 文 章=================== 我用kiel c 寫出8051時鐘的程式(Timer 0 ),如果我要按鍵按下時將現在時間全部串列傳輸(Timer 1) 至另一個8051,那這兩個8051的程式要怎麼編寫呢? 我有附程式檔!! |
src
高階會員 ![]() ![]() ![]() ![]() 發表:1 回覆:94 積分:154 註冊:2005-08-23 發送簡訊給我 |
[code c#] First_Flag表示串列傳輸收到第一個字,接下來要收年月日字串, 年月日字串加冒號:共10個字,當Index=c 10表示年月日字串已收完,這時Second_Flag=1準備收時分秒字串, 字串都收完畢後RX_FLAG=1。 以下是主程式中判斷RX_FLAG=1時,"處理收到的資料"就是去讀收到字串做顯示。 if(RX_FLAG==1) { RX_FLAG=0; /*在此處理收到的資料*/ } 中斷串列傳輸要設定傳輸模式傳輸速率及中斷致能,接下來只要做 傳送:SBUF=傳送的內容。傳送時要等前一次傳送完畢才能傳送下一個,所以要判斷TX_FLAG=1才能執行,如下: while(TX_FLAG!=1); TX_FLAG=0; SBUF=*Index ; 接收:接收的內容=SBUF。 [/code] |
aaa65568
一般會員 ![]() ![]() 發表:3 回覆:5 積分:1 註冊:2007-08-05 發送簡訊給我 |
傳送端 #include sbit RS=P2^0 ; sbit RW=P2^1 ; sbit Enable=P2^2; void InitialLCD(void); void WriteIns(char); void WriteData(char); void WriteString(char,char *); void CheckBusy(void); void KeyScan(void); char SCANDATA=0; char kcode=11; char d[]="00:00:00";// 宣告顯示區陣列變數 char c[]="2007/12/05";// 宣告顯示區陣列變數 char hour=0; // 宣告變數 char minute=0; // 宣告變數 char second=0; // 宣告變數 int year=2007; // 宣告變數 char month=12; // 宣告變數 char day=5;// 宣告變數 char count=0; //////////////////////////////////////////////////// void Delay(int) ; void transfer(void); unsigned char scanner(void) ; void debouncer(void); // 宣告防彈跳函數 #define rowkey() (~P0)&0x0f //讀入P0低4位元(列按鍵值)巨集 void AdjustTime(void); char disp=0x3f; bit TX_FLAG; //宣告串列傳輸允許旗標 char *Index; //宣告指標變數 main() /* 主程式 */ { IE=0x92; TMOD=0x01; // 啟用Timer 0 中斷 TH0=(56636-50000)/256; // 填入計時量 TL0=(56636-50000)%6; // 填入計時量 TR0=1; // 啟動Timer 0 SCON=0X50; //設定串列傳輸模式1及致能接收 ES=1; //串列中斷致能 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 TX_FLAG=1; //允許傳輸 InitialLCD(); /* 初始化LCD */ while(1) { transfer(); WriteIns(0x80); WriteString(10,c); /* 寫入字串MSG0至LCD中 */ WriteIns(0xc0); WriteString(8,d); /* 寫入字串MSG0至LCD中 */ if(scanner()==1) { AdjustTime(); } if(scanner()==2) { Index=c; //指標變數=年月日陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); //判斷是否傳輸完畢 TX_FLAG=0; SBUF=*Index ; } Index=d; //指標變數=十分秒陣列變數起始位址 while(*Index!=0) { while(TX_FLAG!=1); TX_FLAG=0; SBUF=*Index ; } } } } /* main */ void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ { TI=0; /* 已傳送完畢,清除TI=0 */ TX_FLAG=1; //傳送完畢允許下次傳送 } else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ } } /* SCON_int */ void AdjustTime(void) { int input; while(1) { input=scanner(); if (input==10) { return; } else if(input==8) { while((input=scanner())!=0) { if (input==10) { return; } //上下調整時間或日期 else if (input==2) { year ; } else if (input==3) { year--; } transfer(); WriteIns(0x80); WriteString(10,c); } } else if(input==7) { while((input=scanner())!=0) { if (input==10) { return; } //上下調整時間或日期 else if (input==2) { month ; } else if (input==3) { month--; } if(month>12 || month<2) { month=1; } transfer(); WriteIns(0x80); WriteString(10,c); } } else if(input==6) { while((input=scanner())!=0) { if (input==10) { return; } //上下調整時間或日期 else if (input==2) { day ; } else if (input==3) { day--; } if ((day>30 || day<2 ) && ( month==4 || month==6 || month==9 ||month==11)) { day=1; } else if((day>31 || day<2 ) && (month==1 || month==2 || month==5 || month==7 || month==8 || month==10 || month==12)) { day=1; } else if((day>28 || day<2) && month==2) { day=1; } transfer(); WriteIns(0x80); WriteString(10,c); } } else if(input==5) { while((input=scanner())!=0) { if (input==10) { return; } //上下調整時間或日期 else if (input==2) { hour ; } else if (input==3) { hour--; } if(hour>23 || hour<1) { hour=0; } transfer(); WriteIns(0xc0); WriteString(8,d); } } else if(input==4) { while((input=scanner())!=0) { if (input==10) { return; } //上下調整時間或日期 else if (input==2) { minute ; } else if (input==3) { minute--; } if(minute>59 || minute<1) { minute=0; } transfer(); WriteIns(0xc0); WriteString(8,d); } } } } void transfer(void) { d[0]=hour/10 0x30; // 時數之十位數顯示資料 d[1]=hour 0x30; // 時數之個位數顯示資料 d[3]=minute/10 0x30; // 分數之十位數顯示資料 d[4]=minute 0x30; // 分數之個位數顯示資料 d[6]=second/10 0x30; // 秒數之十位數顯示資料 d[7]=second 0x30; // 秒數之個位數顯示資料 c[0]=year/1000 0x30; c[1]=((year00)/100) 0x30; c[2]=(((year00)0)/10) 0x30; c[3]=(((year00)0)) 0x30; c[5]=month/10 0x30; c[6]=month 0x30; c[8]=day/10 0x30; c[9]=day 0x30; } ///////////////////////////////////////////////////////////////////////////////////////LCD顯示 void InitialLCD(void) /* 清除LCD螢幕 */ { WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x08); /* 關閉顯示幕 */ WriteIns(0x01); /* 清除LCD螢幕 */ WriteIns(0x0e); /* 開啟顯示幕 */ WriteIns(0x06); /* 輸入模式設定 */ } /* InitialLCD */ void WriteIns(char instruction) /* 寫命令至LCD中 */ { RS=0; /* 選擇指令暫存器 */ RW=0; /* 寫入 */ Enable=1; /* 致能LCD */ P1=instruction; /* 輸出命令至LCD中 */ Enable=0; /* 除能LCD */ CheckBusy(); /* 檢查LCD忙碌旗標 */ } /* WriteIns */ void WriteData(char i) /* 寫資料至LCD中 */ { RS=1; /* 選擇資料暫存器 */ RW=0; /* 寫入 */ Enable=1; /* 致能LCD */ P1=i; /* 輸出資料至LCD中 */ Enable=0; /* 除能LCD */ CheckBusy(); /* 檢查LCD忙碌旗標 */ } /* WriteData */ void WriteString(count,MSG) /* 寫字串至LCD中 */ char count; /* 字串長度 */ char MSG[]; /* 字串資料 */ { char i; /* 定義位元組變數 */ for(i=0;i WriteData(MSG[i]); /* 寫入1個位元組的資料至LCD中 */ } /* WriteString */ void CheckBusy(void) { char i=0x80; /* 檢查忙碌旗標 */ while(i&0x80) /* 忙碌旗標BF=1? */ { RS=0; /* 選擇指令暫存器 */ RW=1; /* 讀取 */ Enable=1; /* 致能LCD */ i=P1; /* 讀取LCD指令暫存器內的資料 */ Enable=0; /* 除能LCD */ Delay(500); /* 延遲10ms */ } } /* CheckBusy */ ///////////////////////////////////////////////////////////////////////////////////////4x3鍵盤 void debouncer(void) // 防彈跳函數開始 { int i; // 宣告整數變數i for(i=0;i<4800;i ); // 計數4800次,延遲約40ms } unsigned char scanner(void) { char col,row; char scan,keyin; scan=0xef; // 掃瞄信號初值=1110 1111 for(col=0;col<3;col ) { P0=scan; keyin=rowkey(); // 讀入P1低4位元(第col行之列按鍵值) if(keyin != 0) // 若有按鍵時 { for(row=0;row<4;row ) // 掃瞄第row列是否按下 { if(keyin == (0x01< { kcode=row 4*col; // 計算出按鍵碼為 break; // 離開第row列掃瞄(for迴圈) } } while(rowkey() !=0 ); debouncer(); // 防彈跳函數 return(kcode); } scan=(scan<<1)|0x01; } } void Delay(int count) //延時副程式 { int j; for (j=0; j } void clock(void) interrupt 1 // T0 中斷副程式 { TH0=(56636-50000)/256; // 填入計時量 TL0=(56636-50000)%6; // 填入計時量 while ( count==20) // 中斷次數是否達到20 次 { count=0; // 重新計次 second ; // 秒數加1 if (second>=60) // 是否達到60 秒 { second=0; // 秒數歸零 minute ; // 分數加1 } if (minute>=60) // 是否達到60 分 { minute=0; // 分數歸零 hour ; // 時數加1 } if (hour>=24) // 是否達到13 小時 { day ; hour=0; // 時數歸零 } // 切換上下午 if (day>30 && (month==2 || month==4 || month==6 || month==9 ||month==11)) // 是否達到13 小時 { month ; day=0; // 時數歸零 } if (day>31 && (month==1 || month==2 || month==5 || month==7 || month==8 || month==10 || month==12)) // 是否達到13 小時 { month ; day=0; // 時數歸零 } if (month>12) // 是否達到13 小時 { year ; month=0; // 時數歸零 } // 切換上下午 } } -------------------------------------------------------------------------------------------------------------------------------------------------- 接收端 #include sbit RS=P2^0 ; sbit RW=P2^1 ; sbit Enable=P2^2; void InitialLCD(void); void WriteIns(char); void WriteData(char); void WriteString(char,char *); void CheckBusy(void); void Delay(int count); //延時副程式 char d[]="01:01:00";// 宣告顯示區陣列變數 char c[]="2000/01/01";// 宣告顯示區陣列變數 bit RX_FLAG; //宣告串列接收完成旗標 bit First_Flag; bit Second_Flag; // char *Index; //宣告指標變數 //////////////////////////////////////////////////// main() /* 主程式 */ { IE=0x90; //致能中斷 SCON=0X50; //設定串列傳輸模式1及致能接收 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 InitialLCD(); WriteIns(0x80); WriteString(10,c); /* 寫入字串MSG0至LCD中 */ WriteIns(0xc0); WriteString(8,d); while(1) { if(RX_FLAG==1) { RX_FLAG=0; /*在此處理收到的資料*/ WriteIns(0x80); WriteString(10,c); /* 寫入字串MSG0至LCD中 */ WriteIns(0xc0); WriteString(8,d); /* 寫入字串MSG0至LCD中 */ } } } void InitialLCD(void) /* 清除LCD螢幕 */ { WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x38); /* 功能設定 */ WriteIns(0x08); /* 關閉顯示幕 */ WriteIns(0x01); /* 清除LCD螢幕 */ WriteIns(0x0e); /* 開啟顯示幕 */ WriteIns(0x06); /* 輸入模式設定 */ } /* InitialLCD */ void WriteIns(char instruction) /* 寫命令至LCD中 */ { RS=0; /* 選擇指令暫存器 */ RW=0; /* 寫入 */ Enable=1; /* 致能LCD */ P1=instruction; /* 輸出命令至LCD中 */ Enable=0; /* 除能LCD */ CheckBusy(); /* 檢查LCD忙碌旗標 */ } /* WriteIns */ void WriteData(char i) /* 寫資料至LCD中 */ { RS=1; /* 選擇資料暫存器 */ RW=0; /* 寫入 */ Enable=1; /* 致能LCD */ P1=i; /* 輸出資料至LCD中 */ Enable=0; /* 除能LCD */ CheckBusy(); /* 檢查LCD忙碌旗標 */ } /* WriteData */ void WriteString(count,MSG) /* 寫字串至LCD中 */ char count; /* 字串長度 */ char MSG[]; /* 字串資料 */ { char i; /* 定義位元組變數 */ for(i=0;i WriteData(MSG[i]); /* 寫入1個位元組的資料至LCD中 */ } /* WriteString */ void CheckBusy(void) { char i=0x80; /* 檢查忙碌旗標 */ while(i&0x80) /* 忙碌旗標BF=1? */ { RS=0; /* 選擇指令暫存器 */ RW=1; /* 讀取 */ Enable=1; /* 致能LCD */ i=P1; /* 讀取LCD指令暫存器內的資料 */ Enable=0; /* 除能LCD */ Delay(500); /* 延遲10ms */ } } /* CheckBusy */ void Delay(int count) //延時副程式 { int j; for (j=0; j } void SCON_int(void) interrupt 4 /* 串列埠中斷函數 */ { if(TI==1) /* TI=1 */ TI=0; /* 已傳送完畢,清除TI=0 */ else /* RI=1 */ { RI=0; /* 已接收到資料,清除RI=0 */ if(First_Flag==0) { First_Flag=1; Index=c; *Index =SBUF; } else { if(Second_Flag==0) { *Index =SBUF; if(Index==c 10) { Second_Flag=1; Index=d; } } else { *Index =SBUF; if(Index==d 8) { First_Flag=0; Second_Flag=0; RX_FLAG=1; } } } } } /* SCON_int */
|
src
高階會員 ![]() ![]() ![]() ![]() 發表:1 回覆:94 積分:154 註冊:2005-08-23 發送簡訊給我 |
紅色部分修改後再試試
傳送端 main() /* 主程式 */ { IE=0x92; TMOD=0x21; // Timer 0 MODE1 , Timer 1 MODE2 TH0=(56636-50000)/256; // 填入計時量 TL0=(56636-50000)%6; // 填入計時量 TR0=1; // 啟動Timer 0 SCON=0X50; //設定串列傳輸模式1及致能接收 ES=1; //串列中斷致能 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 TX_FLAG=1; //允許傳輸 接收端 main() /* 主程式 */ { IE=0x90; //致能中斷 TMOD=0x20; // Timer 1 MODE2 SCON=0X50; //設定串列傳輸模式1及致能接收 TH1=0XFD; //設定傳輸速率9600/S TR1=1; //啟動TIMER1 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |