Estoy transfiriendo un software de Microchip PIC (usando el compilador C de alta tecnología) a TI MSP430, y en el código existente acceden a los pines directamente con algo como:
RA1 = 1;
¿Existe una manera similar de hacer esto con el MSP430, o tengo que escribir en todo el registro de entrada/salida cada vez? Si no es posible, ¿alguien ha encontrado un buen equivalente? Estoy usando Code Composer Studio v5.3 y el compilador que viene con eso.
En el MSP430, el acceso a los pines individuales se suele escribir utilizando operadores definidos y bit a bit :
P2OUT &= ~BIT1; /* Pin P2.1 = 0 */
P2OUT |= BIT1; /* Pin P2.1 = 1 */
P2OUT ^= BIT1; /* Toggle Pin P2.1 */
Asegúrese de incluir el archivo de encabezado adecuado para su chip específico que contenga el puerto y el pin ( BIT#
) definido.
RA1 = 1;
voy a tener que configurar el registro de salida cada vez.P2OUT.BIT1 = 1;
pero no sé si eso funciona o no. En mi experiencia con el MSP430, siempre he usado operaciones bit a bit para acceder a pines individuales. Parece la forma más común de hacer las cosas.msp430.h
; el compilador detectará automáticamente en qué micro estás.El siguiente código es una solución para el acceso de pin individual usando Code Composer (con un pequeño ajuste se puede portar a cualquier compilador). El ejemplo es una versión modificada del Ejemplo básico de Code Composer Hacer parpadear el LED. En este ejemplo, en lugar de escribir la sentencia habitual LED=1 para encender el LED, escribirá LED(HI).
//***************************************************************************
//
// MSP432 main.c template - P1.0 port toggle
//
//***************************************************************************
#include "msp.h"
#define LO 0x00
#define HI 0x01
#define BIT_0 0x01
#define BIT_1 0x02
#define BIT_2 0x04
#define BIT_3 0x08
#define BIT_4 0x10
#define BIT_5 0x20
#define BIT_6 0x40
#define BIT_7 0x80
#define LED_BIT BIT_0
#define LED_PORT P1OUT
#define LED(x) (x==HI)?(LED_PORT |= LED_BIT):(LED_PORT &= ~LED_BIT)
void main(void)
{
volatile uint32_t i;
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
// The following code toggles P1.0 port
P1DIR |= BIT0; // Configure P1.0 as output
while(1)
{
//blink LED1
LED(HI);
_delay_cycles(100000);
LED(LO);
_delay_cycles(100000);
}
}
El foro de discusión de TI tuvo una discusión muy informativa sobre lo mismo.
En resumen, esto se define mediante el msp430.h
encabezado genérico utilizado en CCS (que está vinculado al chip de destino específico msp430xxxx.h
en la compilación). No tiene soporte para PxOUT.BITy
asignaciones de estilo.
io430.h de IAR tiene soporte para eso, pero el consenso es que msp430.h
es el mejor encabezado (ya que los msp430xxxx.h
encabezados están escritos por empleados de TI, io430.h
están escritos por empleados de IAR)
PxOUT |= BITy
El estilo es la mejor manera de establecer un solo bit. PxOUT &= ~BITy
El estilo es la mejor manera de borrar un solo bit.
PxOUT &= ~BITy
aclara un poco. PxOUT |= BITy
se pone un poco.TI lo hace así en uno de sus ejemplos para los compiladores Code Composer Studio (CCS) e IAR:
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= 0x01; // Set P1.0 to output direction
for (;;)
{
volatile unsigned int i;
P1OUT ^= 0x01; // Toggle P1.0 using exclusive-OR
i = 50000; // Delay
do (i--);
while (i != 0);
}
}
[nota del moderador: este comentario ha llegado a este hilo como resultado de una fusión.]
[nota del autor: la pregunta original donde publiqué esta respuesta decía que no se pudo encontrar ningún ejemplo de código]
Erm, está bien, me tomó alrededor de 30 segundos encontrar esto:
Sitio web de TI para MSP430F2274
Herramientas y software para MSP430F2274
Código de ejemplo para MSP430F22x4
Y finalmente hay una carpeta llamada C
y en ella encontrará algunos archivos llamados msp430x22x4_p1_0x.c
que contienen ejemplos de código sobre cómo usar el Puerto 1 en C. Incluso hay un archivo Léame que le dice qué archivo se usa para qué.
Y para que esta respuesta no sea completamente inútil:
#include <msp430.h>
int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
P1DIR |= BIT0; // Set P1.0 to output direction
while (1)
{
if ((BIT2 & P1IN) == BIT2)
{
P1OUT |= BIT0; // if P1.2 set, set P1.0
}
else
{
P1OUT &= ~(BIT0); // else reset
}
}
}
(En gran medida basado en msp430x22x4_p1_01.c
A. Dannenberg / W. Goh, la declaración de derechos de autor completa es demasiado grande para esta respuesta, pero está contenida en el archivo de ejemplo de código vinculado)
*(uint16_t*)(0x1234U) = 0x20U
pero no, el compilador tendrá los archivos de encabezado, por lo que el código debería ser algo como esto.También quería cambiar el puerto en unidades de bits, así que escribí un código de muestra.
Me alegro si puedes usarlo como referencia.
El código de muestra es para MSP430FR6989.
Vuelva a escribir la dirección si es necesario.
La dirección se puede encontrar en la hoja de datos de cada dispositivo.
typedef carácter sin firmar _BYTE; unión _BITFIELD { _BYTE BYTE; estructura { _BYTE B7 :1; _BYTE B6 :1; _BYTE B5 :1; _BYTE B4 :1; _BYTE B3 :1; _BYTE B2 :1; _BYTE B1 :1; _BYTE B0 :1; } POCO; }; unión un_gpio { /* unión GPIO */ BYTE de caracteres sin firmar; /* Acceso a bytes */ estructura { /* Acceso a bits */ carácter sin firmar B0 :1; carácter sin signo B1 :1; carácter sin firmar B2 :1; carácter sin firmar B3 :1; carácter sin firmar B4 :1; carácter sin signo B5 :1; carácter sin firmar B6 :1; carácter sin firmar B7 :1; } POCO; }; // Esta es la dirección MSP430FR6989. #define GPIO1 (*(unión volátil un_gpio *)0x202) /* Dirección IO*/ #define GPIO2 (*(unión volátil un_gpio *)0x203) /* Dirección IO*/ #define GPIO3 (*(unión volátil un_gpio *)0x222) /* Dirección IO*/ #define GPIO4 (*(unión volátil un_gpio *)0x223) /* Dirección IO*/ /** * C Principal */ int principal (vacío) { WDTCTL = WDTPW | WD TENSIÓN; // detener el temporizador de vigilancia // Deshabilite el modo de alta impedancia predeterminado de encendido GPIO para activar // ajustes de puerto previamente configurados PM5CTL0 &= ~LOCKLPM5; //P1SEL &= (~BIT0); // Establecer P1.0 SEL para GPIO P1DIR |= BIT0; // Establecer P1.0 como Salida P1SALIDA = 0xFF; mientras(1) { //GPIO1.BYTE = 0x01; GPIO1.BIT.B0 = 1; //GPIO1.BIT.B1 = 1; //GPIO1.BIT.B2 = 1; //GPIO1.BIT.B3 = 1; //GPIO1.BIT.B4 = 1; //GPIO1.BIT.B5 = 1; //GPIO1.BIT.B6 = 1; //GPIO1.BIT.B7 = 1; //P1SALIDA = 0x01; __delay_cycles(800000); //GPIO1.BYTE = 0x00; GPIO1.BIT.B0 = 0; //GPIO1.BIT.B1 = 0; //GPIO1.BIT.B2 = 0; //GPIO1.BIT.B3 = 0; //GPIO1.BIT.B4 = 0; //GPIO1.BIT.B5 = 0; //GPIO1.BIT.B6 = 0; //GPIO1.BIT.B7 = 0; //P1SALIDA = 0x00; __delay_cycles(800000); } devolver 0; }
El MSP430 puede configurar o borrar bits individuales a través de las instrucciones BIS o BIC (Bit Set).
Así que ciertamente esperaría P2OUT.BIT1 = 1;
trabajar en C (al menos en mspgcc; el código Ada equivalente lo hace)
procedure Blinky is
LED : Boolean renames p1out_bits(0);
begin
-- Initialise registers etc simplified out
loop
LED := True;
Delay_MS(200);
LED := False;
Delay_MS(800);
end loop;
end Blinky;
Nick Alexeev
broma