Langage C avec le msp430, sous linux
Ici on va voir que l'on peut se passer de l'assembleur !! mais non
nous allons faire du développement croisé.
c'est a dire créer un code exécuté pour un processeur différent de celui qui le réalise (compilation/assemblage) .
Ici on va développer avec un PC pour un msp430
liste des utilitaires pour le msp430.
msp430-addr2line msp430-elfedit msp430-ld msp430-ranlib
msp430-ar msp430-g++ msp430-ld.bfd msp430-readelf
msp430-as msp430-gcc msp430mcu-config msp430-size
msp430-c++ msp430-gcc-4.6.3 msp430-nm msp430-strings
msp430-c++filt msp430-gcov msp430-objcopy msp430-strip
msp430-cpp msp430-gprof msp430-objdump
Projet minimum pour obtenir le launchpad blink en C :
#include "msp430.h"
#define EXIT_SUCCESS 0
#define RED_LED BIT0
#define GREEN_LED BIT6
#define BUTTON BIT3
void no_wdt(void)
{
// Disable WDT
WDTCTL = WDTPW + WDTHOLD; // watchdog timer setup
}
void init_gpio()
{
// P1.0 and 1.6 as outputs and leds off
P1DIR |= RED_LED + GREEN_LED;
P1OUT &= ~(RED_LED + GREEN_LED);
// Button as input, output high for pullup, and pullup on
P1DIR &= ~BUTTON;
P1OUT |= BUTTON;
P1REN |= BUTTON;
}
int main()
{
no_wdt();
init_gpio();
/* boucle infinie */
while(1)
{
/* Flashing green led once in main program loop */
P1OUT ^= GREEN_LED;
__delay_cycles(100000);
P1OUT ^= GREEN_LED;
__delay_cycles(100000);
}
return EXIT_SUCCESS;
}
Ou est l'assembleur!!
msp430-gcc -mmcu=msp430g2553 -02 -Wall -S main.c
.file "main.c"
.arch msp430g2553
.cpu 430
.mpy none
.text
.p2align 1,0
.global no_wdt
.type no_wdt,@function
/***********************
* Function `no_wdt'
***********************/
no_wdt:
push r4
mov r1, r4
add #2, r4
mov #23168, &__WDTCTL
pop r4
ret
.Lfe1:
.size no_wdt,.Lfe1-no_wdt
;; End of function
.p2align 1,0
.global init_gpio
.type init_gpio,@function
/***********************
* Function `init_gpio'
***********************/
init_gpio:
push r4
mov r1, r4
add #2, r4
mov.b &__P1DIR, r15
bis.b #65, r15
mov.b r15, &__P1DIR
mov.b &__P1OUT, r15
and.b #llo(-66), r15
mov.b r15, &__P1OUT
mov.b &__P1DIR, r15
and.b #llo(-9), r15
mov.b r15, &__P1DIR
mov.b &__P1OUT, r15
bis.b #8, r15
mov.b r15, &__P1OUT
mov.b &__P1REN, r15
bis.b #8, r15
mov.b r15, &__P1REN
pop r4
ret
.Lfe2:
.size init_gpio,.Lfe2-init_gpio
;; End of function
.section .init9,"ax",@progbits
.p2align 1,0
.global main
.type main,@function
/***********************
* Function `main'
***********************/
main:
mov r1, r4
add #2, r4
call #no_wdt
call #init_gpio
.L6:
mov.b &__P1OUT, r15
xor.b #64, r15
mov.b r15, &__P1OUT
mov #llo(-32204), r15
.L4:
dec r15
cmp #0, r15
jne .L4
nop
nop
mov.b &__P1OUT, r15
xor.b #64, r15
mov.b r15, &__P1OUT
mov #llo(-32204), r15
.L5:
dec r15
cmp #0, r15
jne .L5
nop
nop
jmp .L6
.LIRD0:
.Lfe3:
.size main,.Lfe3-main
;; End of function
#include "msp430.h"
#define EXIT_SUCCESS 0
#define RED_LED BIT0
#define GREEN_LED BIT6
#define BUTTON BIT3
void no_wdt(void)
{
// Disable WDT
WDTCTL = WDTPW + WDTHOLD; // watchdog timer setup
}
void init_gpio()
{
// P1.0 and 1.6 as outputs and leds off
P1DIR |= RED_LED + GREEN_LED;
P1OUT &= ~(RED_LED + GREEN_LED);
// Button as input, output high for pullup, and pullup on
P1DIR &= ~BUTTON;
P1OUT |= BUTTON;
P1REN |= BUTTON;
}
int main()
{
no_wdt();
init_gpio();
/* boucle infinie */
while(1)
{
/* Flashing green led once in main program loop */
P1OUT ^= GREEN_LED;
__delay_cycles(100000);
P1OUT ^= GREEN_LED;
__delay_cycles(100000);
}
return EXIT_SUCCESS;
}
Oh qu'il est court notre blink !! :) ... alors pas convaincu de maîtriser l'assembleur?
Si on appuie sur le bouton la led rouge s'allume sinon elle est éteinte.