短波等幅电报是无线电玩家的挚爱,其抗干扰能力是无法替代的,使用小功率就能实现远距离通联。但是人工收发电报实在是太难,也太繁琐,也因此莫尔斯码已被主流应用淘汰。如果能用单片机实现自动收发电报,就能很方便的进行远距离通联了。看到有些资深网友反对电报自动化,不过如能用单片机实现自动收发报、自动加解密,相信莫尔斯码会更有实用价值,会焕发第二春。网上这样的程序很少,找了很久终于找到一个,保存到这里,希望对需要的人有帮助。
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
单片机源程序如下:
- #include <reg51.h>
- #include <intrins.h>
- void delay(unsigned char ms);
- void delay2(int i);
- void lcd_wcmd(unsigned char cmd);
- void lcd_pos(unsigned char pos);
- void lcd_wdat(unsigned char dat);
- void lcd_init();
- void xianshi();
- void KeyDown();
- void la_ba();
- sbit rs= P2^6;
- sbit rw = P2^5;
- sbit ep = P2^7;
- sbit d=P3^0;
- sbit d1=P3^1;
- sbit lb=P3^2;
- int b,c,s=0,q=0,w=0;
- #define GPIO_KEY P1
- unsigned char dis1[32];
- unsigned char dis2[9]={',','A','D','G','J','M','P','T','W'};
- unsigned char dis3[9]={'1','2','3','4','5','6','7','8','9'};
- unsigned int code laba[36][5]={
- 1,2,3,3,3,//A
- 2,1,1,1,3,//B
- 2,1,2,1,3,//C
- 2,1,1,3,3,//D
- 1,3,3,3,3,//E
- 1,1,2,1,3,//F
- 2,2,1,3,3,//G
- 1,1,1,1,3,//H
- 1,1,3,3,3,//I
- 1,2,2,2,3,//J
- 2,1,2,3,3,//K
- 1,2,1,1,3,//L
- 2,2,3,3,3,//M
- 2,1,3,3,3,//N
- 2,2,2,3,3,//0
- 1,2,2,1,3,//P
- 2,2,1,2,3,//Q
- 1,2,1,3,3,//R
- 1,1,1,3,3,//S
- 2,3,3,3,3,//T
- 1,1,2,3,3,//U
- 1,1,1,2,3,//V
- 1,2,2,3,3,//W
- 2,1,1,2,3,//X
- 2,1,2,2,3,//Y
- 2,2,1,1,3,//Z
- 2,2,2,2,2,//0
- 1,2,2,2,2,//1
- 1,1,2,2,2,//2
- 1,1,1,2,2,//3
- 1,1,1,1,2,//4
- 1,1,1,1,1,//5
- 2,1,1,1,1,//6
- 2,2,1,1,1,//7
- 2,2,2,1,1,//8
- 2,2,2,2,1,//9
- };
- void delay(unsigned char ms)
- {
- unsigned char i;
- while(ms--)
- {
- for(i = 0; i< 250; i++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- void delay2(int i)
- {
- while(i--);
- }
- bit lcd_bz()
- {
- bit result;
- rs = 0;
- rw = 1;
- ep = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- result = (bit)(P0 & 0x80);
- ep = 0;
- return result;
- }
- void lcd_wcmd(unsigned char cmd)
- {
- while(lcd_bz());//判断LCD是否忙碌
- rs = 0;
- rw = 0;
- ep = 0;
- _nop_();
- _nop_();
- P0 = cmd;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ep = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ep = 0;
- }
- void lcd_pos(unsigned char pos)
- {
- lcd_wcmd(pos | 0x80);
- }
- void lcd_wdat(unsigned char dat)
- {
- while(lcd_bz());//判断LCD是否忙碌
- rs = 1;
- rw = 0;
- ep = 0;
- P0 = dat;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ep = 1;
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- ep = 0;
- }
- void lcd_init()
- {
- lcd_wcmd(0x38);
- delay(1);
- lcd_wcmd(0x0c);
- delay(1);
- lcd_wcmd(0x06);
- delay(1);
- lcd_wcmd(0x01);
- delay(1);
- }
- void xianshi()
- {
- int i=0,j=1,n=0;
- while(dis1[i] != '\0')
- {
- lcd_pos(0x00);//设置显示位置
- while(j!=0&&dis1[i] != '\0')
- {
- lcd_wdat(dis1[i]);//显示字符
- i++;
- j=i%16;
- }
- lcd_pos(0x40);// 设置显示位置
- j=1;
- while(j!=0&&dis1[i] != '\0')
- {
- lcd_wdat(dis1[i]);// 显示字符
- i++;
- j=i%16;
- }
- j=1;
- if(dis1[i] != '\0')
- i-=16;
- }
- i=0;
- }
- void KeyDown()
- {
- int KeyValue=0;
- GPIO_KEY=0x0f;
- if(GPIO_KEY!=0x0f)
- {
- delay(5);
- if(GPIO_KEY!=0x0f)
- {
- GPIO_KEY=0X0F;
- switch(GPIO_KEY)
- {
- case(0X07): KeyValue=0;break;
- case(0X0b): KeyValue=1;break;
- case(0X0d): KeyValue=2;break;
- case(0X0e): KeyValue=12;break;
- }
- }
- GPIO_KEY=0XF0;
- switch(GPIO_KEY)
- {
- case(0X70): KeyValue=KeyValue;break;
- case(0Xb0): KeyValue=KeyValue+3;break;
- case(0Xd0): KeyValue=KeyValue+6;break;
- case(0Xe0): KeyValue=KeyValue+9;break;
- }
- while(GPIO_KEY!=0xf0);
- if(KeyValue!=c&&dis1[w]!='\0')
- {b=0;w++;}
-
- if(KeyValue<=8&&s==0)
- {
- if(c==12||c==15)w--;
- dis1[w]=dis2[KeyValue]+b;
- d=0;delay(25);d=1;delay(25);
- }
- else if(KeyValue<=8&&s==1)
- {
- if(c==12||c==15)w--;
- dis1[w]=dis3[KeyValue];
- d=0;delay(25);d=1;delay(25);
- }
- else if(KeyValue==12)
- {
- if(w>0)
- {
- w--;
- dis1[w]=' ';
- }
- else
- {
- dis1[w]=' ';
- }
- d1=0;delay(25);d1=1;delay(25);
- }
- else if(KeyValue==15)
- {
- while(w!=0)
- {
- w--;
- dis1[w]=' ';
- }
- }
- else if(KeyValue==9)
- {
- q++;
- s=q%2;
- if(c==12||c==15)w-=2;
- }
- else if(KeyValue==10)
- {
- if(s==0)
- dis1[w]=' ';
- else
- dis1[w]='0';
- }
- else if(KeyValue==11)
- {
- dis1[w]=' ';
- }
- else if(KeyValue==18)
- {
- dis1[w]=' ';
- w--;
- }
- else if(KeyValue==21)
- {
- la_ba();
- }
- b++;
- if(b==3)b=0;
- c=KeyValue;
- }
- }
- void la_ba()
- {
- int i,j,t;
- for(i=0;dis1[i]!='\0';i++)
- {
- if(dis1[i]>=65&&dis1[i]<=90)
- {
- d1=0;delay(25);d1=1;delay(25);
- for(j=0;laba[dis1[i]-65][j]!=3;j++)
- {
- if(laba[dis1[i]-65][j]==1)
- {
- t=100;
- while(t--)
- {
- lb=~lb;
- delay2(70);
- }
- delay(50);
- }
- if(laba[dis1[i]-65][j]==2)
- {
- t=300;
- while(t--)
- {
- lb=~lb;
- delay2(70);
- }
- delay(50);
- }
- if(laba[dis1[i]-65][j+1]==3)
- {
- delay(100);
- }
- }
- }
- if(dis1[i]>=48&&dis1[i]<=57)
- {
- d=0;delay(25);d=1;delay(25);
- for(j=0;j<5;j++)
- {
- if(laba[dis1[i]-22][j]==1)
- {
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
莫尔斯电码发生器.zip
(91.17 KB, 下载次数: 62)
|