C Programming For Embedded System Applications

3y ago
55 Views
3 Downloads
263.65 KB
52 Pages
Last View : Today
Last Download : 2m ago
Upload by : Gideon Hoey
Transcription

C programming for embeddedmicrocontroller systems.Assumes experience withassembly language programming.V. P. NelsonFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Outline Program organization and microcontrollermemory Data types, constants, variables Microcontroller register/port addresses Operators: arithmetic, logical, shift Control structures: if, while, for Functions Interrupt routinesFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Basic C program structure#include "STM32L1xx.h"/* I/O port/register names/addresses for the STM32L1xx microcontrollers *//* Global variables – accessible by all functions */int count, bob;//global (static) variables – placed in RAM/* Function definitions*/int function1(char x) { //parameter x passed to the function, function returns an integer valueint i,j;//local (automatic) variables – allocated to stack or registers-- instructions to implement the function}/* Main program */void main(void) {unsigned char sw1;//local (automatic) variable (stack or registers)int k;//local (automatic) variable (stack or registers)/* Initialization section */-- instructions to initialize variables, I/O ports, devices, function registers/* Endless loop */while (1) {//Can also use: for(;;) {-- instructions to be repeated} /* repeat forever */}Fall 2014 - ARM VersionDeclare local variablesInitialize variables/devicesBody of the programELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

STM32L100RC µC memory mapAddress0xFFFF FFFFVacant0xE00F FFFFCortexregisters0xE000 0000Control/data registers: Cortex-M3 CPU functions(NVIC, SysTick Timer, etc.)Vacant0x4002 67FF0x4000 0000PeripheralregistersControl/data registers: microcontroller peripherals(timers, ADCs, UARTs, etc.)Vacant0x2000 3FFF0x2000 000016KB RAM16K byte RAM: variable & stack storageVacant0x0803 FFFF0x0800 0000256KB FlashMemoryVacantFall 2014 - ARM Version256K byte Flash memory:program code & constant data storageReset & interrupt vectors: in 1st words of flash memoryELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Microcontroller “header file” Keil MDK-ARM provides a derivative-specific “headerfile” for each microcontroller, which defines memoryaddresses and symbolic labels for CPU and peripheralfunction register addresses.#include "STM32L1xx.h“/* target uC information */// GPIOA configuration/data register addresses are defined in STM32L1xx.hvoid main(void) {uint16 t PAval;//16-bit unsigned variableGPIOA- MODER & (0x00000003);// Set GPIOA pin PA0 as inputPAval GPIOA- IDR;// Set PAval to 16-bits from GPIOAfor(;;) {}/* execute forever */}Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

C compiler data types Always match data type to data characteristics! Variable type indicates how data is represented #bits determines range of numeric values signed/unsigned determines which arithmetic/relationaloperators are to be used by the compiler non-numeric data should be “unsigned” Header file “stdint.h” defines alternate type namesfor standard C data types Eliminates ambiguity regarding #bits Eliminates ambiguity regarding signed/unsigned(Types defined on next page)Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

C compiler data typesData type declaration * Number of bits Range of valueschar k;80.255unsigned char k;uint8 t k;signed char k;int8 t k;8-128. 127short k;signed short k;int16 t k;unsigned short k;uint16 t k;int k;signed int k;int32 t k;unsigned int k;uint32 t k;16-32768. 32767160.6553532-2147483648. 2147483647320.4294967295* intx t and uintx t defined in stdint.hFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Data type examples Read bits from GPIOA (16 bits, non-numeric)– uint16 t n; n GPIOA- IDR;//or: unsigned short n; Write TIM2 prescale value (16-bit unsigned)– uint16 t t; TIM2- PSC t;//or: unsigned short t; Read 32-bit value from ADC (unsigned)– uint32 t a; a ADC;//or: unsigned int a; System control value range [-1000 1000]– int32 t ctrl; ctrl (x y)*z; //or: int ctrl; Loop counter for 100 program loops (unsigned)– uint8 t cnt;//or: unsigned char cnt;– for (cnt 0; cnt 20; cnt ) {Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Constant/literal values Decimal is the default number formatint m,n;//16-bit signed numbersm 453; n -25; Hexadecimal: preface value with 0x or 0Xm 0xF312; n -0x12E4; Octal: preface value with zero (0)m 0453; n -023;Don’t use leading zeros on “decimal” values. They will be interpreted as octal. Character: character in single quotes, or ASCII value following “slash”m ‘a’;//ASCII value 0x61n ‘\13’; //ASCII value 13 is the “return” character String (array) of characters:unsigned char k[7];strcpy(m,“hello\n”); //k[0] ‘h’, k[1] ‘e’, k[2] ‘l’, k[3] ‘l’, k[4] ‘o’,//k[5] 13 or ‘\n’ (ASCII new line character),//k[6] 0 or ‘\0’ (null character – end of string)Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Program variables A variable is an addressable storage locationto information to be used by the program– Each variable must be declared to indicate sizeand type of information to be stored, plus nameto be used to reference the informationint x,y,z; //declares 3 variables of type “int”char a,b; //declares 2 variables of type “char”– Space for variables may be allocated in registers,RAM, or ROM/Flash (for constants)– Variables can be automatic or staticFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Variable arrays An array is a set of data, stored in consecutivememory locations, beginning at a named address– Declare array name and number of data elements, N– Elements are “indexed”, with indices [0 . N-1]n[0]int n[5];n[3] 5;//declare array of 5 “int” values//set value of 4th array elementn[1]n[2]n[3]Note: Index of first element is always 0.Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)n[4]Address:nn 4n 8n 12n 16

Automatic variables Declare within a function/procedure Variable is visible (has scope) only within thatfunction– Space for the variable is allocated on the systemstack when the procedure is entered Deallocated, to be re-used, when the procedure is exited– If only 1 or 2 variables, the compiler may allocatethem to registers within that procedure, instead ofallocating memory.– Values are not retained between procedure callsFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Automatic variable examplevoid delay () {int i,j; //automatic variables – visible only within delay()for (i 0; i 100; i ) {//outer loopfor (j 0; j 20000; j ) { //inner loop}//do nothing}}Variables must be initialized eachtime the procedure is entered sincevalues are not retained when theprocedure is exited.MDK-ARM (in my example): allocated registers r0,r2 for variables i,jFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Static variables Retained for use throughout the program in RAMlocations that are not reallocated during programexecution. Declare either within or outside of a function– If declared outside a function, the variable is global in scope,i.e. known to all functions of the program Use “normal” declarations. Example: int count;– If declared within a function, insert key word static beforethe variable definition. The variable is local in scope, i.e.known only within this function.static unsigned char bob;static int pressure[10];Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Static variable exampleunsigned char count; //global variable is static – allocated a fixed RAM location//count can be referenced by any functionvoid math op () {int i;//automatic variable – allocated space on stack when function enteredstatic int j;//static variable – allocated a fixed RAM location to maintain the valueif (count 0)//test value of global variable countj 0;//initialize static variable j first time math op() enteredi count;//initialize automatic variable i each time math op() enteredj j i;//change static variable j – value kept for next function call}//return & deallocate space used by automatic variable ivoid main(void) {count 0;while (1) {math op();count ;}}Fall 2014 - ARM Version//initialize global variable count//increment global variable countELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

C statement types Simple variable assignments– Includes input/output data transfers Arithmetic operations Logical/shift operations Control structures– IF, WHEN, FOR, SELECT Function calls– User-defined and/or library functionsFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Arithmetic operations C examples – with standard arithmetic operatorsint i, j, k;uint8 t m,n,p;i j k;m n - 5;j i * k;m n / p;m n % p;i (j k) * (i// 32-bit signed integers// 8-bit unsigned numbers// add 32-bit integers// subtract 8-bit numbers// multiply 32-bit integers// quotient of 8-bit divide// remainder of 8-bit divide– 2); //arithmetic expression*, /, % are higher in precedence than , - (higher precedence applied 1st)Example: j * k m / n (j * k) (m / n)Floating-point formats are not directly supported by Cortex-M3 CPUs.Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Bit-parallel logical operatorsBit-parallel (bitwise) logical operators produce n-bit results of thecorresponding logical operation:& (AND) (OR) (XOR) (Complement)C A & B;(AND)ABC0 1 1 0 0 1 1 01 0 1 1 0 0 1 10 0 1 0 0 0 1 0C A B;(OR)ABC0 1 1 0 0 1 0 00 0 0 1 0 0 0 00 1 1 1 0 1 0 0C A B;(XOR)ABC0 1 1 0 0 1 0 01 0 1 1 0 0 1 11 1 0 1 0 1 1 1B A;(COMPLEMENT)AB0 1 1 0 0 1 0 01 0 0 1 1 0 1 1Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Bit set/reset/complement/test Use a “mask” to select bit(s) to be alteredC A & 0xFE;A0xFECa b c d e f g h1 1 1 1 1 1 1 0 Clear selected bit of Aa b c d e f g 0C A & 0x01;A0xFECa b c d e f g h0 0 0 0 0 0 0 1 Clear all but the selected bit of A0 0 0 0 0 0 0 hC A 0x01;A0x01Ca b c d e f g h0 0 0 0 0 0 0 1 Set selected bit of Aa b c d e f g 1C A 0x01;Fall 2014 - ARM VersionA0x01Ca b c d e f g h0 0 0 0 0 0 0 1 Complement selected bit of Aa b c d e f g h’ELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Bit examples for input/output Create a “pulse” on bit 0 of PORTA (assume bitis initially 0)PORTA PORTA 0x01; //Force bit 0 to 1PORTA PORTA & 0xFE; //Force bit 0 to 0 Examples:if ( (PORTA & 0x80) ! 0 ) //Or: ((PORTA & 0x80) 0x80)bob();// call bob() if bit 7 of PORTA is 1c PORTB & 0x04;// mask all but bit 2 of PORTB valueif ((PORTA & 0x01) 0) // test bit 0 of PORTAPORTA c 0x01;// write c to PORTA with bit 0 set to 1Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Example of µC register address definitions in STM32Lxx.h(read this header file to view other peripheral functions)#define PERIPH BASE((uint32 t)0x40000000)//Peripheral base address in memory#define AHBPERIPH BASE(PERIPH BASE 0x20000)//AHB peripherals/* Base addresses of blocks of GPIO control/data registers */#define GPIOA BASE(AHBPERIPH BASE 0x0000) //Registers for GPIOA#define GPIOB BASE(AHBPERIPH BASE 0x0400) //Registers for GPIOB#define GPIOA((GPIO TypeDef *) GPIOA BASE)//Pointer to GPIOA register block#define GPIOB((GPIO TypeDef *) GPIOB BASE)//Pointer to GPIOB register block/* Address offsets from GPIO base address – block of registers defined as a “structure” */typedef struct{IO uint32 t MODER;/*! GPIO port mode register,Address offset: 0x00*/IO uint16 t OTYPER;/*! GPIO port output type register,Address offset: 0x04*/uint16 t RESERVED0;/*! Reserved,0x06*/IO uint32 t OSPEEDR; /*! GPIO port output speed register,Address offset: 0x08*/IO uint32 t PUPDR;/*! GPIO port pull-up/pull-down register,Address offset: 0x0C*/IO uint16 t IDR;/*! GPIO port input data register,Address offset: 0x10*/uint16 t RESERVED1;/*! Reserved,0x12*/IO uint16 t ODR;/*! GPIO port output data register,Address offset: 0x14*/uint16 t RESERVED2;/*! Reserved,0x16*/IO uint16 t BSRRL;/*! GPIO port bit set/reset low registerBSRR, Address offset: 0x18*/IO uint16 t BSRRH;/*! GPIO port bit set/reset high registerBSRR, Address offset: 0x1A*/IO uint32 t LCKR;/*! GPIO port configuration lock register,Address offset: 0x1C*/IO uint32 t AFR[2];/*! GPIO alternate function low register,Address offset: 0x20-0x24 */} GPIO TypeDef;Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Example: I/O port bits(using bottom half of GPIOB)GPIOB76543210hgfedcbaSwitch connected to bit 4 (PB4) of GPIOBuint16 t sw;//16-bit unsigned type since GPIOB IDR and ODR 16 bitssw GPIOB- IDR;// sw xxxxxxxxhgfedcba (upper 8 bits from PB15-PB8)sw GPIOB- IDR & 0x0010; // sw 000e0000 (mask all but bit 4)// Result is sw 00000000 or 00010000if (sw 0x01)// NEVER TRUE for above sw, which is 000e0000if (sw 0x10)// TRUE if e 1 (bit 4 in result of PORTB & 0x10)if (sw 0)// TRUE if e 0 in PORTB & 0x10 (sw 00000000)if (sw ! 0)// TRUE if e 1 in PORTB & 0x10 (sw 00010000)GPIOB- ODR 0x005a;// Write to 16 bits of GPIOB; result is 01011010GPIOB- ODR 0x10;// Sets only bit e to 1 in GPIOB (GPIOB now hgf1dcba)GPIOB- ODR & 0x10;// Resets only bit e to 0 in GPIOB (GPIOB now hgf0dcba)if ((GPIOB- IDR & 0x10) 1)// TRUE if e 1 (bit 4 of GPIOB)Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Shift operatorsShift operators:x y (right shift operand x by y bit positions)x y (left shift operand x by y bit positions)Vacated bits are filled with 0’s.Shift right/left fast way to multiply/divide by power of 2B A 3;(Left shift 3 bits)AB1 0 1 0 1 1 0 10 1 1 0 1 0 0 0B A 2;(Right shift 2 bits)AB1 0 1 1 0 1 0 10 0 1 0 1 1 0 1B ‘1’;B 0 0 1 1 0 0 0 1 (ASCII 0x31)C ‘5’;C 0 0 1 1 0 1 0 1 (ASCII 0x35)D (B 4) (C & 0x0F);(B 4) 0 0 0 1 0 0 0 0(C & 0x0F) 0 0 0 0 0 1 0 1D 0 0 0 1 0 1 0 1 (Packed BCD 0x15)Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

C control structures Control order in which instructions are executed(program flow) Conditional execution– Execute a set of statements if some condition is met– Select one set of statements to be executed fromseveral options, depending on one or more conditions Iterative execution– Repeated execution of a set of statements A specified number of times, or Until some condition is met, or While some condition is trueFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

IF-THEN structure Execute a set of statements if and only if somecondition is metTRUE/FALSE conditionif (a b){statement s1;statement s2; .}Fall 2014 - ARM Versiona b?YesNoELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)S1;S2;

Relational Operators Test relationship between two variables/expressionsTestTRUE conditionNotes(m b)m equal to bDouble (m ! b)m not equal to b(m b)m less than b1(m b)m less than or equal to b1(m b)m greater than b1(m b)m greater than or equal to b1(m)m non-zero(1)always TRUE(0)always FALSEFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)1. Compiler usessigned or unsignedcomparison, inaccordance withdata typesExample:unsigned char a,b;int j,k;if (a b) – unsignedif (j k) - signed

Boolean operators Boolean operators && (AND) and (OR) produceTRUE/FALSE results when testing multiple TRUE/FALSEconditionsif ((n 1) && (n 5)) //test for n between 1 and 5if ((c ‘q’) (c ‘Q’)) //test c lower or upper case Q Note the difference between Boolean operators &&, and bitwise logical operators &, if ( k && m) //test if k and m both TRUE (non-zero values)if ( k & m) //compute bitwise AND between m and n,//then test whether the result is non-zero (TRUE)Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Common error Note that is a relational operator,whereas is an assignment operator.if ( m n) //tests equality of values of variables m and nif (m n) //assigns value of n to variable m, and then//tests whether that value is TRUE (non-zero)The second form is a common error (omitting the second equal sign), andusually produces unexpected results, namely a TRUE condition if n is 0 andFALSE if n is non-zero.Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

IF-THEN-ELSE structure Execute one set of statements if a condition is met and analternate set if the condition is not met.if (a 0){statement s1;statement s2;}else{statement s3;statement s4:}Fall 2014 - ARM VersionS1;S2;Yesa 0?ELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)NoS3;S4;

IF-THEN-ELSE HCS12 assembly language vs C exampleAD PORT:EQU 91 ; A/D Data PortMAX TEMP:EQU 128 ; Maximum temperatureVALVE OFF:EQU 0; Bits for valve offVALVE ON:EQU 1; Bits for valve onVALVE PORT:EQU 258 ; Port P for the valve.; Get the temperatureC version:ldaa AD PORT; IF Temperature Allowed Maximum#define MAX TEMP 128cmpa #MAX TEMPbls ELSE PART#define VALVE OFF 0; THEN Turn the water valve off#define VALVE ON 1ldaa VALVE OFFstaa VALVE PORTif (AD PORT MAX TEMP)bra END IFVALVE PORT VALVE OFF;; ELSE Turn the water valve onelseELSE PART:VALVE PORT VALVE ON;ldaa VALVE ONstaa VALVE PORTEND IF:; END IF temperature Allowed MaximumFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Ambiguous ELSE associationif (n 0)if (a b)z a;elsez b;//else goes with nearest previous “if” (a b)if (n 0) {Braces force proper associationif (a b)z a;} else {//else goes with first “if” (n 0)z b;}Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Multiple ELSE-IF structure Multi-way decision, with expressionsevaluated in a specified orderif (n 1)statement1; //do if n 1else if (n 2)statement2; //do if n 2else if (n 3)statement3; //do if n 3elsestatement4; //do if any other value of n (none of the above)Any “statement” above can be replaced with a set ofstatements: {s1; s2; s3; }Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

SWITCH statement Compact alternative to ELSE-IF structure, for multiway decision that tests one variable or expressionfor a number of constant values/* example equivalent to that on preceding slide */switch ( n) {//n is the variable to be testedcase 0: statement1; //do if n 0case 1: statement2; // do if n 1case 2: statement3; // do if n 2default: statement4; //if for any other n value}Any “statement” above can be replaced with a set ofstatements: {s1; s2; s3; }Fall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

WHILE loop structure Repeat a set of statements (a “loop”) as longas some condition is metwhile (a b){statement s1;statement s2; .}a b?NoYesS1;S2; “loop” through thesestatements while a bSomething must eventually cause a b, to exit the loopFall 2014 - ARM VersionELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

WHILE loop example:C vs. HCS12 AssemblyLanguageC version:#define MAX ALLOWED 128#define LIGHT ON 1#define LIGHT OFF 0while (AD PORT MAX ALLOWED){LIGHT PORT LIGHT ON;delay();LIGHT PORT LIGHT OFF;delay();}Fall 2014 - ARM VersionAD PORT: EQU 91 ; A/D Data portMAX ALLOWED:EQU 128 ; Maximum TempLIGHT ON: EQU 1LIGHT OFF: EQU 0LIGHT PORT: EQU 258 ; Port P; --; Get the temperature from the A/Dldaa AD PORT; WHILE the temperature maximum allowedWHILE START:cmpa MAX ALLOWEDbls END WHILE; DO - Flash light 0.5 sec on, 0.5 sec offldaa LIGHT ONstaa LIGHT PORT ; Turn the lightjsr delay; 0.5 sec delayldaa LIGHT OFFstaa LIGHT PORT ; Turn the light offjsr delay; End flashing the light, Get temperature from the A/Dldaa AD PORT; END DObra WHILE STARTEND WHILE:ELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

DO-WHILE

C programming for embedded microcontroller systems. Assumes experience with assembly language programming. V. P. Nelson Fall 2014 - ARM Version ELEC 3040/3050 Embedded Systems Lab (V. P. Nelson)

Related Documents:

Bruksanvisning för bilstereo . Bruksanvisning for bilstereo . Instrukcja obsługi samochodowego odtwarzacza stereo . Operating Instructions for Car Stereo . 610-104 . SV . Bruksanvisning i original

10 tips och tricks för att lyckas med ert sap-projekt 20 SAPSANYTT 2/2015 De flesta projektledare känner säkert till Cobb’s paradox. Martin Cobb verkade som CIO för sekretariatet för Treasury Board of Canada 1995 då han ställde frågan

service i Norge och Finland drivs inom ramen för ett enskilt företag (NRK. 1 och Yleisradio), fin ns det i Sverige tre: Ett för tv (Sveriges Television , SVT ), ett för radio (Sveriges Radio , SR ) och ett för utbildnings program (Sveriges Utbildningsradio, UR, vilket till följd av sin begränsade storlek inte återfinns bland de 25 största

Hotell För hotell anges de tre klasserna A/B, C och D. Det betyder att den "normala" standarden C är acceptabel men att motiven för en högre standard är starka. Ljudklass C motsvarar de tidigare normkraven för hotell, ljudklass A/B motsvarar kraven för moderna hotell med hög standard och ljudklass D kan användas vid

LÄS NOGGRANT FÖLJANDE VILLKOR FÖR APPLE DEVELOPER PROGRAM LICENCE . Apple Developer Program License Agreement Syfte Du vill använda Apple-mjukvara (enligt definitionen nedan) för att utveckla en eller flera Applikationer (enligt definitionen nedan) för Apple-märkta produkter. . Applikationer som utvecklas för iOS-produkter, Apple .

2. Embedded systems Vs General Computing system Page 4 Sec 1.2 ; 3. History of embedded systems , classification of embedded system Page 5,6 Sec 1.3 , Sec 1,4 . 4. Major application area of embedded sys Page 7 Sec 1.5 5. Purpose of embeded system Page 8 Sec 1.6 6. Typical Embedded sys: Core of embedded system Page 15 Chap 2 : 7. Memory Page 28

The network embedded system is a fast growing area in an embedded system application. The embedded web server is such a system where all embedded device are connected to a web server and can be accessed and controlled by any web browser. Examples; a home security system is an example of a LAN networked embedded system .

och krav. Maskinerna skriver ut upp till fyra tum breda etiketter med direkt termoteknik och termotransferteknik och är lämpliga för en lång rad användningsområden på vertikala marknader. TD-seriens professionella etikettskrivare för . skrivbordet. Brothers nya avancerade 4-tums etikettskrivare för skrivbordet är effektiva och enkla att