加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

msp430芯片初探

发布时间:2020-12-15 07:11:50 所属栏目:百科 来源:网络整理
导读:N年前作的一个超级烂的msp430 并口仿真器,当时是msp430刚刚进入中国的时候做的,竟然让我在箱子里面翻了出来,我都佩服我自己了。 尽管仿真器看着烂,但是居然能用! 此外,在箱子里面找出了M年前参加msp430研讨会送的msp430f437手表,依稀还能看到“手表”

N年前作的一个超级烂的msp430 并口仿真器,当时是msp430刚刚进入中国的时候做的,竟然让我在箱子里面翻了出来,我都佩服我自己了。

尽管仿真器看着烂,但是居然能用!

此外,在箱子里面找出了M年前参加msp430研讨会送的msp430f437手表,依稀还能看到“手表”的风采。

其中手表的原理图如下:

手表的有关介绍如下:

Watch?Operation:

First?Startup:

When?initially?powered,?the?device?will?display?the?default?time:??12:00:00.??It?will?immediately?begin?counting?the?seconds.

Normal?Operation:

Setting?the?Time?(Minutes):??Press?and?hold?SW1,?pressing?SW2?now?increments?the?minute?value.??

Setting?the?Time?(Hours):??Press?and?hold?SW2,?pressing?SW1?now?increments?the?hour?value.?

Note:?When?pressing?SW2,?the?device?will?first?appear?to?change?the?unit?mode.??This?is?ignored?by?the?watch?after?SW1?is?pressed.

Displaying?the?Temperature:??Press?SW1,?watch?will?return?to?clock?mode?after?6?seconds

Changing?the?unit?Mode:??Press?and?hold?SW2

Switching?off?LCD:?Press?SW1?(to?enter?Temperature?mode)?Press?SW1?again.??The?LCD?will?turn?on?after?5?seconds.

Note:?while?LCD?is?off,?device?is?in?“low-power?clock”?mode?and?not?in?temperature?mode.

Erasing?Calibration?Values:??Press?and?hold?SW2?until?the?temperature?is?displayed.??While?temperature?is?displayed,?SW2?increases?the?displayed?value?and?SW1?decreases?the?displayed?value.??Holding?SW1?and?SW2?simultaneously?for?1?second?saves?the?calibrated?value.

Note?For?Instructors:??The?code?running?on?the?watch?boards?when?shipped?does?not?save?temperature?calibrations?between?power?offs.??The?C?file?available?on?the?web?does?include?this?function?as?well?as?displaying?1degree?F?to?indicate?being?un-calibrated.

?

标准msp430的JTAG接口如下:

编译程序安装的是IAR 4.201版本,选择里面的connection为softbaugh LPT(其他有关LPT的选项也是可以的)。

手上还有一个JLINK,赶明再尝试一下是否可以仿真。

付程序如下:

//******************************************************************************
//? 430Day 2004 watch.c - Multi-function demo with Clock & Temperature
//
//
//? Murugavel Raju
//? Lane Westlund
//? Texas Instruments,Inc
//? January,2004
//? Built with IAR Embedded Workbench Version: 2.21B
//? Modified by Albus 3/25/2004
//
//
//******************************************************************************

#include? <msp430x43x.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)
static 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( 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();
???
? 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;
? TACTL = TASSEL0 + TACLR + MC1;??????? // TACLK = ACLK,16-bit up-mode
? 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
? {
???
??? TACTL = TASSEL0 + TACLR + MC1;????? // TACLK = ACLK,16-bit up-mode.
??? 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
???????
??? getTemp();
??? displayTemp();
? }
? while( (~P2IN & PB_TEMP) && (~P2IN & PB_ALT) ); // pause until user stops holding down buttons
? tempModeTime = 0;
? P2IFG = 0;
? P2IE |= PB_TEMP + PB_ALT;?????????? // Enable interrupts for switches
?
? flash_erase((void *)&Refcal_flash);?? // Erase Flash INFO segment A
? flash_write((void *)&Refcal_flash,Refcal_ram);// Write cal data to Refcal
? flash_write((void *)&Temp_offset,Temp_offset_ram);// Write offset data
? flash_write((void *)&Temp_slope,Temp_slope_ram);// Write slope data
?
? _EINT();????????????????????????????? // Re-enable general interrupts
?
? 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

}

void getTemp(void)
{
? ADC12CTL0 &= ~ENC;??????????????????? // Clear ENC first
? ADC12CTL0 = SHT0_15 + REFON + ADC12ON;
? ADC12MCTL0 = INCH_10 + SREF_1;??????? // Sample channel 10 using internal reference
? TACTL = TASSEL0 + TACLR + MC1;??????? // TACLK = ACLK,16-bit up-mode
? CCR1 = 1500;????????????????????????? // Delay to allow Ref to settle
? CCTL1 = CCIE;???????????????????????? // Compare-mode interrupt
? LPM3;???????????????????????????????? // Wait for delay
? ADC12CTL0 |= ENC + ADC12SC;?????????? // Start conversion
? LPM3;???????????????????????????????? // Wait for conversion completion
? ADC12CTL0 &= ~ENC;??????????????????? // Clear ENC first
? ADC12CTL0 = 0;??????????????????????? // Turn-off ADC12
???
? tempF = (((long) ADC12MEM0 * Temp_slope_ram) / 4096 - Temp_offset_ram);
}

void displayTemp(void)
{
? clearLCD();
?
? if( unitMode == ENGLISH )
? {
??? displayValue(tempF,2);
??? LCDM7 = char_gen[15];?????????????? // Display "F'
??? LCDM6 = char_gen[13];?????????????? // Display degree
? }
? else
? {
??? tempF -= 32;
??? tempF *= .5555;???????????????????? // 5/9
???????
??? displayValue(tempF,2);
??? LCDM7 = char_gen[12];?????????????? // Display "C"
??? LCDM6 = char_gen[13];?????????????? // Display degree
? }
}

void displayTime(void)
{
? LCDM7 = 0;
???
? LCDM6 = char_gen[seconds&0x0f];
? LCDM5 = char_gen[(seconds>>4)&0x0f]+char_gen[16];
???
? LCDM4 = char_gen[minutes&0x0f];
? LCDM3 = char_gen[(minutes>>4)&0x0f]+char_gen[16];
???
? LCDM2 = char_gen[hours&0x0f];
? if( hours & 0x10 )
? {
??? LCDM1 = char_gen[1];
? }
? else
? {
??? LCDM1 = 0;
? }
}

void displayValue( int value,int stop )
{
? int i;
? int sign = 0;
? if( value < 0 )
? {
??? value = ~value +1;
??? sign = 1;
? }
? i = 6-stop;
? while( value > 9 )
? {
??? LCD[i] = char_gen[value%10];
??? value = value/10;
??? i--;
? }
? LCD[i] = char_gen[value];
? if( sign )
? {
??? LCD[i-1] = char_gen[17];
? }
}

void incHours (void)
{???
? hours = __bcd_add_short(hours,0x01);
?
? if (hours == 0x13)
??? hours = 0x01;?????????????????????? // If hrs transition is 12 to 13,hrs = 1

}

void incMinutes(void)
{???
? minutes = __bcd_add_short(minutes,0x01);
? if (minutes == 0x60)
? {
??? minutes = 0;
??? incHours();
? }?
}

void decMinutes(void)
{
? if( (--minutes & 0x0f) == 0x0f )
? {
??? minutes = (minutes & 0xf0)+0x09;
??? if( minutes == 0xf9 )
??? {
????? minutes = 0x59;
????? if( --hours == 0x00)
????? {
??????? hours = 0x12;
????? }
????? else if( hours == 0x0f )
????? {
??????? hours = 0x09;
????? }
??? }
? }

}


void clearLCD(void)
{
? int i;
? for( i = 0; i < 20; i++ ){
??? LCD[i] = 0;
? }
}

void changeUnitMode(void)
{

? unitMode ^= 1;??????????????????????? // Toggle between 1 and 0
? clearLCD();
? if(unitMode == METRIC)
? {
??? LCDM7 = char_gen[12];?????????????? // Display degrees C for indication
??? LCDM6 = char_gen[13];
? }
? else
? {
??? LCDM7 = char_gen[15];?????????????? // Display degrees F for indication
??? LCDM6 = char_gen[13];
? }
}


void flash_write(word* address,int data)// Write the (integer) data to the addressed flash
{
? word gie = _BIC_SR(GIE) & GIE;??????? // Disable interrupts

? FCTL3 = FWKEY;??????????????????????? // Unlock the flash
? FCTL1 = FWKEY + WRT;????????????????? // Enable flash write
? *address = data;????????????????????? // Write the data to the flash
? FCTL1 = FWKEY;??????????????????????? // Disable flash write
? FCTL3 = FWKEY + LOCK;???????????????? // Lock the flash
? _BIS_SR(gie);???????????????????????? // Restore interrupts (to previous state)
}

void flash_erase(word* address)???????? // Erase the addressed flash segment
{
? word gie = _BIC_SR(GIE) & GIE;??????? // Disable interrupts
?
? FCTL3 = FWKEY;??????????????????????? // Unlock the flash
? FCTL1 = FWKEY + ERASE;??????????????? // Enable flash segment erase
? *address = 0;???????????????????????? // Erase the flash segment
? FCTL1 = FWKEY;??????????????????????? // Disable flash segment erase
? FCTL3 = FWKEY + LOCK;???????????????? // Lock the flash
? _BIS_SR(gie);???????????????????????? // Restore interrupts (to previous state)
}

// Basic Timer interrupt service routine
#pragma vector=BASICTIMER_VECTOR
__interrupt void bt_isr(void)
{
? seconds = __bcd_add_short(seconds,0x01);
? if( seconds == 0x60 )
? {
??? seconds = 0;
??? minutes = __bcd_add_short(minutes,0x01);
??? if( minutes == 0x60 )
??? {
????? minutes = 0;
????? hours = __bcd_add_short(hours,0x01);
????? if( hours == 0x13 )
????? {
??????? hours = 0x01;
????? }
??? }
? }

? LPM3_EXIT;??????????????????????????? // Exit LPM3 mode on return
}


#pragma vector=PORT2_VECTOR
__interrupt void p2_isr(void)
{ unsigned volatile int i;

? for (i = 0x3000; i>0 ; i--);????????? //Debounce
?
? if( (~P2IN & PB_TEMP)&&(P2IFG&PB_ALT) )//If temp button held,and alt button pressed...
? {
??? incMinutes();
??? tempModeTime = 0;
??? displayTime();
??? P1OUT &= ~0x01;
? }
? else if( (~P2IN & PB_ALT)&&(P2IFG&PB_TEMP) )//If alt button held,and temp button pressed...
? {

??? unitMode ^= 1;????????????????????? // Toggle between 1 and 0
??? incHours();
??? displayTime();
??? tempModeTime = 0;
??? P1OUT &= ~0x01;
??? held_down = 0;
? }
? else if ( tempModeTime > 0 && P2IFG & PB_TEMP ){
??? LCDCTL &= ~LCDON;
??? lcdOffModeTime = LCD_OFF_TIME;
??? tempModeTime = 0;
? }
? else if( P2IFG & PB_TEMP )??????????? // If temp button pressed,start displaying temp
? {????????
??? tempModeTime = MODE_TIME;
? }
?
? else if ( P2IFG & PB_ALT )??????????? // If alt button pressed,toggle degrees C & F
? {???????
??? changeUnitMode();
? }
?
? P2IFG = 0;
}

#pragma vector=ADC_VECTOR
__interrupt void adc_isr(void)
{
? ADC12IFG &= ~BIT0;??????????????????? // Clear MEM0 interrupt flag
? LPM3_EXIT;??????????????????????????? // The ADC value is available in ADC12MEM0
}

enum
{
? NO_INT = 0,
? CC1_INT = 2,
? CC2_INT = 4,
? TA_INT = 10
};

#pragma vector=TIMERA1_VECTOR __interrupt void ta1_isr(void) { ? switch (TAIV) ? { ??? case NO_INT: break; ??? case CC1_INT: TACTL = 0; break;???? // Disable TimerA ??? case CC2_INT: break; ??? case TA_INT: break; ??? default: break; ? } ? LPM3_EXIT;??????????????????????????? // Exit LPM3 on return }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读