MSP430技术论坛
直播中

kmno4

12年用户 971经验值
私信 关注
[讨论]

MSP430 Launchpad(MSP430G2231)开发板控制 数显游标卡尺

  MSP430G2231控制数显游标卡尺,感兴趣的可以试一下哈~


28.jpg
  (原文件名:1.jpg)

29.jpg
  (原文件名:2.jpg)

30.png
  (原文件名:3.png)
  这是代码,供大家参考:
  //*******************************************
  // Running on Launchpad
  // MSP430G2231
  // ------------------
  // /|| XIN|-
  // | | |
  // --|RST XOUT|-
  // | |
  // Vin+ -->|A1+ P1.2 |
  // |A1- = VSS P1.0|-->LED
  // | P1.1|-->TX RS232
  // | P1.4|<--CLOCK CALIPER
  // | P1.5|<--DATA CALIPER
  //
  //*******************************************
  #include
  int value = 0; // value received from caliper
  unsigned char clock_active = 0; // any clock activity during last 32msec?
  unsigned char ready_for_data = 0;// idle between clock burts, ready for next one
  unsigned char bits_so_far = 0; // current bit count during value "assembly"
  // how many CPU cycles between bits
  #define Bitime 104 //9600 Baud, SMCLK=1MHz (1MHz/9600)=104
  unsigned char BitCnt; // Bit count, used when transmitting byte
  unsigned int TXByte; // Value sent over UART when Transmit() is called
  #define LED BIT0 // LED on P1.0
  #define TXPIN BIT1 // RS232 TX on P1.1
  #define CLOCK BIT4 // Clock on P1.4
  #define DATA BIT5 // Data on P1.5
  void Transmit(void);
  void main(void)
  {
  DCOCTL = 0x00; // Safe Flow
  BCSCTL1 = CALBC1_1MHZ; // run at 1Mhz
  DCOCTL = CALDCO_1MHZ;
  //WDT as 32 ms interval counter. If no action on clock withing 32msec,
  // we are ready to receive next "number"
  WDTCTL = WDT_MDLY_32; // default timer 32 msec
  IE1 |= WDTIE; // Enable WDT interrupt
  P1DIR |= LED; // Set P1.0 to output direction
  P1OUT |= LED; // LED ON, we'r ready
  P1SEL |= TXPIN;
  P1DIR |= TXPIN; // Set P1.1 to output direction
  // Set up CLOCK input pin
  P1DIR &= ~CLOCK; // sets input direction
  P1OUT |= CLOCK; // pull-up is selected
  P1REN |= CLOCK; // pull-up/pull-down enabled
  P1IES &= ~CLOCK; // interupt triggered on low-to-high
  P1IFG &= ~CLOCK; // reset interup flag to 0. needs to be reset on start
  P1IE |= CLOCK; // interupt enabled for CLOCK
  // Set up DATA input pin
  P1DIR &= ~DATA; // sets input direction
  P1OUT |= DATA; // pull-up is selected
  P1REN |= DATA; // pull-up/pull-down enabled
  P1IES &= ~DATA; // interupt triggered on low-to-high
  P1IFG &= ~DATA; // reset interup flag to 0. nneds to be reset on start
  P1IE &= ~DATA; // interupt disabled for DATA
  // sending something over serial
  while (1)
  {
  __bis_SR_register(LPM0_bits + GIE);
  // after we went into low power mode, program counter is at this instruction
  // (next one after where you entered LPM), but it's not moving until you enable active mode
  // within main loop. That can be done with __bic_SR_register_on_exit(LPM0_bits) in ISR
  _NOP();
  // seding next value. value has been assambled by CLOCL interupt function
  // value is 16 bit, TXByte should be 8, sending in two parts
  TXByte = value >> 8; // first byte (most significant bits)
  Transmit();
  TXByte = value & 0xFF; // second byte (least significant)
  Transmit();
  P1OUT ^= LED; // blink LED
  }
  }
  // Function Transmits Character from TXByte
  void Transmit()
  {
  CCTL0 = OUT; // TXD Idle as Mark
  TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode
  BitCnt = 0xA; // Load Bit counter, 8 bits + ST/SP
  CCR0 = TAR;
  CCR0 += Bitime; // Set time till first bit
  TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1)
  TXByte = TXByte << 1; // Add start bit (which is logical 0)
  CCTL0 = CCIS0 + OUTMOD0 + CCIE; // Set signal, intial value, enable interrupts
  while ( CCTL0 & CCIE ); // Wait for TX completion
  TACTL = TASSEL_2; // SMCLK, timer off (for power consumption)
  }
  // Timer A0 interrupt service routine. Used to send bits over RS232
  #pragma vector=TIMERA0_VECTOR
  __interrupt void Timer_A (void)
  {
  CCR0 += Bitime; // Add Offset to CCR0
  if ( BitCnt == 0) // If all bits TXed, disable interrupt
  CCTL0 &= ~ CCIE;
  else
  {
  CCTL0 |= OUTMOD2; // TX Space
  if (TXByte & 0x01)
  CCTL0 &= ~ OUTMOD2; // TX Mark
  TXByte = TXByte >> 1;
  BitCnt --;
  }
  }
  // Button is pressed
  #pragma vector=PORT1_VECTOR
  __interrupt void PORT1_ISR(void)
  {
  static unsigned char port;
  port = P1IN; // read DATA port value as soon as possible (otherwise it might be gone)
  P1IFG &= ~CLOCK; // Clear interrupt flag
  clock_active = 1;
  if (ready_for_data)
  {
  if (bits_so_far && bits_so_far <= 16){ // first bit is start bit, ignore it. Total we have 24 bits. But we need only 16
  if (!(port & DATA)) // if 0 recived, invert = >1
  value |=0x8000; // then set most significant bit
  value = value >> 1; // and move it one right
  }else if (bits_so_far == 21){ // 21st bit indicates sighn (+/-)
  if (!(port & DATA))
  value = (~value)+1; // make it negative
  }else if (bits_so_far >= 23){ // we'r done, got all bits
  ready_for_data = 0; // warchdog timer will set it
  __bic_SR_register_on_exit(LPM0_bits); // wake up main from LPM sleep
  }
  bits_so_far++;
  }
  }
  // watchdog used as 30msec timer for detecting start of new bit burst on clock
  #pragma vector=WDT_VECTOR
  __interrupt void WDT_ISR(void)
  {
  if (ready_for_data)
  return;
  if (clock_active){
  clock_active = 0; // clear flag, will wait another 32msec to see if there have been any activity of clock
  ready_for_data = 0; // not yet ready
  }else{
  ready_for_data = 1; // nothing within last 32msec, ready for next clock burst
  value = 0; // init of value
  bits_so_far = 0; // init of bit counter
  }
  }


回帖(3)

lstcspring

2012-11-22 21:07:51
你哪个国家的,注释都是英文?
举报

ymqnuc

2013-2-16 13:33:40
ddddddddddddddddddddddddddddd
举报

snowcable

2013-10-16 21:11:43
正好设备器件重合,拿来试下!感谢楼主分享...
举报

更多回帖

发帖
×
20
完善资料,
赚取积分