📄 msp430dayii_democ.c
字号:
//******************************************************************************
// 430Day 2004 watch.c - Multi-function demo with Clock & Temperature
//
// MSP430FG43x
//
// +-----------------+
// /|\| XIN|-
// | | | 32KHz
// --|RST XOUT|-
// | |
// | P1.0|-->LED
// | |
// | P2.1|-->Switch 1
// | P2.2|-->Switch 2
// | | ____________
// | S0..S21|--------|SBLCDA4 |
// | COM0..COM3|--------|4-Mux LCD |
// | | |____________|
// | |
// +-----------------+
//
// Usage: (Switch 1) Display temp
// (Switch 2) Change unit mode
// (Holding Switch 1, press Switch 2) increment minutes
// (Holding Switch 2, press Switch 1) increment hours
// (Holding Switch 2) enters temperature calibration mode after 5 seconds
// Calibration mode:
// (Switch 1) decrease temperature
// (Switch 2) increase temperature
// (Holding Switch 2 and Switch 1) set temperature and return to RTC
// (Switch 1 pressed twice) turn off LCD
//
// M. Raju
// L. Westlund
// Z. Albus
// Texas Instruments, Inc
// April, 30, 2004
// Built with IAR Embedded Workbench Version: 2.21B
//
// Temperature compensation changes by Hugh Molesworth
//
//******************************************************************************
#include <msp430x43x.h>
#include "RtcTempCompensation.h"
#define PB_TEMP (1 << 1) // Push Button 1, Temperature: P2.1
#define PB_ALT (1 << 2) // Push Button 2, Alternate: P2.2
#define TEMP_COMPENSATION 16802 / 4096
typedef unsigned int word; // Type definition for 'word'
enum
{
ENGLISH,
METRIC
};
static char *LCD = LCDMEM;
static int MODE_TIME = 5;
static int LCD_OFF_TIME = 5;
static int Refcal_ram = 1500; // ADC12 1.5V reference calibration variable
static int Temp_slope_ram = 761; // Temperature slope calibration variable
static int Temp_offset_ram = 469; // Temperature offset calibration variable
int unitMode = ENGLISH; // The current state for measurements (metric/english)
unsigned char seconds = 0, minutes = 0, hours = 0x12; // The default time values
int tempModeTime; // The number of seconds left to display the temperature
int lcdOffModeTime; // The number of seconds left to have the LCD off
int twoButtonsPressed; // The amount of time both buttons were pressed
signed int tempF; // Temperature variable
int held_down = 0;
void displayTime( void ); // Displays time
void displayValue( int value, int stop );// Displays an int value on the LCD. Value can be moved in memory using the stop variable (in order to append metric characters to an int value)
void clearLCD(void); // Clears the LCD memory
void init(void); // Increments the hours variable (and rolls over to 12 if needed)
void decMinutes(void);
void incMinutes(void);
void incHours(void);
void displayTemp(void); // Gets the current temperature and displays it on the LCD
void changeUnitMode(void); // Changes the units of measurement from English to Metric
void calibrate(void); // Calibrates the temperature
void getTemp(void); // Gets the current temperature
void flashLCD(void);
void flash_write(word* address, int data);// Write the (integer) data to the addressed flash
void flash_erase(word* address); // Erase the addressed flash segment
//added the following SIX lines to declare variables in Flash INFO memory for IAR 2.x
#pragma dataseg=INFOA
__no_init static word Refcal_flash; // ADC12 reference calibration in Flash INFO memory
__no_init static word Temp_slope; // Temperature sensor slope calibration in Flash INFO memory
__no_init static word Temp_offset; // Temperature sensor offset calibration in Flash INFO memory
#pragma dataseg=default
// LCD segment definitions.
#define d 0x80
#define c 0x40
#define b 0x20
#define a 0x10
#define h 0x08
#define e 0x04
#define g 0x02
#define f 0x01
const char char_gen[] = {
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"
0x00, // Displays Blank
a+d+e+f, // Displays "C"
a+b+f+g, // Displays "degrees" o
a+d+e+f+g, // Displays "E"
a+e+f+g, // Displays "F"
h, // Displays ":" or "."
g, // Displays "-"
f+g+e+d // Displays "t"
};
#undef a
#undef b
#undef c
#undef d
#undef e
#undef f
#undef g
#undef h
void main(void)
{
init();
clearLCD();
while( 1 )
{
LPM3; // Wait in LPM3 for the 1 second timer interrupt
#if defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
// Once per second check to see if it's time to do the compensation correction
UpdateCorrection();
#endif
if( tempModeTime > 0 ) // Called if tempMode is the highest non-zero mode (temp was the most recent pushed)
{
LCDCTL |= LCDON;
getTemp();
if (tempF > 79)
P1OUT |= 0x01;
else
P1OUT &= ~0x01;
displayTemp();
tempModeTime--; // Decrement the temp time counter (once a second)
}
else if( (~P2IN & (PB_ALT)) ) // if alt button held
{
P1OUT &= ~0x01;
held_down++;
if( held_down == 4 )
{
held_down = 0;
unitMode ^= 1; // Toggle between 1 and 0
calibrate();
}
}
else // Default, display the time
{
P1OUT &= ~0x01;
if(lcdOffModeTime == 0)
{
LCDCTL |= LCDON;
displayTime();
twoButtonsPressed = 0;
}
else{
lcdOffModeTime--;
}
}
}
}
int __low_level_init(void)
{
FLL_CTL0 |= XCAP18PF; // Set load capacitance for xtal
WDTCTL = WDTPW + WDTHOLD; // Disable the Watchdog
while(FLL_CTL0 & LFOF); // Wait until LF OSC stabilizes
return (1); // Flag to initialize the data segment
}
void init( void )
{
P1OUT = 0x00; // P1.0 = LED
P1DIR = 0xFF;
P2OUT = 0x00;
P2DIR = 0xF9;
P3OUT = 0x00;
P3DIR = 0xFF;
P6OUT = 0x00;
P6DIR = 0xFF;
LCDCTL = LCDON + LCDSG0_3 + LCD4MUX; // 4mux LCD, segs0-15 = outputs
BTCTL = BT_fLCD_DIV128 + BTDIV + BTIP2 + BTIP1;// Set LCD frame freq = ACLK/128, set interrupt interval
IE2 |= BTIE; // Enable Basic Timer interrupt
P5SEL = 0xFC; // Set Rxx and COM pins for LCD
clearLCD();
#if defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
// Initialize Timer_A-1 for 1 interrupt per second
InitialiseTimerA1();
#endif
P2DIR = ~(PB_TEMP + PB_ALT); // Set ports to input for temperature and alternate switches
P2IFG = 0; // Clear pending P2 interrupts
P2IES = PB_TEMP + PB_ALT; // Set interrupt to occur on high-to-low transition on switches
P2IE = PB_TEMP + PB_ALT; // Enable interrupts for switches
FCTL2 ^= FXKEY + FN2 + FN1 + FN0; // Set FLASH timing generator 447.5Khz
ADC12CTL1 = SHP; // Pulse mode select for ADC12
ADC12IE = BIT0; // Enable interrupts for ADC12
Refcal_ram = Refcal_flash; // Make RAM copy of Vref cal value
Temp_slope_ram = Temp_slope; // Make RAM copy of Temp slope value
Temp_offset_ram = Temp_offset; // Make RAM copy of Temp offset value
_EINT();
}
void flashLCD(void)
{
int i;
#if !defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
TACTL = TASSEL0 + TACLR + MC1; // TACLK = ACLK, 16-bit up-mode
#endif
for( i = 0; i < 20; i++)
{
LCD[i] = 0xff;
}
for( i = 0 ; i < 7; i++)
{
LCDCTL |= LCDSON;
CCR1 = 60000; // Delay
CCTL1 = CCIE; // Compare-mode interrupt
LPM3; // Wait for delay
}
}
void calibrate()
{
_DINT();
Refcal_ram = 1500; // Make RAM copy of Vref cal value
Temp_slope_ram = 761; // Make RAM copy of Temp slope value
Temp_offset_ram = 469; // Make RAM copy of Temp offset value
_EINT();
getTemp();
Temp_offset_ram += tempF - 75; // Make default temp 75 (user will be near there)
while( !((~P2IN & PB_TEMP) && (~P2IN & PB_ALT)))// Loop until user holds down both buttons
{
#if !defined (OPTION_USING_TEMPERATURE_COMPENSATION_FOR_RTC)
TACTL = TASSEL0 + TACLR + MC1; // TACLK = ACLK, 16-bit up-mode.
#endif
P2IE &= ~(PB_TEMP + PB_ALT); // disable interrupts for switches
if(~P2IN & PB_TEMP)
{
Temp_offset_ram++;
}
if(~P2IN & PB_ALT)
{
Temp_offset_ram--;
}
CCR1 = 10000; // Delay
CCTL1 = CCIE; // Compare-mode interrupt
LPM3; // Wait for delay
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -