MSP430 ile Morse Kodu Okuma

Başlatan halil_ist, 09 Kasım 2014, 21:10:32

halil_ist

Merhabalar,

MSP430G2553 ile Morse Kod okuyan bir program yazmak istiyorum. Sadece 7-segment displayden 0'dan 9'a kadar olan sayıları göreceğiz. Devrenin resmini ekledim. Interrupt kullanmadan yapmamız gerekiyor. Yardımcı olursanız sevinirim.

P1.1 pinindeki butonla nokta, P1.2 pinindeki butonla çizgi göndereceğiz. Uygun diziyi girdikten sonra Mspnin üzerindeki P1.3 butonuna bastığımızda, program bu diziyi çözecek ve 7-segment displayde gösterecek.

Eğer uygun diziyi girmezsek, 7-segment displayde E harfi gözükecek.

Baktığımda, morse alfabesinde 0'dan 9' a kadar olan sayılara karşılık " ----- .---- ..--- ...-- ....- ..... -.... --... ---.. ----. " veriliyormuş.
Örnek verecek olursak, ben butonlardan
----- verdiğimde ekranda 0 gözükecek,
.---- verdiğimde 1 sayısı gözükecek.

Devre şeması :







Sparky


halil_ist

Aslında öğrenmek istediğim şey,  butonlara bastığımda gönderdiğim çizgi ve noktaların 7-segment displayde sayı halinde nasıl göstereceği.


RaMu

MSP430 ile buton kullanarak led yakıp söndürebiliyor musun,
bunu yapıyorsan işin zor kısmı tamam demektir,
yok bilmiyorsan önce ilk adımı öğrenmek zorundasın.

Flatron

#4
Alıntı yapılan: RaMu - 09 Kasım 2014, 23:05:22MSP430 ile buton kullanarak led yakıp söndürebiliyor musun,
bunu yapıyorsan işin zor kısmı tamam demektir,
yok bilmiyorsan önce ilk adımı öğrenmek zorundasın.

Hocam MSP430 da LED yakıp sönderene kadar Ardiona ya 5 farklı Sensorü SPI haberleştirim daha iyi :) TI bu kiti millete gıcıklık olsun diye çıkartmış sanırım

Sparky

Bu kart hakkında bilgin ve tecrüben var mı? led yak/söndür , buton ile basit uygulamalar kısmını hallettin mi? Bu konularda eksiğin varsa önce onları tamamlaman daha iyi olur.

MSP430 ile daha önce çalışmadım fakat mikrodenetleyici mantığı her kartta aynıdır. Bahsettiğin uygulama çok zor görünmüyor. Buton + led yakma uygulamaları ve bilgisiyle halledilir.

halil_ist

Evet butonta led yakıp söndürebiliyorum. O konuda sıkıntım yok.

P1DIR = 0x01h; P10UT = 0x00h; vs. gibi komutlarla digital input output konusunda yeterli bilgim var ama yapamadığım kısım, butonlara basıp displayde sayı görmek.

örneğin; morse alfabesine göre 5 kere butonla çizgi gönderdiğimde, displayde 0 sayısını görmeliyim.


Flatron


halil_ist

Bu videoyu izlemiştim ama kodu indiremedim .ino uzantılı bir dosyası var :(

Flatron

Kod bu
/* Morse Code Key Trainer for the MSP430
by Ido Gendel, 2013
Share and Enjoy... at your own risk ;-) */

// Energia library for handling a 16x2 LCD
#include <LiquidCrystal.h>
// Let's define our LCD object
LiquidCrystal lcd(P2_0, P2_1, P1_7, P2_3, P2_4, P2_5);
// Straight Key connects GND to
#define KEY_PIN P1_2
// Continuous buzzer  controlled by
#define SPEAKER_PIN P1_1
// Reset/Mode selector  connects GND to
#define CTRL_PIN P1_3
// Random seed source (floating, NC analog pin)
#define NOISE_PIN A5
// State LEDs, charlieplexed, connect to
#define MODE_LED_PIN1 P1_6
#define MODE_LED_PIN2 P1_4

/* Key timing (ms): Set these to taste and ability
Note that the standard requires a 1:3:7 ratio */
#define DIT_DURATION 100
#define DAH_DURATION 300
#define SPACE_DURATION 700

// Lookup "tables" for converting intl. Morse code to ASCII:

/* First, the Alphabet in a super-economic lookup structure.
I invented it, then discovered I was hardly the first :-) */
const char CODES_1_4[31] = "ETIANMSURWDKGOHVF_L_PJBXCYZQ__";
/* There are relatively little codes with 5/6 "bits",
so for them I'm using a linear search with a sentinel
That means I can't have these as const... */
char CODES_5[30] = {0, '5', 1, '4', 3, '3', 7, '2', 10, '+', 15, '1', 16, '6', 17, '=',
                                        18, '/', 22, '(', 24, '7',  28, '8', 30, '9', 31, '0', 123, '_'};
char CODES_6[20] = {12, '?', 18, '"', 21, '.', 26, '@', 30, '\\'',
                                       33, '-', 45, ')', 51, ',', 56, ':', 123, '_'};                                       

// A lookup string for creating test strings
const char punctuationChars[14] = "+=/()?'.@\\"-,:";

// These are updated by the pin change interrupts
volatile boolean keyChanged = false, keyState = LOW;
volatile boolean ctrlChanged = false, ctrlState = LOW;

// Information about ongoing Morse input goes here
char currentCode = 0, currentCodeLength = 0;

// Time-keeping
uint32_t m, keyTimeStamp = 0, ctrlTimeStamp = 0;

/* This string is used for "scrolling" (in free mode)
or for test string storage (in test mode) */
char displayStr[17] = "                ";
unsigned char displayStrIndex;

#define MODE_FREE 1
#define MODE_TEST 2
char mode = MODE_FREE;

// Test mode keeps score
char score = 0;
// Where to put the score in test mode:
#define SCORE_LCD_X 11
#define SCORE_LCD_Y 0

// Flags
boolean spaceRequired = false;
boolean testFinished = false;

//---------------------------------------------------------
// Enable/Disable the switch reading interrupts
void setInterrupts(const char active) {
 
  if (active) {
    attachInterrupt(KEY_PIN, keyChangeInterrupt, CHANGE);
    attachInterrupt(CTRL_PIN, ctrlChangeInterrupt, CHANGE);
  } else {
       detachInterrupt(KEY_PIN);
       detachInterrupt(CTRL_PIN);
    } // else
 
} // setInterrupts
//---------------------------------------------------------

/* Activate one of two charlieplexed LEDs
to provide current mode indication. */
void setModeLEDs() {

  digitalWrite(MODE_LED_PIN1, LOW); 
  digitalWrite(MODE_LED_PIN2, LOW);

  switch (mode) {
    case MODE_FREE : digitalWrite(MODE_LED_PIN1, HIGH); break;
    case MODE_TEST : digitalWrite(MODE_LED_PIN2, HIGH); break;   
  } // switch
 
} // setModeLEDs

//---------------------------------------------------------
// This is only used in Free mode
void charToLCD(const char c) {
 
   // Should we start a new line?
  if (displayStrIndex == 16) {
   
       // "Scroll" display up
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(displayStr);
      displayStrIndex = 0;
      lcd.setCursor(0, 1);
       
  } // if

  lcd.print(c);
  displayStr[displayStrIndex++] = c;
 
} // charToLCD

//---------------------------------------------------------

/* Look up character by Morse code as bits (0=Dit, 1=Dah)
and its length */
char morseToASCII(const char code, char len) {
 
   char *p;
 
  // Illegal code?
  if ((len < 1) || (len > 6)) return '_';
  // Superfast lookup for 1 to 4 bit codes
  if (len < 5) return CODES_1_4 [(1 << len) - 2 + code] ;

  /* Linear search for 5/6 bit codes
  First, set the sentinel on the proper lookup table: */
  if (len == 5) {
    CODES_5[28] = code;
    p = &CODES_5[0];
  } else {
       CODES_6[18] = code;
       p = &CODES_6[0];
    } // else

  // Now perform the actual search
  for ( ; *p != code; p += 2);
  return *(p + 1);
 
} // morseToASCII

//--------------------------------------------------------

// Interrupt function for Straight Key reading
void keyChangeInterrupt() {
 
  keyChanged = true;
  // The key connects to GND, so we need the inverse
  keyState = !digitalRead(KEY_PIN);
 
} // keyChangeInterrupt

//--------------------------------------------------------

// Interrupt function for Reset/Mode switch reading
void ctrlChangeInterrupt() {
 
  ctrlChanged = true;
  // The key connects to GND, so we need the inverse
  ctrlState = !digitalRead(CTRL_PIN);
 
} // ctrlChangeInterrupt

//--------------------------------------------------------
// Update the currect test score on the LCD
void showScore() {

  lcd.setCursor(SCORE_LCD_X, SCORE_LCD_Y);
  // Score has a leading zero if it's less than 10
  lcd.write(score / 10 + 48);
  lcd.write(score % 10 + 48); 
 
} // showScore

//--------------------------------------------------------
void initiateTest() {
 
  unsigned char p, r;
 
  /* Populate a test string with characters, different
  probability for each group (letters, digits, punctuation) */
  for (p = 0; p < 16; p++) {

    r = random(100);
    if (r < 80) displayStr[p] = random(26) + 65; // A-Z
     else if (r < 95) displayStr[p] = random(10) + 48; // 0-9
      else displayStr[p] = punctuationChars[random(13)]; // Punctuation

  } // for

  // Put a couple of spaces
  displayStr[random(5) + 2] = ' ';
  displayStr[random(5) + 10] = ' ';   
 
  // Display the test string
  lcd.setCursor(0, 1);
  lcd.print(displayStr);
 
  // Reset test parameters
  displayStrIndex = 0;
  score = 0;
  showScore();
  testFinished = false;
 
} // initiateTest

//--------------------------------------------------------
// Compare user input to current test character
void checkMatch(const char c) {
 
  // Update score, display a right/wrong indication
  lcd.setCursor(displayStrIndex, 1);
  if (c == displayStr[displayStrIndex]) {
     score++;
     lcd.write(0xE8); // "Root", looks like a check mark
     showScore();     
  } else lcd.write('x'); 

  // Is the test finished?
  if (displayStrIndex == 15) testFinished = true;
   else  displayStrIndex++;
 
} // checkMatch

//--------------------------------------------------------
// Test end sequence
void finishTest() {

  char n; 
 
  // Disable interrupts while doing the 'graphics'
  setInterrupts(false);
     
  // Advancing bar
  lcd.setCursor(0, 1);
  for (n = 0 ; n < 16 ; n++) {
    lcd.write(255);
    delay(25);
  } // for
     
  // Bar recedes back to indicate score
  for(--n ; n >= score ; n--) {
    lcd.setCursor(n, 1);       
    lcd.write(' ');
    delay(100);
  } // for
     
  // wait for user to press something
  while (digitalRead(KEY_PIN) && digitalRead(CTRL_PIN)) ;
  // Discard this particular press (wait until it ends)
  while (!digitalRead(KEY_PIN) || !digitalRead(CTRL_PIN)) ;
         
  // Reset test
  resetCurrentMode();
  // Resume interrupts
  setInterrupts(true); 
 
} // finishTest

//--------------------------------------------------------
void resetCurrentMode() {

  setModeLEDs();
  lcd.begin(16, 2);

  switch (mode) {
    case MODE_FREE: lcd.print("Free Keying Mode");
                                        break;
    case MODE_TEST: lcd.print("Test Mode    /16");               
                                        initiateTest();
                                        break;
  } // switch
 
  lcd.setCursor(0, 1);
  displayStrIndex = 0;
  spaceRequired = false;
 
} // resetCurrentMode

//--------------------------------------------------------
void setup()
{
 
  pinMode(KEY_PIN, INPUT_PULLUP);
  pinMode(CTRL_PIN, INPUT_PULLUP);
  pinMode(SPEAKER_PIN, OUTPUT);
  digitalWrite(SPEAKER_PIN, LOW);

  pinMode(MODE_LED_PIN1, OUTPUT);
  pinMode(MODE_LED_PIN2, OUTPUT); 

   randomSeed(analogRead(NOISE_PIN));
   // A delay against ghost signals on power-on
   delay(10);
   setInterrupts(true);
   resetCurrentMode();
   
} // setup

//--------------------------------------------------------
void analyzeKeyPress(const int16_t duration) {
 
  // Ignore improbable presses (i.e. Debounce)
  if (duration < 2) return;

  // Mark as error when press is too long
  if (duration > DAH_DURATION) currentCodeLength = 8;
   else {
     
     // it's a legitimate "bit", add it to code
     currentCodeLength++;
     currentCode <<= 1;
     // Dit is 0, Dah is 1:
     if (duration > DIT_DURATION) currentCode++;
     
   } // else
 
} // analyzeKeyPress

//--------------------------------------------------------
/* The interrupt only identifies changes,
this processes them (outside the interrupt function) */
void processKeyChange() {

  // Audio feedback   
  digitalWrite(SPEAKER_PIN, keyState);
 
  // Add completed Dit or Dah if key is up
  if (!keyState) analyzeKeyPress(m - keyTimeStamp);
  keyTimeStamp = m;
  keyChanged = false;
 
} // processKeyChage

//--------------------------------------------------------
/* The interrupt only identifies changes,
this processes them (outside the interrupt function) */
void processCtrlChange() {

  // Switch just pressed? begin time count
  if (ctrlState) ctrlTimeStamp = m;
   else {

     // Switch released; if it was a long press, switch mode
     if ((m - ctrlTimeStamp) > DAH_DURATION) mode = 3 - mode;
     // Short or long press, start anew
     resetCurrentMode();
     
    } // else
   
  ctrlChanged = false;
 
} // processCtrlChage

//--------------------------------------------------------
void loop() {

  char c; 
 
  m = millis();
 
  // Morse input timeout?
  if (m - keyTimeStamp > DAH_DURATION) {

    // Was there an input?
    if (currentCodeLength) {

      c = morseToASCII(currentCode, currentCodeLength);
      switch (mode) {

        case MODE_FREE: if (spaceRequired) charToLCD(32);
                                          charToLCD(c);
                                          break;
       case MODE_TEST: if (spaceRequired) checkMatch(32);   
                                           // Prevent overflow to next test
                                           if (!testFinished)  checkMatch(c);
                                           break;
                                           
        }  // switch
     
      // Clear input data
      currentCode = currentCodeLength = 0;
      spaceRequired = false;
     
    }  else   
         // No input; is it time to add an auto whitespace?
         if (m - keyTimeStamp > SPACE_DURATION)
           spaceRequired = displayStrIndex > 0;
   
  } // if
 
  if (testFinished) finishTest();
 
  if (keyChanged) processKeyChange();
  if (ctrlChanged) processCtrlChange();
   
} // loop

RaMu

Alıntı yapılan: Flatron - 09 Kasım 2014, 23:09:37Hocam MSP430 da LED yakıp sönderene kadar Ardiona ya 5 farklı Sensorü SPI haberleştirim daha iyi :) TI bu kiti millete gıcıklık olsun diye çıkartmış sanırım

Arduino nun ne ilgisi var şimdi,
konuyu dağıtmayalım bence.

Arkadaşın sorunu daha önce 7 segmentle ilgili örnek yapmamış olması,
bu işler sadece tecrübe ve azim ister,
şimdi parçaları tek tek öğrenip birleştirirse kolaylıkla bu programı yazar.


Şimdi 7 segment display nasıl kullanılır onu çözmelisin,
istersen netteki örneklere bak,
istersen al eline ölçü aletini
7segdisp in pinlerini belirle,a,b,..,g  toplam 7 pin kullanacaksın,
mcu çıkışından hangi pinlere 1 hangilerine 0 gönderirsem 0 dan 9 a rakamları gösterir
kısmını çöz,
misal displayde 1 gösterebilmek için
P2 portuna 0x06 değerini göndermelisin,
yaptığın bağlantıya göre tek tek bu değerleri hesaplamalısın,
sonra direk P2 portuna bu değerleri 1 saniye aralıklarla gönderen programı yaz
displayde 0-9 saydığını gör,
sonra buton işine geçersin yavaş yavaş.

Yok ben hazır kod istiyorum gibi bir niyetin varsa bunuda çekinmeden baştan belirtebilirsin,
nasıl yapılacağını öğrenmek istiyorsan anlatmaya çalışırım bu şekilde.

halil_ist

#11
Anlayışın için teşekkür ederim RaMu. Aslında daha önce 7segment display çalışmalar da yaptım. Onda da sıkıntım yok.

Aslında kod olsa kolayca anlayacağımı düşünüyorum. Hem böylece öğrenmiş olurum.

Flatron

#12
Alıntı yapılan: RaMu - 10 Kasım 2014, 00:43:45Arduino nun ne ilgisi var şimdi,
konuyu dağıtmayalım bence.


Konu neden dağılsın?
Arduino bir geliştirme bordudur?
MSP430 da bir geliştirme bordudur

Aralarındaki en bariz farkı söylemiyelimmi?
Biri 5 dakikada kurulur
öbürüne 2 gb indirirsin daha neler indirmen gerektiğine dair hiçbir bilgi bulamazsın doğru dürüst bir kaynak bile bulamazsın (Anlattığım 3-4 yıl öncesine ait)



RaMu

Biri profesyoneldir biri amatör,
Ne zaman ki arduino değil atmel dersin
atmel studioda program yazarsın işler değişir.

Flatron

#14
@ halil_ist
Yukarıda kodu yapıştırdım.
Yapan zaten hemen her satırında satırın ne yaptığınıda anlatmış .Bence önce aynısını LCD de çalıştırın daha sonra tam olarak anlamak için parça parça inceleyin ve  LCD de tamamlayın, en son seven segment i eklersiniz. böylece kodun doğru olduğundan emin olursunuz

Örneğin LookUp komutunu inceleyin.(Bu komutla çok daha uzun kod yazmanıza gerek kalmaz)
Ayrıca önceki mesajda verdiğim linkte yapanın başka önemli açıklamaları da var.Linkte şemada var
Kolay Gelsin

guest

Ben bunun çalışan kodunu yazabilirim istersen. Ama hazır koda kızmasınlar sonra.

bossofbass


halil_ist

Alıntı yapılan: guest - 10 Kasım 2014, 18:31:02Ben bunun çalışan kodunu yazabilirim istersen. Ama hazır koda kızmasınlar sonra.

Yo hayır kızmazlar. yazarsan ben anlarım zaten çok iyi olur benim için.

guest

Sevgili Halil kod adlı genç arkadaşım. Ne yazık ki benden lab alan Halil isimli biri olmadığı için kim olduğunu buradan anlama şansım yok. İlk hafta size söylediğim gibi dışarıdan hazır kod almanız yasaktır. Bu yasak bundan benim bir çıkarım olduğu için değil, sizin deneyler üzerinde uğraşarak  konuyu daha iyi anlamanız için konmuştur. Tabi ki farklı mecralardan yardım alabilirsin ama hazır kod değil. Çarşamba günü görüşmek üzere.

Flatron

#19
Neyse umarım yetiştirir .

Hızlı Yanıt

Not: Bu konu bir moderatör tarafından onaylanmadan görüntülenmeyecektir.

Adı:
E-Posta:
Doğrulama:
Lütfen bu kutuyu boş bırakın:
IRFP250 Nedir:
kısayollar: göndermek için alt+s veya önizleme yapmak için alt+p'ye basın