找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 1803|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

MSP430單片機(jī)摩爾斯電碼自動(dòng)發(fā)報(bào)程序與Proteus仿真圖

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
關(guān)于“軟件設(shè)計(jì)周”的東西,雖然我是學(xué)計(jì)算機(jī)的,但是由于一些安排,跨界搞了兩周。做的很奇怪,一部分也是迎合驗(yàn)收要求。都用上單片機(jī)、LCD了,還在用摩爾斯電碼。而且我感覺(jué)整個(gè)實(shí)體機(jī)大概率跑不起來(lái),只能活在仿真里,這么一想就更魔幻了。。。
東西做的比較粗糙,但是還是發(fā)出來(lái)吧,哪怕是有人復(fù)制一下數(shù)組,也可以讓人家少寫個(gè)輔助的小程序。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


一共有32個(gè)按鍵,第一個(gè)是模式選擇鍵,有三種模式,同時(shí)控制三盞LED顯示模式
模式1中第二個(gè)鍵為傳統(tǒng)電鍵,就是諜報(bào)劇里經(jīng)�?匆�(jiàn)的那種
模式2中第二三個(gè)鍵構(gòu)成了雙槳自動(dòng)電鍵,按住就連續(xù)持續(xù)發(fā)點(diǎn)或者劃
模式3中后26個(gè)鍵是個(gè)英文字母,自動(dòng)發(fā)報(bào)
有一個(gè)卡了一整子的點(diǎn)是,我不理解,為啥MSP430搞矩陣鍵盤,只能是輸出低電平,拉低某一引腳,我不是學(xué)這個(gè)的,也沒(méi)深究。

示波器輸出兩種波形,一種是電報(bào)波,另一種是調(diào)制波,調(diào)制波的頻率就是系統(tǒng)的總“幀率”

D4是自動(dòng)發(fā)報(bào)提示,熄滅表示在自動(dòng)發(fā)報(bào),自動(dòng)發(fā)報(bào)序列里面有東西,是不響應(yīng)新發(fā)報(bào)請(qǐng)求的
D5是暫停提示,熄滅時(shí)表示暫停記錄

LCD顯示已經(jīng)保存的電報(bào),支持暫停保存,清空已有,自動(dòng)重發(fā)。
緩存32位的01串,實(shí)際上人的操作可能會(huì)有一點(diǎn)相位差,那么根據(jù)奈奎斯特采樣定律,采用兩倍采樣即可完成無(wú)損還原。所以程序內(nèi)部存儲(chǔ)為64位。理想來(lái)說(shuō),應(yīng)該用移位來(lái)處理的,實(shí)際上為了寫起來(lái)方便,用了64個(gè)int,大概率會(huì)影響時(shí)序什么的。
使用了若干計(jì)數(shù)器,每10個(gè)程序幀,記錄一次,每20個(gè)程序幀顯示一次,等等。

電碼的碼率是,額,玄學(xué),因?yàn)槲也欢胪獠恐袛嗍裁吹�,整個(gè)時(shí)序邏輯還是挺怪的。而且在仿真情況下,delay也不清楚究竟怎延遲,還要驅(qū)動(dòng)LCD�;蛟S將程序幀和外部的某個(gè)計(jì)時(shí)中斷綁定,可以一定程度上解決問(wèn)題,但我的單片機(jī)編程是現(xiàn)學(xué)現(xiàn)賣的,只要能過(guò)學(xué)校老師的驗(yàn)收就行,我是學(xué)信安的,有不足的地方就賣個(gè)萌混過(guò)去吧0v0。

單片機(jī)代碼如下,變量命名比較亂,ACM打多了改不過(guò)來(lái)了
  1. #include "io430.h"
  2. #define uint unsigned int
  3. uint kd;
  4. uint mode=0x01;
  5. uint rem=0;
  6. void delay(uint t)
  7. {
  8.   uint i;
  9.   while(t--)
  10.     for(i=40;i>0;i--);
  11. }
  12. void KEY_J(void)//矩陣鍵盤函數(shù)
  13. {
  14.   kd=0;
  15.   P1DIR=0xff;
  16.   P1OUT=0x00;//當(dāng)我定義0xff,意味著我就開(kāi)始了列掃描,從高位到底
  17.   P2DIR=0x00;
  18.   if((P2IN&0x0f)!=0x0f)//如果有變化,那應(yīng)該是有按鍵被按下
  19.   {
  20.     delay(10);//防抖
  21.     if((P2IN&0x0f)!=0x0f){
  22.       switch((P2IN&0x0f))//按照順序,被按下的引腳會(huì)變成低電平,依次來(lái)判斷哪一行被按下。
  23.       {
  24.         case 0x0e:kd=kd;break; //第一行得到的數(shù)就是第幾列
  25.         case 0x0d:kd=kd+8;break;//第二行得到的數(shù)就是第幾列加8
  26.         case 0x0b:kd=kd+16;break;
  27.         case 0x07:kd=kd+24;break;
  28.       }
  29.       P1DIR=0x00;
  30.       P2DIR=0x0f;
  31.       P2OUT=0x00;
  32.       switch(P1IN)//按照順序,被按下的引腳會(huì)變成低電平,依次來(lái)判斷哪一行被按下。
  33.       {
  34.         case 0xfe:kd=kd+1;break; //第一行得到的數(shù)就是第幾列
  35.         case 0xfd:kd=kd+2;break;//第二行得到的數(shù)就是第幾列加8
  36.         case 0xfb:kd=kd+3;break;
  37.         case 0xf7:kd=kd+4;break;
  38.         case 0xef:kd=kd+5;break;
  39.         case 0xdf:kd=kd+6;break;
  40.         case 0xbf:kd=kd+7;break;
  41.         case 0x7f:kd=kd+8;break;
  42.       }
  43.     }
  44.   }
  45.   return;
  46. }
  47. void cha_mod(){
  48.   mode=mode<<1;
  49.   if(mode==0x08)mode=0x01;
  50.   //P3OUT=mode;
  51.   P3OUT=P3OUT&(mode|0xf8);
  52.   P3OUT=P3OUT|(mode&0x07);
  53.   delay(5000);
  54. }
  55. uint pau=0;
  56. void cha_pau(){
  57.   pau=pau^1;
  58.   if(pau)
  59.     P3OUT=P3OUT|0x40;
  60.   else
  61.     P3OUT=P3OUT&0xbf;
  62.   delay(5000);
  63. }
  64. #define MYSET1 P3OUT|=0x08
  65. #define MYSET0 P3OUT&=0xf7
  66. uint UDP=0;
  67. void tiaozhi(){
  68.     UDP=UDP^1;
  69.     if((P3OUT&0x08)&&UDP)
  70.       P3OUT|=0x10;
  71.     else
  72.       P3OUT&=0xef;
  73. }
  74. uint plot=0,cnt_rec=0;
  75. uint rect=0;
  76. uint rec[64];
  77. void rec_ins(){
  78.   if(rect<64){
  79.     if(P3OUT&0x08)
  80.       rec[rect]=1;
  81.     else
  82.       rec[rect]=0;
  83.     rect++;
  84.   }else{
  85.     for(int i=0;i<63;i++)
  86.       rec[i]=rec[i+1];
  87.     if(P3OUT&0x08)
  88.       rec[63]=1;
  89.     else
  90.       rec[63]=0;
  91.   }
  92. }
  93. #define LCDIO     P4OUT
  94. #define LCD1602_RS_1  P5OUT|=1  
  95. #define LCD1602_RS_0  P5OUT&=~1
  96. #define LCD1602_RW_1  P5OUT|=2
  97. #define LCD1602_RW_0  P5OUT&=~2
  98. #define LCD1602_EN_1  P5OUT|=4
  99. #define LCD1602_EN_0  P5OUT&=~4
  100. void LCD_check_busy()
  101. {
  102.         P1DIR=0x00;
  103.         LCDIO=0xff;
  104.         LCD1602_RS_0;
  105.         LCD1602_RW_1;
  106.         LCD1602_EN_1;
  107.         while(P1IN&0x80);
  108.         LCD1602_EN_0;
  109.         P1OUT=0x00;
  110.         P1DIR=0xFF;
  111. }
  112. void LCD_write_command(unsigned char command)
  113. {
  114.         //LCD_check_busy();
  115.         LCD1602_RS_0;   
  116.         LCDIO=command;
  117.         LCD1602_EN_1;
  118.         //delayms(1);
  119.         LCD1602_EN_0;
  120.         delay(1);
  121. }
  122. void LCD_write_dat( unsigned char dat)
  123. {
  124.       //LCD_check_busy();
  125.       LCD1602_RS_1;
  126.       LCDIO=dat;
  127.       LCD1602_EN_1;
  128.       //delayms(1);
  129.       LCD1602_EN_0;
  130.       delay(1);
  131.       LCD1602_RS_0;
  132. }
  133. void LCD_set_xy( unsigned char x, unsigned char y )
  134. {
  135.   unsigned char address;
  136.   if (y == 1)
  137.     address = 0x80+x;
  138.   else if (y == 2)
  139.   {
  140.     address=0x80+0x40+x;
  141.   }
  142.   LCD_write_command(address);
  143. }
  144. void LCD_dsp_char( unsigned char x,unsigned char y, char dat)
  145. {
  146.   LCD_set_xy( x, y );
  147.   LCD_write_dat(dat);
  148. }
  149. void LCD_init(void)
  150. {
  151.       P4DIR=0xFF;
  152.       P4SEL=0;
  153.       P5DIR=0xFF;
  154.       P5SEL=0;
  155.       P5OUT=0x00;
  156.       P4OUT=0x00;
  157.       delay(200);   
  158.       LCD1602_RW_0;
  159.       LCD1602_EN_0;
  160.       //CLEARSCREEN;//clear screen
  161.       LCD_write_command(0x38);//set 8 bit data transmission mode
  162.       delay(10);
  163.       LCD_write_command(0x38);//set 8 bit data transmission mode
  164.       delay(10);
  165.       LCD_write_command(0x38);//set 8 bit data transmission mode
  166.       delay(10);
  167.       LCD_write_command(0x06);//open display (enable lcd display)
  168.       delay(10);
  169.       LCD_write_command(0x0C);//set lcd first display address
  170.       delay(10);
  171.       LCD_write_command(0x01);//clear screen
  172.       delay(10);
  173.       //LCD_write_command(0x80);//clear screen
  174.       //delayms(1);
  175. }
  176. void dis_set(uint pos,char ch){
  177.   if(pos<16)
  178.     LCD_dsp_char(pos,1,ch);
  179.   else
  180.     LCD_dsp_char(pos-16,2,ch);
  181. }
  182. void display(){
  183.   for(int i=0;i<rect;i+=2){
  184.     if(rec[i])
  185.       dis_set(i>>1,'=');
  186.     else
  187.       dis_set(i>>1,'.');
  188.   }
  189.   for(int i=rect;i<64;i+=2){
  190.       dis_set(i>>1,' ');
  191.   }
  192. }
  193. uint snd[30][16]={
  194. 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  195. 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
  196. 1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
  197. 1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,
  198. 1,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,
  199. 1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,
  200. 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  201. 1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,
  202. 1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,
  203. 1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,
  204. 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
  205. 1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,
  206. 1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,
  207. 1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,
  208. 1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
  209. 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
  210. 1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,
  211. 1,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,
  212. 1,1,1,0,1,1,1,0,1,0,1,1,1,0,0,0,
  213. 1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,
  214. 1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
  215. 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
  216. 1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
  217. 1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,
  218. 1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,
  219. 1,1,1,0,1,0,1,0,1,1,1,0,0,0,0,0,
  220. 1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,
  221. 1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,
  222. };
  223. uint siz[30]={2,4,6,10,12,8,2,10,10,8,4,14,10,10,8,6,12,12,14,8,6,4,8,10,10,12,14};
  224. uint luc[32];
  225. int bro;
  226. void ins(int tar){
  227.   P6OUT=0xff;
  228.   rem=siz[tar];
  229.   for(int i=0;i<siz[tar];i++){
  230.     luc[rem-i]=snd[tar][i];
  231.   }
  232.   MYSET1;
  233.   bro=0;
  234.   return;
  235. }
  236. void rep(){
  237.   P6OUT=0xff;
  238.   rem=rect>>1;;
  239.   for(int i=0;i<rem;i++){
  240.     luc[rem-i]=rec[i<<1];
  241.   }
  242.   MYSET1;
  243.   bro=0;
  244.   return;
  245. }
  246. void init(){
  247.   WDTCTL = WDTPW + WDTHOLD;
  248.   P3DIR=0xff;
  249.   P3OUT=0x01;
  250.   mode=0x01;
  251.   LCD_init();
  252.   return;
  253. }
  254. void sol1(){
  255.   if(kd==2)
  256.       MYSET1;
  257.   else
  258.       MYSET0;
  259.   return;
  260. }
  261. void sol2(){
  262.   if(kd==2)
  263.     ins(0);
  264.   if(kd==3)
  265.     ins(1);
  266. }
  267. void sol3(){
  268.   if(kd>=7)
  269.     ins(kd-5);
  270. }
  271. int main( void )
  272. {
  273.   init();
  274.   while(1){
  275.     KEY_J();
  276.     if(kd==0){delay(10);}
  277.     if(rem){
  278.       P3OUT|=0x20;
  279.       bro++;
  280.       if(bro>=20){
  281.         bro=0;
  282.         rem--;
  283.         if(luc[rem])
  284.           MYSET1;
  285.         else
  286.           MYSET0;
  287.       }
  288.     }else{  
  289.       if(kd==1){cha_mod();}
  290.       if(mode==0x01){sol1();}
  291.       if(mode==0x02){sol2();}
  292.       if(mode==0x04){sol3();}
  293.       if(rem==0)
  294.         P3OUT&=0xdf;
  295.       if(kd==4){cha_pau();}
  296.       if(kd==5){rect=0;}
  297.       if(kd==6){rep();}
  298.     }
  299.     P6DIR=0xff;
  300.     //P6OUT=rem;
  301.     cnt_rec++;
  302.     if(cnt_rec>=10){
  303.       cnt_rec=0;
  304.       if(pau==0)
  305.         rec_ins();
  306.     }
  307.     plot++;
  308.     if(plot>=20){
  309.       plot=0;
  310.       display();
  311.       delay(0);
  312.     }else{
  313.       delay(64);
  314.     }
  315.     tiaozhi();
  316.   };
  317. }
復(fù)制代碼

Keil代碼與Proteus仿真下載: 4 28.rar (406.39 KB, 下載次數(shù): 10)

評(píng)分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評(píng)分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表