📄 main.c
字号:
/** \file
* ESP430CE1 Application Program Example
*
* This file shows exemplarily the usage of the ESP430CE1 module for
* a single-phase emeter with two current sensors (one shunt and one
* current transformer).
*
* \author Volker Rzehak
* \date 04/08/2003
*
* \Modified Stefan Schauer
* \date 04/29/2003
*/
//====================================================================
#include "parameter.h"
#include "device.h"
#include "comms_uart.h"
#include "subroutines.h"
#include "uart0.h"
#include "SendData.h"
#include "fet4xx_rtclcd.h"
#include "display.h"
#include "emeter.h"
#include <stdio.h>
#include <string.h> // Needed for strlen(), strcpy(), and strcmp()
#include <stdlib.h> // Needed for atoi()
#include <math.h>
#if defined(__CROSSWORKS__)
// #include <In430.h>
#include <__cross_studio_io.h>
#endif
// const and var definition
const char banner[]="MSP430FE427 ";
const unsigned int sbanner = 14;
const char TempBanner[]="\rTemp: ";
unsigned int OP_Mode = idle; // operation mode
// forward declarations
unsigned int sys_status = 0; // System status bits
unsigned long software_version;
//====================================================================
long GetVersion(void)
{
const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug",
"Sep", "Oct", "Nov", "Dec"};
char temp[12];
float fver;
int year;
int month;
int day;
int hour;
int minute;
int second;
int i;
strcpy(temp, __DATE__);
year = atoi(temp + 9);
*(temp + 6) = 0;
day = atoi(temp + 4);
*(temp + 3) = 0;
for (i = 0; i < 12; i++)
{
if (!strcmp(temp, months[i]))
{
month = i + 1;
break;
}
}
strcpy(temp, __TIME__);
second = atoi(temp+6);
*(temp + 5) = 0;
minute = atoi(temp + 4);
*(temp + 3) = 0;
hour = atoi(temp);
fver = (year*31*12) + ((month-1)*31) + day + ((hour*60.0) + minute)/(24.0*60.0);
return((long)(fver*1000));
}
#define VLD_OFF 0 // Off
#define VLD_LO 7 // 2.65V
//#define VLD_HI 8 // 2.8V
#define VLD_HI 9 // 2.9V
void SetSVSLevel(int level)
{
SVSCTL = (SVSCTL & ~(15*VLDON)) | (level*VLDON);
}
//====================================================================
// Init Digital Hardware
void init_system(void)
{
P1OUT = 0x03;
P2OUT = 0x00;
// ----- Port Selection: 0= GPIO, 1= Peripheral Function -----
P1SEL = (0<<0) // P1.0 = GP output to User0 LED
|(0<<1) // P1.1 = GP output to User1 LED
|(1<<2) // P1.2 = LCD driver S31
|(1<<3) // P1.3 = LCD driver S30
|(1<<4) // P1.4 = LCD driver S29
|(1<<5) // P1.5 = LCD driver S28
|(1<<6) // P1.6 = LCD driver S27
|(1<<7); // P1.7 = LCD driver S26
// ----- Port Direction: 0= Input, 1 = Output -----
P1DIR = (1<<0) // P1.0 = GP output to User0 LED
|(1<<1) // P1.1 = GP output to User1 LED
|(1<<2) // P1.2 = LCD driver S31
|(1<<3) // P1.3 = LCD driver S30
|(1<<4) // P1.4 = LCD driver S29
|(1<<5) // P1.5 = LCD driver S28
|(1<<6) // P1.6 = LCD driver S27
|(1<<7); // P1.7 = LCD driver S26
#ifdef withRS485
// ----- Port Selection: 0= GPIO, 1= Peripheral Function -----
P2SEL = (1<<0) // P2.0 = LCD driver S25
|(1<<1) // P2.1 = LCD driver S24
|(0<<2) // P2.2 = GP output to RS485 DE
|(0<<3) // P2.3 = GP output to RS485 ~RE
|(1<<4) // P2.4 = UART TXD0
|(1<<5) // P2.5 = UART RXD0
|(0<<6) // P2.6 n/a
|(0<<7); // P2.7 n/a
// ----- Port Direction: 0= Input, 1 = Output -----
P2DIR = (1<<0) // P2.0 = output to LCD
|(1<<1) // P2.1 = output to LCD
|(1<<2) // P2.2 = output to RS485 DE
|(1<<3) // P2.3 = output to RS485 ~RE
|(1<<4) // P2.4 = output UART TXD0
|(0<<5) // P2.5 = input UART RXD0
|(0<<6) // P2.6 n/a
|(0<<7); // P2.7 n/a
SelectRS485Direction(RS485_DISABLE); //Set P2.2 & P2.3 to disable the RS-485 driver for power savings
#else
// ----- Port Selection: 0= GPIO, 1= Peripheral Function -----
P2SEL = (1<<0) // P2.0 = LCD driver S25
|(1<<1) // P2.1 = LCD driver S24
|(0<<2) // P2.2 = GP input from push-button S1
|(0<<3) // P2.3 = GP input from push-button S2
|(1<<4) // P2.4 = UART TXD0
|(1<<5) // P2.5 = UART RXD0
|(0<<6) // P2.6 n/a
|(0<<7); // P2.7 n/a
// ----- Port Direction: 0= Input, 1 = Output -----
P2DIR = (1<<0) // P2.0 = output to LCD
|(1<<1) // P2.1 = output to LCD
|(0<<2) // P2.2 = input from push-button S1
|(0<<3) // P2.3 = input from push-button S2
|(1<<4) // P2.4 = output UART TXD0
|(0<<5) // P2.5 = input UART RXD0
|(0<<6) // P2.6 n/a
|(0<<7); // P2.7 n/a
#endif
P1IE = 0x00; // Disable Port 1 interrupts
P2IE = 0x00; // Disable Port 2 interrupts
P1IFG = 0x00; // Clear Port 1 interrupt Flags
P2IFG = 0x00; // Clear Port 2 interrupt Flags
FCTL2 = FWKEY | FSSEL_1 | defFlashFreq; // Configure Flash Timing Generator
SVSCTL = (VLD_LO*VLDON) // 7-4 Voltage Level Detect
// (7 * VLDON) // 7-4 Voltage Level Detect 7 = 2.65V
// (8 * VLDON) // 7-4 Voltage Level Detect 8 = 2.8V
// (9 * VLDON) // 7-4 Voltage Level Detect 9 = 2.9V
|(0 * PORON) // 3 0= Do not cause a POR
|(0 * SVSON) // 2 SVS On Status (Read Only)
|(0 * SVSOP) // 1 SVS Comparator Output (Read Only)
|(0 * SVSFG); // 0 SVS Flag Writing 0 clears any previous events
#ifdef withDisplay
#if (LCD_SIZE == 7)
LCDCTL = LCDON + LCD4MUX + LCDP2 + LCDP1+ LCDP0; // Enable 7-segment LCD
#else
LCDCTL = LCDON + LCD4MUX + LCDP2 + LCDP0; // Enable 6-segment LCD
#endif
BTCTL = BTHOLD + BTFRFQ1; // f(LCD) = ACLK / 256 = 128 Hz
#ifdef LCD_TEST_PATTERN
DisplayTest();
#endif
#ifndef FLASH_LOADER
// Wait for about 5 seconds to let voltage stabilize
// Display banner and version information while waiting
#define DISPLAY_VERSION 1
#if DISPLAY_VERSION == 1
{
long k;
int L;
int i = LCD_SIZE-1;
char msg[32];
LCDtext ((unsigned char *) banner, 6, 6);
for (k=0; k<300000; k++){ _NOP();} // Wait a little
LCDtext ((unsigned char *) "Version", 7, 7);
for (k=0; k<200000; k++){ _NOP();} // Wait a little
LCDdecu32(software_version, 7, 7, 3);
for (k=0; k<500000; k++){ _NOP();} // Wait a little
}
#else
{
long k;
LCDtext ((unsigned char *) banner, 6, 6);
for (k=0; k<3000000; k++){ _NOP();} // Wait a little
}
#endif
DisplayClear();
#endif // FLASH_LOADER
#endif // withDisplay
}
void __low_level_init(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
// P1OUT ^= 0x01;
// P1DIR |= 0x01; // P1.0 toggle on each reset
}
//====================================================================
// Wait in low-power mode. Handle interrupts as they occur.
#ifndef FLASH_LOADER
void WaitLPM(void)
{
#ifdef withUARTComm
// --- Look at the Supply Voltage Supervisor to see if we are on battery backup
if((SVSCTL & SVSOP) != 0)
{ // Supply Voltage is Low. We are on battery backup. Switch to power-savings modes.
// LCDM16 |= 0xF0; // Turn on all unused segments of LCD
SetSVSLevel(VLD_HI); // Switch voltage threshold to higher level to prevent excessive
// switching between power-saving modes.
#ifdef withRS485
SelectRS485Direction(RS485_DISABLE); // Set P2.2 & P2.3 to disable the RS-485 driver for power savings
#endif
idle_esp(); // Set Embedded Signal Processor into Idle Mode.
LPM2; // Switch MSP430 into Low Power Mode 2
// LPM3; // Switch MSP430 into Low Power Mode 3
_NOP();
}
else
{ // Supply Voltage is good. Do normal operations.
#ifdef withRS485
SelectRS485Direction(RS485_LISTEN); // Set P2.2 & P2.3 to enbable the RS-485 receive
#endif
if ( OP_Mode == idle) // if first sample after waking up from battery operation
{
SetSVSLevel(VLD_LO); // Switch voltage threshold to lower level to prevent excessive
// switching between power-saving modes.
wakeup_esp(); // Take ESP out of suspend mode and turn on analog voltage reference
init_analog_front_end();// Init. analog front-end (sigma-delta ADC)
init_esp_parameter(1); // Init. Embedded Signal Processing parameters
start_measurement(); // Start taking power measurements again.
}
if((UART_Status & LineReceived) != 0)
{
Process_UART(); // process UART receive
UART_Status &= ~LineReceived; // clear flag
if ( OP_Mode == request_cal)
{
TX_Mode = tx_off;
start_calibration();
}
else
{
if ( OP_Mode == done) start_measurement();
}
}
else if ((TX_Mode >= tx_ch1) && (TX_Mode <= tx_ch3))
{
sys_status |= NewValues;
}
else
{
_NOP();
LPM0; // switch MSP430 into Low Power Mode 0
_NOP();
}
// process UART send
if((sys_status & NewValues) != 0)
{
sys_status &= ~NewValues;
SendData();
}
}
#else
LPM0; // switch MSP430 into Low Power Mode 0
_NOP();
#endif // withUARTComm
#ifdef withDisplay
DisplayData();
#endif // withDisplay
}
#else // FLASH_LOADER
void WaitLPM(void)
{
// process UART receive
if((UART_Status & LineReceived) != 0)
{
Process_UART();
UART_Status &= ~LineReceived; // clear flag
}
else
{
_NOP();
LPM0; // switch MSP430 into Low Power Mode 0
_NOP();
}
}
#endif
#ifdef FLASH_LOADER
//====================================================================
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
// Init. FLL and clocks
init_fll(10, defSystemFreq, 32);
// Init Digital Hardware
init_system();
InitUART(115200);
SelectRS485Direction(RS485_LISTEN); // Set P2.2 & P2.3 to listen to serial input
DisplayClear();
LCDtext ((unsigned char *) "LOADING", 7, 7);
//
// SetupClock(); // Init Real-Time Clock
//
_EINT(); // Enable Interrupts
while (1)
{
WaitLPM(); // Wait in low-power mode. Return after interrupt
} // End of while (1)
} // End of main()
#else // Normal User Code (FLASH_LOADER not defined)
//====================================================================
void main (void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
// Init. FLL and clocks
init_fll(10, defSystemFreq, 32);
software_version = GetVersion();
// Init Digital Hardware
init_system();
// Init. UART and set baud rate
#ifdef withUARTComm
// InitUART(9600);
// InitUART(57600);
InitUART(115200);
TX_Mode = tx_off;
if((SVSCTL & SVSOP) != 0) // --- Look at the Supply Voltage Supervisor
{ // Supply Voltage is Low. We are on battery backup. Switch to power-savings modes.
#ifdef withRS485
SelectRS485Direction(RS485_DISABLE); // Set P2.2 & P2.3 to disable the RS-485 driver for power savings
#endif
}
else
{ // Supply Voltage is good. Do normal operations.
SelectRS485Direction(RS485_LISTEN); // Set P2.2 & P2.3 to listen to serial input
LCDtext ((unsigned char *) banner, 6, 6);
#ifndef SUPRESS_WAKEUP_STRING
SendString("\r\r");
SendString(banner);
SendChar('\r');
SendString("ESP Firmware Version: ");
SendResult((unsigned char*) &firmware_version, 2);
SendChar('\r');
SendString("MSP Software Version: ");
SendFloat(software_version, 3);
SendChar('\r');
SendChar('\n');
SendChar('\r');
#endif
}
#endif // withUARTComm
SetupClock(); // Init Real-Time Clock
_DINT(); // Disable Interrupts
if((SVSCTL & SVSOP) == 0) // --- Look at the Supply Voltage Supervisor
{ // Supply Voltage is good. Do normal operations.
// Wake up the ESP
init_analog_front_end();// Init. analog front-end (sigma-delta ADC)
init_esp_parameter(1); // Init. Embedded Signal Processing parameters
start_measurement() ; // Init. event generation and start measurement
}
DisplayClear();
Display_Mode = 2; // Display time first
_EINT(); // Enable Interrupts
while (1)
{
WaitLPM(); // Wait in low-power mode. Return after interrupt
} // End of while (1)
} // End of main()
#endif // FLASH_LOADER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -