[资料分享] ADS1100 驱动程序--MSP430F413

[复制链接]
889|0
 楼主| xyz549040622 发表于 2020-1-27 10:47 | 显示全部楼层 |阅读模式
  1. //------------------------------------------------------------------------------
  2. // ADS1100_Demo.c - ADS1100 Bridge Sensor Readout Demo w/ MSP430F413
  3. //
  4. // Description: Program reads out an external ADS1100 Sigma-Delta ADC over the
  5. // I2C interface. The differential input voltage is displayed as a signed number
  6. // on a 3.5 digit LCD display. The displayed value is calculated using a 2-point
  7. // calibration mechanism. During initial power-up (INFOA Flash memory is erased),
  8. // two calibration data points are obtained (CalMin and CalMax) and stored in
  9. // Flash memory. The range of CalMin to CalMax is projected into a display-value
  10. // from 0 to CAL_MIN_MAX_SPAN. Button #1 is used to enter low-power mode,
  11. // button #2 is used to re-calibrate. An external 32-kHz watch crystal is used
  12. // for time interval generation and for driving the LCD.
  13. //
  14. //          /|\            /|\ /|\
  15. //           |    ADS1100  10k 10k  MSP430F413           
  16. //           |   +-------+  |   | +----------+
  17. //           +---|Vcc SDA|<-|---+>|P2.0      |    +----------------------+
  18. //       o-------|VIN+   |  |     |    S0-S23|--->| Varitronix 3.5 digit |
  19. //       o-------|VIN-   |  |     |      COM0|--->|  Static LCD Display  |
  20. //            +--|Vss SCL|<-+-----|P2.1      |    +----------------------+                        
  21. //           \|/ +-------+        |          |
  22. //                                |  XIN/XOUT|<---32.768KHz Watch Crystal     
  23. //                                |      P1.6|<---Button #1 (low-active)
  24. //                                |      P1.7|<---Button #2 (low-active)
  25. //                                +----------+
  26. // Andreas Dannenberg
  27. // Texas Instruments Inc.
  28. // June 2004
  29. // Built with IAR Embedded Workbench Version: 3.10A
  30. //------------------------------------------------------------------------------

  31. #include "msp430x41x.h"
  32. #include "I2C_Master.h"

  33. #define CAL_MIN_MAX_SPAN    1000                // Scale value for CalMin/CalMax

  34. // Definitions for ADS1100 A/D converter
  35. #define ADS1100_SA          (0x48)              // ADS1100 I2C Slave Address
  36. #define ADS1100_GAIN1       (0x00)              // PGA Gain X1
  37. #define ADS1100_GAIN2       (0x01)              // PGA Gain X2
  38. #define ADS1100_GAIN4       (0x02)              // PGA Gain X4
  39. #define ADS1100_GAIN8       (0x03)              // PGA Gain X8
  40. #define ADS1100_128SPS      (0x00)              // 128 Samples/s
  41. #define ADS1100_32SPS       (0x04)              // 32 Samples/s
  42. #define ADS1100_16SPS       (0x08)              // 16 Samples/s
  43. #define ADS1100_8SPS        (0x0C)              // 8 Samples/s
  44. #define ADS1100_SC          (0x10)              // Single Conversion Mode
  45. #define ADS1100_ST_BSY      (0x80)              // Start Conversion + Busy

  46. // Circuit related definitions
  47. #define BRIDGE_H            (0x38)              // IO pins for pos. bridge rail
  48. #define BRIDGE_L            (0x07)              // IO pins for neg. bridge rail

  49. enum
  50. {
  51.   BT_ISR_NRM,                                   // BT ISR - Wakeup
  52.   BT_ISR_CL1,                                   // BT ISR - Show 'CAL'
  53.   BT_ISR_CL2,                                   // BT ISR - Display 'LO'
  54.   BT_ISR_CH1,                                   // BT ISR - Toggle CAL/HI
  55.   BT_ISR_CH2                                    // BT ISR - Toggle CAL/HI
  56. };

  57. enum
  58. {
  59.   P1_ISR_NRM,                                   // Port1 ISR - Normal Mode
  60.   P1_ISR_CL,                                    // Port1 ISR - Cal Low Mode
  61.   P1_ISR_CH                                     // Port1 ISR - Cal High Mode
  62. };

  63. const unsigned char LCD_Tab[] =
  64. {
  65.   0x77,                                         // Displays "0"
  66.   0x12,                                         // Displays "1"
  67.   0x3d,                                         // Displays "2"
  68.   0x3b,                                         // Displays "3"
  69.   0x5a,                                         // Displays "4"
  70.   0x6b,                                         // Displays "5"
  71.   0x6f,                                         // Displays "6"
  72.   0x13,                                         // Displays "7"
  73.   0x7f,                                         // Displays "8"
  74.   0x7b,                                         // Displays "9"
  75.   0x5e,                                         // Displays "H"         
  76.   0x64,                                         // Displays "L"
  77.   0x65,                                         // Displays "C"
  78.   0x5f,                                         // Displays "A"
  79.   0x00,                                         // Displays Blank
  80.   0x00                                          // Displays Blank
  81. };  

  82. // Global vars
  83. static unsigned int BtIsrMode;                  // ISR Mode for Basic Timer
  84. static unsigned int P1IsrMode;                  // ISR Mode for Port 1
  85. static int CalMinTmp;                           // Vars to hold calib values
  86. static int CalMaxTmp;
  87. static int LastADCValue;
  88. static char UpdateDisplay = 1;                  // Flag to request LCD update

  89. #pragma dataseg = INFOA                         // Info Flash Memory Block A
  90. __no_init static int CalMin;
  91. __no_init static int CalMax;
  92. #pragma dataseg = default

  93. // Function prototypes
  94. void Init_Sys(void);
  95. void StoreCalInFlash(void);
  96. void Disp_Signed_3_5(int Value);
  97. void Disp_BCD_3_5(unsigned int Value);
  98. //------------------------------------------------------------------------------
  99. void main(void)
  100. {
  101.   Init_Sys();
  102.   
  103.   if (CalMin == CalMax)                         // Are constants in Flash OK?
  104.   {
  105.     BtIsrMode = BT_ISR_CL1;                     // Go to calibration mode
  106.     P1IsrMode = P1_ISR_CL;
  107.   }
  108.   else
  109.   {
  110.     BtIsrMode = BT_ISR_NRM;                     // Go to measurement mode
  111.     P1IsrMode = P1_ISR_NRM;
  112.   }
  113.   
  114.   I2CWrite8(ADS1100_SA, ADS1100_8SPS + ADS1100_GAIN8);  // Start conversions
  115.   __bis_SR_register(LPM3_bits + GIE);           // Enter LPM3 w/ ints enabled
  116. }
  117. //------------------------------------------------------------------------------
  118. void Init_Sys(void)
  119. {
  120.   WDTCTL = WDTPW + WDTHOLD;                     // Stop WDT
  121.   FLL_CTL0 |= XCAP18PF;                         // Set load capacitance for xtal
  122.   LCDCTL = 0xc5;                                // Static LCD, segments = 0 - 23
  123.   BTCTL = BT_fLCD_DIV256+BTDIV+BT_fCLK2_DIV32;  // 0.25s BT Int, Set LCD freq
  124.   IE2 |= BTIE;                                  // Enable Basic Timer interrupt
  125.   P1OUT = 0;                                    // P1OUTs = 0
  126.   P1DIR = 0x3f;                                 // P1.7/P1.6 input, others outp
  127.   P1IES = 0xc0;                                 // P1.7/P1.6 int on falling edge
  128.   P1IFG = 0;
  129.   P1IE = 0xc0;                                  // Enable button intuerrupts
  130.   P2OUT = 0;                                    // P2OUTs = 0
  131.   P2DIR = 0xfc;                                 // Set port but I2C pins to outputs
  132.   P3OUT = 0;                                    // P3OUTs = 0
  133.   P3DIR = 0xff;                                 // Set port to outputs
  134.   P4OUT = 0;                                    // P4OUTs = 0
  135.   P4DIR = 0xff;                                 // Set port to outputs
  136.   P5OUT = 0;                                    // P5OUTs = 0
  137.   P5DIR = 0xff;                                 // Set port to outputs
  138.   P6OUT = BRIDGE_H;                             // Enable bridge supply voltage
  139.   P6DIR = 0xff;                                 // Set port to outputs
  140. }
  141. //------------------------------------------------------------------------------
  142. void StoreCalInFlash(void)
  143. {
  144.   FCTL2 = FWKEY + FSSEL1 + FN1;                 // SMCLK/3 = ~333kHz
  145.   FCTL3 = FWKEY;                                // Clear LOCK
  146.   FCTL1 = FWKEY + ERASE;                        // Enable segment erase
  147.   *(unsigned int *)0x1080 = 0;                  // Dummy write, erase info A
  148.   FCTL1 = FWKEY + WRT;                          // Enable write
  149.   CalMin = CalMinTmp;                           // Program calibration constants
  150.   CalMax = CalMaxTmp;
  151.   FCTL1 = FWKEY;                                // Done. Clear WRT
  152.   FCTL3 = FWKEY + LOCK;                         // Done. Set LOCK
  153. }
  154. //------------------------------------------------------------------------------
  155. void Disp_Signed_3_5(int Value)
  156. {
  157.   unsigned int i;
  158.   unsigned int Output;
  159.   char fNeg = 0;

  160.   if (Value >= 2000)                            // Higher/equ w/ 2000?
  161.   {
  162.     Disp_BCD_3_5(0x0a1f);                       // Display 'HI'
  163.     return;
  164.   }

  165.   if (Value < -1999)                            // Less than -1999?
  166.   {
  167.     Disp_BCD_3_5(0x0b0f);                       // Display 'LO'
  168.     return;
  169.   }

  170.   if (Value < 0)                                // Test for new negative value
  171.   {
  172.     Value = -Value;                             // Negate value
  173.     fNeg = 1;                                   // Set negative flag
  174.   }

  175.   for (i = 16, Output = 0; i; i--)              // BCD Conversion, 16-Bit
  176.   {
  177.     Output = __bcd_add_short(Output, Output);
  178.     if (Value & 0x8000)
  179.       Output = __bcd_add_short(Output, 1);
  180.     Value <<= 1;
  181.   }

  182.   if (fNeg)
  183.     Output |= 0x2000;

  184.   Disp_BCD_3_5(Output);
  185. }
  186. //------------------------------------------------------------------------------
  187. void Disp_BCD_3_5(unsigned int Value)
  188. {
  189.   unsigned char *pLCD = (unsigned char *)&LCDM1;  // 1st LCD mem location
  190.   unsigned char LCDSegInfo;
  191.   unsigned char LCDDigit;

  192.   do
  193.   {
  194.     LCDDigit = Value & 0x0f;                    // Get one LCD digit
  195.     LCDSegInfo = LCD_Tab[LCDDigit];             // Get LCD segment information
  196.     *pLCD++ = LCDSegInfo;                       // Segments a & b to LCD
  197.     LCDSegInfo >>= 1;
  198.     *pLCD++ = LCDSegInfo;                       // Segments c & d to LCD
  199.     LCDSegInfo >>= 1;
  200.     *pLCD++ = LCDSegInfo;                       // Segments e & f to LCD
  201.     LCDSegInfo >>= 1;
  202.     *pLCD++ = LCDSegInfo;                       // Segments g & h to LCD
  203.     Value >>= 4;                                // Process next digit
  204.   } while (pLCD < (unsigned char *)&LCDM13);    // Updated all segments?

  205.   if (Value & 0x01)                             // Data >999?
  206.     LCDM12 |= 0x10;                             // B-C digit active
  207.   
  208.   if (Value & 0x02)                             // Display neg sign?
  209.     LCDM8 |= 0x10;                              // "-" segment active
  210. }
  211. //------------------------------------------------------------------------------
  212. #pragma vector = BASICTIMER_VECTOR
  213. __interrupt void BT_ISR(void)
  214. {
  215.   int CurrentADCValue;

  216.   switch (BtIsrMode)
  217.   {
  218.     case BT_ISR_NRM :
  219.       CurrentADCValue = I2CRead16(ADS1100_SA);  // Get conversion result
  220.       if (UpdateDisplay || LastADCValue != CurrentADCValue)
  221.       {
  222.         UpdateDisplay = 0;                      // Reset flag
  223.         LastADCValue = CurrentADCValue;         // Store new value
  224.         Disp_Signed_3_5(((long)CurrentADCValue - CalMin) * CAL_MIN_MAX_SPAN /
  225.                         (CalMax - CalMin));
  226.       }
  227.       break;
  228.     case BT_ISR_CL1 :
  229.       Disp_BCD_3_5(0x0cdb);                     // Display 'CAL'
  230.       BtIsrMode = BT_ISR_CL2;                   // Next state
  231.       break;
  232.     case BT_ISR_CL2 :
  233.       Disp_BCD_3_5(0x0b0f);                     // Display 'LO'
  234.       BtIsrMode = BT_ISR_CL1;                   // Next state
  235.       break;
  236.     case BT_ISR_CH1 :
  237.       Disp_BCD_3_5(0x0cdb);                     // Display 'CAL'
  238.       BtIsrMode = BT_ISR_CH2;                   // Next state
  239.       break;
  240.     case BT_ISR_CH2 :
  241.       Disp_BCD_3_5(0x0a1f);                     // Display 'HI'
  242.       BtIsrMode = BT_ISR_CH1;                   // Next state
  243.       break;
  244.   }
  245. }
  246. //------------------------------------------------------------------------------
  247. #pragma vector = PORT1_VECTOR
  248. __interrupt void PORT1_ISR(void)
  249. {
  250.   volatile unsigned int i;                      // 'volatile' to prevent opt.
  251.   
  252.   switch (P1IsrMode)
  253.   {
  254.     case P1_ISR_NRM :
  255.       if (P1IFG & 0x40)                         // Test for on P1.6 (on/off)
  256.       {
  257.         IE2 ^= BTIE;                            // Toggle Basic Timer interrupt
  258.         P6OUT ^= BRIDGE_H;                      // Toggle Bridge Supply Voltage
  259.         LCDCTL ^= LCDON;                        // Toggle LCD on/off
  260.         
  261.         if (LCDCTL & LCDON)
  262.         {
  263.           I2CWrite8(ADS1100_SA, ADS1100_8SPS + ADS1100_GAIN8);  // Start conversions
  264.           UpdateDisplay = 1;                    // Request display update
  265.         }
  266.         else
  267.         {
  268.           I2CWrite8(ADS1100_SA, ADS1100_SC);    // Disable conversions
  269.           IFG2 &= ~BTIFG;                       // Clear Basic Timer int flag
  270.         }
  271.       }
  272.       if (P1IFG & 0x80 &&  LCDCTL & LCDON)      // Test for on P1.7 (calibration)
  273.       {
  274.         P1IsrMode = P1_ISR_CL;                  // Enter calibration mode (low)
  275.         BtIsrMode = BT_ISR_CL1;
  276.       }
  277.       break;
  278.     case P1_ISR_CL :
  279.       if (P1IFG & 0xc0)                         // Test for P1.6/P1.7
  280.       {
  281.         CalMinTmp = I2CRead16(ADS1100_SA);      // Get 16-bit conversion result
  282.         P1IsrMode = P1_ISR_CH;
  283.         BtIsrMode = BT_ISR_CH1;                 // Enter calibration mode (high)
  284.       }
  285.       break;
  286.     case P1_ISR_CH :
  287.       if (P1IFG & 0xc0)                         // Test for P1.6/P1.7
  288.       {
  289.         CalMaxTmp = I2CRead16(ADS1100_SA);      // Get 16-bit conversion result
  290.         if (CalMinTmp == CalMaxTmp)             // Are calibr constants OK?
  291.         {
  292.           P1IsrMode = P1_ISR_CL;                // No,
  293.           BtIsrMode = BT_ISR_CL1;               // enter calibration mode (low)
  294.         }
  295.         else                                    // Calibration OK
  296.         {
  297.           StoreCalInFlash();                    // Yes, program constants and
  298.           P1IsrMode = P1_ISR_NRM;               // enter normal mode
  299.           BtIsrMode = BT_ISR_NRM;
  300.           UpdateDisplay = 1;                    // Request display update
  301.         }
  302.       }
  303.       break;
  304.   }
  305.   
  306.   for (i = 0x7fff; i; i--);                     // Delay for key-debounce
  307.   P1IFG = 0x00;                                 // Clear all P1 int flags
  308. }


您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2841

主题

19330

帖子

110

粉丝
快速回复 在线客服 返回列表 返回顶部