|
昨天我在51論壇發(fā)布了基于89C51單片機摩爾斯電碼收發(fā)系統(tǒng)仿真,附完整代碼和仿真,還有視頻演示,帖子:http://www.torrancerestoration.com/bbs/dpj-213679-1.html 。由于接收部分沒有完善,所以主程序沒有上傳,現(xiàn)給予補上。
別看程序比較短,缺費了我好幾天時間編寫調(diào)試修改,所以請大家給予多多鼓勵,評論,以利我進一步提高。

單片機源程序如下:
- /*----------------------------------------------------------------
- * 【實驗平臺】: 89C51單片機開發(fā)板
- * 【外部晶振】: 11.0592mhz
- * 【主控芯片】: STC89C52
- * 【編譯環(huán)境】: Keil μVisio4
- * 【程序編寫】: wzqwxx 水上人家
- 名稱:摩爾斯電碼接收
- 內(nèi)容:僅供交流學(xué)習(xí),其他用途請注明編者,不保證功能正常
- 本程序僅實現(xiàn)了短電報自動接收功能
- 編制程序過程本身就很有趣和充滿挑戰(zhàn),如果能制作成品,
- 練習(xí)發(fā)報也十分有趣,這也是對古老的電訊一種紀(jì)念,致敬
- 充滿智慧的先輩們。
- 播發(fā)摩爾斯電碼的一般要求是:以一個“點”的長度為一個時間
- 單位,“劃”是三個點的時間長度;點劃之間的間隔是一個點的長度;
- 字符之間的間隔是三個點的長度;單詞之間的間隔是七個點的長度。
- 這樣才能被收報人識別。
- ------------------------------------------------------------------*/
- //MRSJS.c文件
- #include<regx52.h>
- //#include <stdio.h>
- #include "1602.h"
- #define L 33 //顯存數(shù)組元素個數(shù)
- sbit MRSIN = P3^3; //摩爾斯接口
- sbit beep = P2^3; //蜂鳴器接口
- unsigned char MRScode;//暫存接收碼值
- unsigned char MRStime_L = 0,MRStime_H = 0; //接收摩爾斯碼計數(shù)延時
- unsigned char idata i,strbuf[L];//顯示緩沖
-
- //摩爾斯碼字庫 A~Z 0~9共36個 ? , . ! @ : - 共7個,總共43個字節(jié)
- unsigned char code MRSZK[] = { 0x61,0X28,0X2a,0x44,0x80,0x22,
- 0x46,0x20,0x60,0x27,0x45,0x24,0x63,0x62,0x47,0x26,0x2d,0x42,
- 0x40,0x81,0x41,0x21,0x43,0x29,0x2b,0x2c,/*A~Z*/0xbf,0xaf,0xa7,0xa3,
- 0xa1,0xa0,0xb0,0xb8,0xbc,0xbe,/*0~9*/0xcc,0xf3,0xd5,0xeb,0xda,0xf8,0xe1};
- unsigned char code ASCIIZK[] = "?,.!@:-"; //符號庫,可擴展
- /*******************信號接收解碼*********************/
- void EX1MRS (void) interrupt 2 //外部中斷1服務(wù)函數(shù)
- {
- static unsigned char num,blag; //num為接收摩爾斯碼點劃的個數(shù)
- unsigned char j;
- /*******************處理低電平*********************/
- TR0 = 1; //啟動time0計數(shù)產(chǎn)生中斷
- if(blag == 1) //從第二個下降沿開始處理
- {
- //按點平均時長89ms,劃時長約270ms,空格約640ms計算的范圍
- if(MRStime_L > 2 && MRStime_L < 120 ) //處理點和劃
- {
- MRScode <<= 1; //發(fā)送端從高位開始的
- if(MRStime_L > 43 ) //點時長計數(shù)上限22,劃時長計數(shù)上限68
- {
- MRScode |= 0x01;
- Lcdwritechar(0,6+num,'_');
- }
- else
- {
- Lcdwritechar(0,6+num,'.');
- }
- num++;
- MRStime_L=0;
- /*******************處理高電平*********************/
- if(MRStime_H > 43 )//處理可見字符;字元之間時長計數(shù)是68
- {
- if(num<5 && num >0) //處理字母
- {
- num = (8-3-num) << 5; //得到字母前三位識別碼值
- for(j = 0; j <= 25;j++)//字母字庫地址0~25;
- {
- if( MRSZK[j] == (MRScode | num) )
- {
- strbuf[i] = j+0x41;
- i++;
- //printf("%bc",j+0x41) ;//發(fā)送到串口文本模式顯示
- break;
- }
- }
- num = 0;
- }
- else if(num>5) //處理符號
- {
- num = 0;
- for(j = 36; j <= 42;j++)//符號字庫地址36~42;
- {
- if((MRSZK[j]&0x3F) == MRScode ) //清零高兩位
- {
- strbuf[i] = ASCIIZK[j-36];
- i++;
- // printf("%bc",ASCIIZK[j-36]) ;//發(fā)送到串口顯示
- break;
- }
- }
- }
- else //處理數(shù)字
- {
- num = 0;
- for(j = 26; j <= 35;j++)//數(shù)字地址26~35;
- {
- if((MRSZK[j]&0x1F) == MRScode ) //清零高三位
- {
- strbuf[i] = j+0x16;
- i++;
- // printf("%bc",j+0x16) ;//發(fā)送到串口文本模式顯示
- break;
- }
- }
- }
- if(MRStime_H > 110) //處理空格;
- {
- strbuf[i] = ' ';
- i++;
- // printf(" ") ;
- }
- if(MRStime_H > 190) //結(jié)束處理;
- {
- // printf("\n") ;//這里有時執(zhí)行不到 ?
- blag = 0;
- TR0 = 0;
- }
- MRScode = 0;
- write_com(0x01);// 清屏
- Lcdwritestring(1,0,strbuf);//x行,Y列寫字符串
- num = 0;
- }
- MRStime_H=0;
- }
- }
- else
- {
- write_com(0x01);// 清屏
- for(i = 0; i < L ;i++){strbuf[i] = 0;}; //清空顯存
- i = 0;
- num = 0;
- blag = 1;
- MRStime_H = 0;
- MRStime_L = 0;
- }
- }
- void time0_MRS (void) interrupt 1 //STC89C52 4毫秒@11.0592MHz
- {
- TL0 = 0x9A; //設(shè)置定時初值 我這是按點平均時長90ms,劃時長270ms設(shè)置的
- TH0 = 0xF1; //設(shè)置定時初值 在接收人工發(fā)送的要設(shè)計智能調(diào)整適應(yīng)
- if(MRSIN)
- ++MRStime_H; //高電平延時計數(shù)
- if(!MRSIN)
- ++MRStime_L; //低電平延時計數(shù)
- if(MRStime_H > 250) //這是為接收最后一個字符自己產(chǎn)生一個下降沿觸發(fā)中斷
- {
- MRSIN = 1;
- MRSIN = 0;
- MRSIN = 1;
- }
- }
- //void UART_init()
- //{
- // TMOD |= 0x20; //T1工作模式2 8位自動重裝
- // TH1 = 0xfd;
- // TL1 = 0xfd; //比特率9600 時鐘頻率11.0592MHZ
- // TR1 = 1; //啟動T1定時器
- // SM0 = 0;
- // SM1 = 1; //串口工作方式1 10位異步
- // REN = 1; //串口允許接收
- // TI = 1;
- //}
- //
- void Timer0Init(void) //4毫秒@11.0592MHz
- {
- TMOD &= 0xF0; //設(shè)置定時器模式
- TMOD |= 0x01; //設(shè)置定時器模式
- TL0 = 0x9A; //設(shè)置定時初值
- TH0 = 0xF1; //設(shè)置定時初值
- TF0 = 0; //清除TF0標(biāo)志
- ET0 = 1;
- TR0 = 0; //定時器0開始設(shè)為0,由外中斷啟動計時
- }
- void EX1init(void)
- {
- IT1 = 1; //指定外部中斷0下降沿觸發(fā),INT0 (P3.2)
- EX1 = 1; //使能外部中斷
- PX1 = 1;
- EA = 1; //開總中斷
- }
- void main(void)
- {
- Timer0Init();//初始化定時器
- // UART_init(); //初始化串口
- EX1init(); //初始化外部中斷
- lcd_init();//初始化液晶屏
- while(1)//主循環(huán)
- {
- beep = MRSIN; //單手鍵發(fā)送功能
- }
- }
-
-
復(fù)制代碼
仿真截圖
接收源碼:
摩斯碼電報接收.zip
(38.24 KB, 下載次數(shù): 39)
2021-10-28 16:31 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|