關于“軟件設計周”的東西,雖然我是學計算機的,但是由于一些安排,跨界搞了兩周。做的很奇怪,一部分也是迎合驗收要求。都用上單片機、LCD了,還在用摩爾斯電碼。而且我感覺整個實體機大概率跑不起來,只能活在仿真里,這么一想就更魔幻了。。。
東西做的比較粗糙,但是還是發出來吧,哪怕是有人復制一下數組,也可以讓人家少寫個輔助的小程序。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
一共有32個按鍵,第一個是模式選擇鍵,有三種模式,同時控制三盞LED顯示模式
模式1中第二個鍵為傳統電鍵,就是諜報劇里經常看見的那種
模式2中第二三個鍵構成了雙槳自動電鍵,按住就連續持續發點或者劃
模式3中后26個鍵是個英文字母,自動發報
有一個卡了一整子的點是,我不理解,為啥MSP430搞矩陣鍵盤,只能是輸出低電平,拉低某一引腳,我不是學這個的,也沒深究。
示波器輸出兩種波形,一種是電報波,另一種是調制波,調制波的頻率就是系統的總“幀率”
D4是自動發報提示,熄滅表示在自動發報,自動發報序列里面有東西,是不響應新發報請求的
D5是暫停提示,熄滅時表示暫停記錄
LCD顯示已經保存的電報,支持暫停保存,清空已有,自動重發。
緩存32位的01串,實際上人的操作可能會有一點相位差,那么根據奈奎斯特采樣定律,采用兩倍采樣即可完成無損還原。所以程序內部存儲為64位。理想來說,應該用移位來處理的,實際上為了寫起來方便,用了64個int,大概率會影響時序什么的。
使用了若干計數器,每10個程序幀,記錄一次,每20個程序幀顯示一次,等等。
電碼的碼率是,額,玄學,因為我不懂引入外部中斷什么的,整個時序邏輯還是挺怪的。而且在仿真情況下,delay也不清楚究竟怎延遲,還要驅動LCD。或許將程序幀和外部的某個計時中斷綁定,可以一定程度上解決問題,但我的單片機編程是現學現賣的,只要能過學校老師的驗收就行,我是學信安的,有不足的地方就賣個萌混過去吧0v0。
單片機代碼如下,變量命名比較亂,ACM打多了改不過來了- #include "io430.h"
- #define uint unsigned int
- uint kd;
- uint mode=0x01;
- uint rem=0;
- void delay(uint t)
- {
- uint i;
- while(t--)
- for(i=40;i>0;i--);
- }
- void KEY_J(void)//矩陣鍵盤函數
- {
- kd=0;
- P1DIR=0xff;
- P1OUT=0x00;//當我定義0xff,意味著我就開始了列掃描,從高位到底
- P2DIR=0x00;
- if((P2IN&0x0f)!=0x0f)//如果有變化,那應該是有按鍵被按下
- {
- delay(10);//防抖
- if((P2IN&0x0f)!=0x0f){
- switch((P2IN&0x0f))//按照順序,被按下的引腳會變成低電平,依次來判斷哪一行被按下。
- {
- case 0x0e:kd=kd;break; //第一行得到的數就是第幾列
- case 0x0d:kd=kd+8;break;//第二行得到的數就是第幾列加8
- case 0x0b:kd=kd+16;break;
- case 0x07:kd=kd+24;break;
- }
- P1DIR=0x00;
- P2DIR=0x0f;
- P2OUT=0x00;
- switch(P1IN)//按照順序,被按下的引腳會變成低電平,依次來判斷哪一行被按下。
- {
- case 0xfe:kd=kd+1;break; //第一行得到的數就是第幾列
- case 0xfd:kd=kd+2;break;//第二行得到的數就是第幾列加8
- case 0xfb:kd=kd+3;break;
- case 0xf7:kd=kd+4;break;
- case 0xef:kd=kd+5;break;
- case 0xdf:kd=kd+6;break;
- case 0xbf:kd=kd+7;break;
- case 0x7f:kd=kd+8;break;
- }
- }
- }
- return;
- }
- void cha_mod(){
- mode=mode<<1;
- if(mode==0x08)mode=0x01;
- //P3OUT=mode;
- P3OUT=P3OUT&(mode|0xf8);
- P3OUT=P3OUT|(mode&0x07);
- delay(5000);
- }
- uint pau=0;
- void cha_pau(){
- pau=pau^1;
- if(pau)
- P3OUT=P3OUT|0x40;
- else
- P3OUT=P3OUT&0xbf;
- delay(5000);
- }
- #define MYSET1 P3OUT|=0x08
- #define MYSET0 P3OUT&=0xf7
- uint UDP=0;
- void tiaozhi(){
- UDP=UDP^1;
- if((P3OUT&0x08)&&UDP)
- P3OUT|=0x10;
- else
- P3OUT&=0xef;
- }
- uint plot=0,cnt_rec=0;
- uint rect=0;
- uint rec[64];
- void rec_ins(){
- if(rect<64){
- if(P3OUT&0x08)
- rec[rect]=1;
- else
- rec[rect]=0;
- rect++;
- }else{
- for(int i=0;i<63;i++)
- rec[i]=rec[i+1];
- if(P3OUT&0x08)
- rec[63]=1;
- else
- rec[63]=0;
- }
- }
- #define LCDIO P4OUT
- #define LCD1602_RS_1 P5OUT|=1
- #define LCD1602_RS_0 P5OUT&=~1
- #define LCD1602_RW_1 P5OUT|=2
- #define LCD1602_RW_0 P5OUT&=~2
- #define LCD1602_EN_1 P5OUT|=4
- #define LCD1602_EN_0 P5OUT&=~4
- void LCD_check_busy()
- {
- P1DIR=0x00;
- LCDIO=0xff;
- LCD1602_RS_0;
- LCD1602_RW_1;
- LCD1602_EN_1;
- while(P1IN&0x80);
- LCD1602_EN_0;
- P1OUT=0x00;
- P1DIR=0xFF;
- }
- void LCD_write_command(unsigned char command)
- {
- //LCD_check_busy();
- LCD1602_RS_0;
- LCDIO=command;
- LCD1602_EN_1;
- //delayms(1);
- LCD1602_EN_0;
- delay(1);
- }
- void LCD_write_dat( unsigned char dat)
- {
- //LCD_check_busy();
- LCD1602_RS_1;
- LCDIO=dat;
- LCD1602_EN_1;
- //delayms(1);
- LCD1602_EN_0;
- delay(1);
- LCD1602_RS_0;
- }
- void LCD_set_xy( unsigned char x, unsigned char y )
- {
- unsigned char address;
- if (y == 1)
- address = 0x80+x;
- else if (y == 2)
- {
- address=0x80+0x40+x;
- }
- LCD_write_command(address);
- }
- void LCD_dsp_char( unsigned char x,unsigned char y, char dat)
- {
- LCD_set_xy( x, y );
- LCD_write_dat(dat);
- }
- void LCD_init(void)
- {
- P4DIR=0xFF;
- P4SEL=0;
- P5DIR=0xFF;
- P5SEL=0;
- P5OUT=0x00;
- P4OUT=0x00;
- delay(200);
- LCD1602_RW_0;
- LCD1602_EN_0;
- //CLEARSCREEN;//clear screen
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delay(10);
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delay(10);
- LCD_write_command(0x38);//set 8 bit data transmission mode
- delay(10);
- LCD_write_command(0x06);//open display (enable lcd display)
- delay(10);
- LCD_write_command(0x0C);//set lcd first display address
- delay(10);
- LCD_write_command(0x01);//clear screen
- delay(10);
- //LCD_write_command(0x80);//clear screen
- //delayms(1);
- }
- void dis_set(uint pos,char ch){
- if(pos<16)
- LCD_dsp_char(pos,1,ch);
- else
- LCD_dsp_char(pos-16,2,ch);
- }
- void display(){
- for(int i=0;i<rect;i+=2){
- if(rec[i])
- dis_set(i>>1,'=');
- else
- dis_set(i>>1,'.');
- }
- for(int i=rect;i<64;i+=2){
- dis_set(i>>1,' ');
- }
- }
- uint snd[30][16]={
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,
- 1,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,
- 1,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,
- 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,
- 1,1,1,0,1,1,1,0,1,0,0,0,0,0,0,0,
- 1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,
- 1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,
- 1,1,1,0,1,0,1,1,1,0,0,0,0,0,0,0,
- 1,0,1,1,1,0,1,0,1,0,0,0,0,0,0,0,
- 1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
- 1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,
- 1,0,1,1,1,0,1,1,1,0,1,0,0,0,0,0,
- 1,1,1,0,1,1,1,0,1,0,1,1,1,0,0,0,
- 1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,
- 1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
- 1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 1,0,1,0,1,1,1,0,0,0,0,0,0,0,0,0,
- 1,0,1,0,1,0,1,1,1,0,0,0,0,0,0,0,
- 1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,
- 1,1,1,0,1,0,1,0,1,1,1,0,0,0,0,0,
- 1,1,1,0,1,0,1,1,1,0,1,1,1,0,0,0,
- 1,1,1,0,1,1,1,0,1,0,1,0,0,0,0,0,
- };
- 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};
- uint luc[32];
- int bro;
- void ins(int tar){
- P6OUT=0xff;
- rem=siz[tar];
- for(int i=0;i<siz[tar];i++){
- luc[rem-i]=snd[tar][i];
- }
- MYSET1;
- bro=0;
- return;
- }
- void rep(){
- P6OUT=0xff;
- rem=rect>>1;;
- for(int i=0;i<rem;i++){
- luc[rem-i]=rec[i<<1];
- }
- MYSET1;
- bro=0;
- return;
- }
- void init(){
- WDTCTL = WDTPW + WDTHOLD;
- P3DIR=0xff;
- P3OUT=0x01;
- mode=0x01;
- LCD_init();
- return;
- }
- void sol1(){
- if(kd==2)
- MYSET1;
- else
- MYSET0;
- return;
- }
- void sol2(){
- if(kd==2)
- ins(0);
- if(kd==3)
- ins(1);
- }
- void sol3(){
- if(kd>=7)
- ins(kd-5);
- }
- int main( void )
- {
- init();
- while(1){
- KEY_J();
- if(kd==0){delay(10);}
- if(rem){
- P3OUT|=0x20;
- bro++;
- if(bro>=20){
- bro=0;
- rem--;
- if(luc[rem])
- MYSET1;
- else
- MYSET0;
- }
- }else{
- if(kd==1){cha_mod();}
- if(mode==0x01){sol1();}
- if(mode==0x02){sol2();}
- if(mode==0x04){sol3();}
- if(rem==0)
- P3OUT&=0xdf;
- if(kd==4){cha_pau();}
- if(kd==5){rect=0;}
- if(kd==6){rep();}
- }
- P6DIR=0xff;
- //P6OUT=rem;
- cnt_rec++;
- if(cnt_rec>=10){
- cnt_rec=0;
- if(pau==0)
- rec_ins();
- }
- plot++;
- if(plot>=20){
- plot=0;
- display();
- delay(0);
- }else{
- delay(64);
- }
- tiaozhi();
- };
- }
復制代碼
Keil代碼與Proteus仿真下載:
4 28.rar
(406.39 KB, 下載次數: 10)
2023-4-28 19:28 上傳
點擊文件名下載附件
|