📄 f42x_weigh_scale.c
字号:
//------------------------------------------------------------------------------
// MSP430F42x Single Chip Weigh Scale - C Language Version
//
// Description: Program reads out the MSP430 SD16 Sigma-Delta ADC channel 0.
// The differential input voltage is displayed as a signed number on a 7.5 digit
// LCD. The displayed value is calculated using a 2-point calibration mechanism.
// During initial power-up (with INFOA Flash memory erased), two calibration
// data points are obtained (CalMin and CalMax) and stored into Flash memory.
// The range of CalMin to CalMax is projected during measurement mode into a
// display-value from 0 to CAL_MIN_MAX_SPAN. A button connected to P1.0 is
// used to enter low-power mode (short press) and re-calibrate the
// system (long press). An external 32-kHz watch crystal is used for FLL
// stabilization, time interval generation and for driving the LCD.
//
//
// MSP430F427
// +---------------+
// | | +----------------------+
// IN+ o---|A0+ S0-S23|--->| SoftBaugh SBLCDA4 |
// IN- o---|A0- COM0-COM3|--->| 7.1 Digit,4-Mux LCD |
// VBridge o--+|P2.0 | +----------------------+
// +|P2.1 |
// o---|VRef R03-R33|<---LCD Voltage Ladder Rs
// | |
// | XIN/XOUT|<---32.768KHz Watch Crystal
// | P1.0|<---Button (low-active)
// +---------------+
//
// Andreas Dannenberg
// Texas Instruments Inc.
// September 2004
// Built with IAR Embedded Workbench Version: 3.20A
//------------------------------------------------------------------------------
#include "msp430x42x.h"
#define CAL_MIN_MAX_SPAN 10000 // Scale value for CalMin/CalMax
// 10,000 Counts=10kg=10,000g
// Circuit related definitions
#define BRIDGE_SUPPLY (0x03) // IO pins P2.0/P2.1 for
// pos. bridge rail
#define PUSH_BUTTON (0x01) // Button on pin P1.0
// Get a 18-bit wide result from SD16 channel 0 (17 bit + sign bit)
#define GET_RESULT(var) SD16CCTL0 &= ~SD16LSBACC; \
var = (long)(int)SD16MEM0 << 2; \
SD16CCTL0 |= SD16LSBACC; \
var |= ((int)SD16MEM0 & 0xc0) >> 6
enum
{
PM_MEASURE, // Program Mode - Normal
PM_CAL_LO, // Program Mode - Cal Low
PM_CAL_HI, // Program Mode - Cal High
PM_PWRDOWN // Program Mode - Powered Down
};
// LCD segment definitions.
#define e 0x40 // AAAA
#define g 0x20 // F B
#define f 0x10 // F B
#define d 0x08 // GGGG
#define c 0x04 // E C
#define b 0x02 // E C
#define a 0x01 // DDDD
const char LCD_Tab[] = {
a + b + c + d + e + f, // Displays "0"
b + c, // Displays "1"
a + b + d + e + g, // Displays "2"
a + b + c + d + g, // Displays "3"
b + c + f + g, // Displays "4"
a + c + d + f +g, // Displays "5"
a + c + d + e + f + g, // Displays "6"
a + b + c, // Displays "7"
a + b + c + d + e + f + g, // Displays "8"
a + b + c + d + f + g, // Displays "9"
a + b + c + e + f + g, // Displays "A"
b + c + e + f + g, // Displays "H"
a + d + e + f, // Displays "C"
d + e + f, // Displays "L"
0x00, // Displays Blank
0x00 // Displays Blank
};
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g
// Global vars
static unsigned int VoltageSettleCtr; // Used as voltage settle ctr.
static unsigned int SD16TempCtr; // Number of resuts collected
static long SD16Temp; // Temp sum register
static long SD16Result; // Final averaged result
static long LastADCValue; // Last averaged result
static unsigned int ProgramMode; // Current program mode
static long CalMinTmp; // Temp vars to hold
static long CalMaxTmp; // calibration values
static char ButtonDownCtr; // Keeps track of button press
// duration
#define FLAG_UPDATE_DISPL 0x01 // Bit definitions used for
#define FLAG_BUTTON_DOWN 0x02 // flag register
static char Flags = FLAG_UPDATE_DISPL; // Flag register
#pragma dataseg = INFOA // Info Flash Memory Block A
__no_init static long CalMin;
__no_init static long CalMax;
#pragma dataseg = default
// Function prototypes
void Init_Sys(void);
void StartNextConversion(void);
void StoreCalInFlash(void);
void Disp_Signed_Long(long Value);
void Disp_BCD(unsigned long Value);
//------------------------------------------------------------------------------
void main(void)
{
Init_Sys();
if (CalMin == CalMax) // Are constants in Flash OK?
{
Disp_BCD(0xfcadfd0); // Display 'CAL LO'
ProgramMode = PM_CAL_LO; // Enter calibration mode
}
else
{
ProgramMode = PM_MEASURE; // Enter measurement mode
}
StartNextConversion(); // Start conversions
__bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ ints enabled
}
//------------------------------------------------------------------------------
void Init_Sys(void)
{
int i;
char *pLCD = (char *)&LCDM1;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
FLL_CTL0 |= XCAP18PF; // Set load capacitance for xtal
for (i = 0; i < 20; i++) // Clear LCD memory
*pLCD++ = 0;
LCDCTL = LCDSG0_3 + LCD4MUX + LCDON; // 4mux LCD, segs0-23
BTCTL = BT_fLCD_DIV128+BTDIV+BT_fCLK2_DIV64; // 0.5s BT Int, Set LCD freq
IE2 |= BTIE; // Enable Basic Timer interrupt
P1OUT = 0xff; // P1OUTs = 1
P1DIR = 0xff & ~PUSH_BUTTON; // All pins but button to output
P1IES = PUSH_BUTTON; // Button int on falling edge
P1IFG = 0;
P1IE = PUSH_BUTTON; // Enable button interrupt
P2OUT = 0xff; // P2OUTs = 1
P2DIR = 0xff; // All pins outputs
SD16INCTL0 = SD16GAIN_32 + SD16INCH_0; // 32x gain, channel pair A0
SD16CCTL0 = SD16DF + SD16IE; // Continuous conv., 2s compl.
}
//------------------------------------------------------------------------------
// Programs the calibration constants CalMinTmp and CalMaxTmp into Flash
// info memory segment A using in-system self programming techniques
//------------------------------------------------------------------------------
void StoreCalInFlash(void)
{
FCTL2 = FWKEY + FSSEL1 + FN1; // SMCLK/3 = ~333kHz
FCTL3 = FWKEY; // Clear LOCK
FCTL1 = FWKEY + ERASE; // Enable segment erase
*(unsigned int *)0x1080 = 0; // Dummy write, erase info A
FCTL1 = FWKEY + WRT; // Enable write
CalMin = CalMinTmp; // Program calibration constants
CalMax = CalMaxTmp;
FCTL1 = FWKEY; // Done. Clear WRT
FCTL3 = FWKEY + LOCK; // Done. Set LOCK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -