找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2906|回复: 1
打印 上一主题 下一主题
收起左侧

原创:基于89C51单片机莫尔斯电码解码接收程序,附完整代码

  [复制链接]
跳转到指定楼层
楼主
  昨天我在51论坛发布了基于89C51单片机摩尔斯电码收发系统仿真,附完整代码和仿真,还有视频演示,帖子:http://www.51hei.com/bbs/dpj-213679-1.html  。由于接收部分没有完善,所以主程序没有上传,现给予补上。
  别看程序比较短,缺费了我好几天时间编写调试修改,所以请大家给予多多鼓励,评论,以利我进一步提高。



单片机源程序如下:
  1. /*----------------------------------------------------------------
  2. * 【实验平台】: 89C51单片机开发板
  3. * 【外部晶振】: 11.0592mhz        
  4. * 【主控芯片】: STC89C52
  5. * 【编译环境】: Keil μVisio4         
  6. * 【程序编写】: wzqwxx 水上人家

  7. 名称:摩尔斯电码接收

  8. 内容:仅供交流学习,其他用途请注明编者,不保证功能正常
  9.           本程序仅实现了短电报自动接收功能
  10.           编制程序过程本身就很有趣和充满挑战,如果能制作成品,
  11.           练习发报也十分有趣,这也是对古老的电讯一种纪念,致敬
  12.           充满智慧的先辈们。
  13.       播发摩尔斯电码的一般要求是:以一个“点”的长度为一个时间
  14.   单位,“划”是三个点的时间长度;点划之间的间隔是一个点的长度;
  15.   字符之间的间隔是三个点的长度;单词之间的间隔是七个点的长度。
  16.   这样才能被收报人识别。

  17. ------------------------------------------------------------------*/

  18. //MRSJS.c文件

  19. #include<regx52.h>   
  20. //#include <stdio.h>
  21. #include "1602.h"
  22. #define L 33 //显存数组元素个数

  23. sbit MRSIN = P3^3;  //摩尔斯接口
  24. sbit beep = P2^3;  //蜂鸣器接口
  25. unsigned char MRScode;//暂存接收码值
  26. unsigned char MRStime_L = 0,MRStime_H = 0; //接收摩尔斯码计数延时
  27. unsigned char idata i,strbuf[L];//显示缓冲

  28. //摩尔斯码字库 A~Z 0~9共36个  ? , . ! @ : -   共7个,总共43个字节
  29. unsigned char code MRSZK[] = { 0x61,0X28,0X2a,0x44,0x80,0x22,
  30.         0x46,0x20,0x60,0x27,0x45,0x24,0x63,0x62,0x47,0x26,0x2d,0x42,
  31.         0x40,0x81,0x41,0x21,0x43,0x29,0x2b,0x2c,/*A~Z*/0xbf,0xaf,0xa7,0xa3,
  32.         0xa1,0xa0,0xb0,0xb8,0xbc,0xbe,/*0~9*/0xcc,0xf3,0xd5,0xeb,0xda,0xf8,0xe1};

  33. unsigned char code ASCIIZK[] = "?,.!@:-"; //符号库,可扩展



  34. /*******************信号接收解码*********************/

  35. void EX1MRS (void) interrupt 2 //外部中断1服务函数
  36. {
  37.         static unsigned char  num,blag;       //num为接收摩尔斯码点划的个数
  38.         unsigned char  j;


  39. /*******************处理低电平*********************/
  40.         TR0 = 1;   //启动time0计数产生中断
  41.         if(blag == 1) //从第二个下降沿开始处理
  42.         {  
  43.                  //按点平均时长89ms,划时长约270ms,空格约640ms计算的范围
  44.                 if(MRStime_L > 2 && MRStime_L < 120 ) //处理点和划
  45.                 {
  46.                         MRScode <<= 1;          //发送端从高位开始的
  47.                          if(MRStime_L > 43 )        //点时长计数上限22,划时长计数上限68
  48.                         {
  49.                                 MRScode |= 0x01;
  50.                             Lcdwritechar(0,6+num,'_');
  51.                     }
  52.                         else
  53.                         {
  54.                                 Lcdwritechar(0,6+num,'.');
  55.                         }
  56.                         num++;
  57.                         MRStime_L=0;

  58. /*******************处理高电平*********************/
  59.                    if(MRStime_H > 43 )//处理可见字符;字元之间时长计数是68   
  60.                    {
  61.                                 if(num<5 && num >0)          //处理字母
  62.                                 {
  63.                                         num = (8-3-num) << 5;  //得到字母前三位识别码值
  64.                                          for(j = 0; j <= 25;j++)//字母字库地址0~25;
  65.                                         {
  66.                                                 if( MRSZK[j] == (MRScode | num) )
  67.                                                 {
  68.                                                         strbuf[i] = j+0x41;
  69.                                                         i++;
  70.                                                         //printf("%bc",j+0x41) ;//发送到串口文本模式显示                                       
  71.                                                         break;
  72.                                                 }
  73.                                         }
  74.                                         num = 0;                                                                        
  75.                                 }                        
  76.                                    else if(num>5)   //处理符号
  77.                                 {
  78.                                         num = 0;
  79.                                          for(j = 36; j <= 42;j++)//符号字库地址36~42;
  80.                                         {
  81.                                                 if((MRSZK[j]&0x3F) == MRScode )        //清零高两位
  82.                                                 {
  83.                                                         strbuf[i] = ASCIIZK[j-36];
  84.                                                         i++;
  85.                                                 //        printf("%bc",ASCIIZK[j-36]) ;//发送到串口显示                                       
  86.                                                         break;        
  87.                                                 }
  88.                                         }                        
  89.                                 }
  90.                                 else //处理数字
  91.                                 {
  92.                                         num = 0;        
  93.                                          for(j = 26; j <= 35;j++)//数字地址26~35;
  94.                                         {
  95.                                                 if((MRSZK[j]&0x1F) == MRScode )        //清零高三位
  96.                                                 {
  97.                                                         strbuf[i] = j+0x16;
  98.                                                         i++;
  99.                                                 //        printf("%bc",j+0x16) ;//发送到串口文本模式显示                                       
  100.                                                         break;        
  101.                                                 }
  102.                                         }
  103.                                 }
  104.                                 if(MRStime_H > 110)        //处理空格;
  105.                                 {
  106.                                         strbuf[i] = ' ';
  107.                                         i++;
  108.                                 //        printf(" ") ;
  109.                                 }

  110.                                 if(MRStime_H > 190)        //结束处理;
  111.                                 {
  112.                         //                printf("\n") ;//这里有时执行不到 ?        
  113.                                         blag = 0;
  114.                                         TR0 = 0;
  115.                                 }
  116.                                 MRScode = 0;
  117.                                 write_com(0x01);// 清屏
  118.                                 Lcdwritestring(1,0,strbuf);//x行,Y列写字符串
  119.                                 num = 0;
  120.                         }
  121.                         MRStime_H=0;
  122.                 }
  123.         }
  124.         else
  125.         {
  126.                 write_com(0x01);// 清屏
  127.                 for(i = 0; i < L ;i++){strbuf[i] = 0;};         //清空显存
  128.                 i = 0;
  129.                 num = 0;
  130.                  blag = 1;
  131.                 MRStime_H = 0;
  132.                 MRStime_L = 0;
  133.         }        
  134. }


  135. void time0_MRS (void) interrupt 1  //STC89C52 4毫秒@11.0592MHz
  136. {
  137.         TL0 = 0x9A;                //设置定时初值        我这是按点平均时长90ms,划时长270ms设置的
  138.         TH0 = 0xF1;                //设置定时初值        在接收人工发送的要设计智能调整适应
  139.         if(MRSIN)
  140.                 ++MRStime_H; //高电平延时计数
  141.         if(!MRSIN)
  142.                 ++MRStime_L; //低电平延时计数
  143.         if(MRStime_H > 250)        //这是为接收最后一个字符自己产生一个下降沿触发中断
  144.         {
  145.                 MRSIN = 1;
  146.                 MRSIN = 0;
  147.                 MRSIN = 1;                        
  148.         }
  149. }


  150. //void UART_init()
  151. //{
  152. //        TMOD |= 0x20;          //T1工作模式2  8位自动重装
  153. //        TH1 = 0xfd;
  154. //        TL1 = 0xfd;         //比特率9600   时钟频率11.0592MHZ
  155. //        TR1 = 1;                //启动T1定时器
  156. //        SM0 = 0;
  157. //        SM1 = 1;                 //串口工作方式1 10位异步
  158. //        REN = 1;                //串口允许接收
  159. //        TI = 1;
  160. //}
  161. //

  162. void Timer0Init(void)                //4毫秒@11.0592MHz
  163. {
  164.         TMOD &= 0xF0;                //设置定时器模式
  165.         TMOD |= 0x01;                //设置定时器模式
  166.         TL0 = 0x9A;                //设置定时初值
  167.         TH0 = 0xF1;                //设置定时初值
  168.         TF0 = 0;                //清除TF0标志
  169.         ET0 = 1;
  170.         TR0 = 0;                //定时器0开始设为0,由外中断启动计时
  171. }

  172. void EX1init(void)
  173. {
  174.         IT1 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
  175.         EX1 = 1;   //使能外部中断
  176.         PX1 = 1;
  177.         EA = 1;    //开总中断
  178. }



  179. void main(void)
  180. {
  181.         Timer0Init();//初始化定时器
  182. //        UART_init(); //初始化串口
  183.         EX1init(); //初始化外部中断
  184.         lcd_init();//初始化液晶屏
  185.         while(1)//主循环
  186.         {
  187.                 beep = MRSIN;  //单手键发送功能
  188.         }
  189. }
  190.   
  191.   

复制代码

仿真截图




接收源码:
摩斯码电报接收.zip (38.24 KB, 下载次数: 39)

评分

参与人数 1黑币 +60 收起 理由
admin + 60 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏7 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:965487 发表于 2021-10-29 21:47 | 只看该作者
O(∩_∩)O谢谢admin加分鼓励
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表