Objectif Architecture d’un système à µP Description d’un système Fonctionnement matériel Conception Applications spéciales Exemple du 6809 M. Deloizy 1 Exemple du 6809 Simplicité Lenteur Pas d’optimisation Programmes et données dans le même espace Exécution séquentielle M. Deloizy 3 Le processeur Processeur Mémoires Dispositifs d’Entrées/Sorties Logique de contrôle et gestion Architecture de Von Neumann (1903~1957) 2 Éléments constitutifs d’un système Système 8 bits M. Deloizy Sélection de la donnée pointée par PC Lecture de la donnée Suite d’instructions exécutées séquentiellement 4 Exécution d’une instruction Cœur du système Gère échanges avec « périphériques » sous contrôle d’un « programme » Programme : M. Deloizy Code opérateur Décodage et exécution de l’instruction Code opérateur [+ opérande] PC indique instruction en cours Peut durer plusieurs cycles Récupération de l’instruction suivante M. Deloizy 5 Selon complexité Micro programmes Peut nécessiter lecture de données complémentaires PC placé sur la prochaine instruction à exécuter M. Deloizy 6 1 Description « électrique » du 6809 Description « électrique » du 6809 40 pattes / 5V Vss, Vcc : alimentation A0 ~ A15 : adresses (sorties, 64k adr.) D0 ~ D7 : données (8 bits, bidir.) NMI, IRQ, FIRQ : entrées interruptions RESET : entrée initialisation (trigger) XTAL, EXTAL : oscillateur Q, E : sorties horloges (quad, Fxtal/4) R/W : sortie Read/Write HALT : entrée. Mise en veille. Réveil par RESET, NMI ou DMA/BREQ DMA/BREQ : entrée. Demande accès aux bus M. Deloizy M. Deloizy « adresse » du périphérique µP positionne la ligne R/W à 0 µP positionne données (quand EÊ) Périphérique doit lire données (quand E Ì) µP met données en Hi-Z M. Deloizy 8 Lecture d’un périphérique µP positionne les lignes adresses 00 : normal 11 : bus Hi-Z 01 : reconnaissance interruption 10 : attente synchro (instruction Wait) 7 Écriture dans un périphérique MRDY : entrée. Indique si le périphérique est prêt. BA, BS : sorties. Indiquent l’état du CPU µP positionne les lignes adresses µP positionne la ligne R/W à 1 Périphérique doit positionner données µP lit données (quand E Ì) Périphérique doit mettre données en Hi-Z µP met données en Hi-Z 9 Chronogrammes du µP M. Deloizy 10 Périphériques Situés « autour » du processeur Circuit adressable accessible en lecture ou écriture Exemples : M. Deloizy 11 Entrées / Sorties numériques CNA ou CAN Interfaces (écran, réseaux, mémoires de masse, …) Mémoires (RAM, ROM, UVPROM, EEPROM, OTP…) Vus par le processeur comme des mémoires M. Deloizy 12 2 Rappel Cellule mémoire unité Association de mémoires RD et WR inactifs : D en Hi-Z RD actif : Donnée apparaît sur D (en sortie) WR actif : Donnée chargée en mémoire WR A0 Décodeur lignes A1 1 parmi 4 D RD/WR# : Mémoire 16x1 bits RD Autre possibilité : Augmentation du nombre de bits Numéro de ligne 1 : lecture de la mémoire (D en sortie) 0 : chargement de la mémoire (D en entrée) & R/W# Décodeur colonnes 1 parmi 4 RD/WR# EN EN : validation de la mémoire D Mémoire 16x1 bits Mémoire de mots 16x4 bits EN D A3 A2 A1 A0 A3 A2 A1 A0 15 M. Deloizy Association de mémoires Y EN Décodeur 2 => 4 X A4 q2 q1 cs q0 A3 A2 A1 A0 M. Deloizy D3 D2 D1 D0 a3 Q1 d a2 a1 en a0 r/w# a3 Q0 d a2 en a1 a0 r/w# Adresse (0 à 15) q3 a3 Q3 d a2 a1 en a0 r/w# a3 Q2 d a2 a1 en a0 r/w# R/W# A5 14 Association de mémoires D R/W# M. Deloizy Augmentation du nombre de mots 64x4 bits Numéro de colonne A2 A3 13 M. Deloizy EN D EN R/W# M. Deloizy 16 M. Deloizy 18 Exemple : HM65764 en a3 a2 a1 a0 en a3 a2 a1 a0 en a3 a2 a1 a0 en a3 a2 a1 a0 Q3 d3 d2 d1 d0 r/w# Q2 d3 d2 d1 d0 r/w# Q1 d3 d2 d1 d0 r/w# Q0 d3 d2 d1 d0 r/w# D3 D2 D1 D0 R/W# 17 3 Exemple : 27C64 Boîtiers 27C64, 27C256 & 27C512 M. Deloizy 19 27C64, 27C256 & 27C512 (JEDEC) M. Deloizy M. Deloizy 20 Exemple : EEProm HN58S65 21 M. Deloizy 22 Afficheur AV1624 Exemple : UART TL16C450 M. Deloizy 23 M. Deloizy 24 4 CAN AD7813 DDR SDRAM SDRAM DDR SDRAM M. Deloizy M. Deloizy VDD = VDDQ = +1.5V ±0.075V Differential bidirectional data strobe Differential clock inputs (CK, CK#) 8 internal banks for concurrent operation Automatic refresh tCK range: 300–667 MHz Timing – cycle time : 1.5 … 2.5 ns (800 … 1333 Mb/s) M. Deloizy 26 Boîtier Caractéristiques : SDRAM Fonctionne sur 2 fronts horloge 25 DDR3 SDRAM : MT41J256M8 – 32 Meg x 8 x 8 banks RAM synchrone Horloge interne synchronisée sur CPU Évite temps attente lors accès FBGA 94 billes Fine-pitch Ball Grid Array 27 M. Deloizy 28 Décodage d’adresses Décodage d’adresses Circuit logique combinatoire Génération d’un signal de validation M. Deloizy Pour un µP avec NBAD lignes d’adresses Assigner une adresse à chaque périphérique 29 Sélection d’un circuit parmi les périphériques Actif pour une plage d’adresses À partir de l’adresse émise par le processeur Adresses comprises entre 0 et (2NBAD-1) M. Deloizy 30 5 Présentation Exemple: Génération de CS pour des adresses comprises entre 4000 et 4FFF : Chaque périphérique se voit attribué une zone mémoire (plage d’adresses) Méthode Choix arbitraire Parfois, contrainte liée au processeur Exemple : RAM 32 ko : 32768 octets (32768 adresses) On choisit de la placer en haut du plan mémoire : Occupe les adresses 8000H à FFFFH. On génère un signal (CS) actif quand le processeur émet une adresse dans cette plage Adresse A15 A14 A13 A12 A11 A10 A9 A8 A7 A6 A5 A4 A3 A2 A1 A0 4FFF 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4FFE 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 4FFD 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 … 0 1 x x x x x x x x x x x x x x 4002 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 4001 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 4000 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 CS actif quand : A15=0 ET A14=1 M. Deloizy 31 Exemple M. Deloizy 34 M. Deloizy 36 16 ko de ROM type 27C64 32 Circuit logique 74138 Système 6809 M. Deloizy Bloc continu Vecteur RESET & interruptions en FFF8 à FFFF 8 ko de RAM type 65764 (en page 0) 1 uart TL16C450 1 afficheur AV1624 Décodage strict Décodage incomplet Utilisation de circuit décodeur/démultiplexeur M. Deloizy 33 Circuit logique 74139 Circuit logique 74244 M. Deloizy 35 6 Circuit logique 74245 Circuit logique 74373 M. Deloizy 37 Système complet M. Deloizy 38 M. Deloizy 40 M. Deloizy 42 Système 6809 M. Deloizy 39 Alimentations Interruptions… M. Deloizy 41 7 Décodage Lignes R/W M. Deloizy 43 M. Deloizy 44 45 M. Deloizy 46 47 M. Deloizy 48 Câblage mémoires Câblage UART M. Deloizy Extension de mémoire 6809 : 64k adressables On souhaite « voir » 1 Mo Nécessite 20 lignes d’adresses (16x64 = 1024) Mise en place d’un système de pages M. Deloizy 8 Mémoire partagée 2 processeurs Périphériques (RAM, ROM, …) distincts 1 périphérique en commun Par exemple : RAM Intérêt : Communication très rapide entre les 2 systèmes RAM propriétaire d’un système M. Deloizy 49 Systèmes 16 bits M. Deloizy 52 Bus d’adresses A0 … A23 : 16 Mo adressables Bus de données D0 … D15 : 16 bits Mémoire 16 bits constituée de 2 plans 8 bits en // Problème : accès à octets pairs ou impairs Nécessite signaux de plans individuels : Bus d’adresse indique « adresse de mot » UDS# et LDS# sélectionnent octet pair ou impair A0 inutile (non sorti sur le bus) Ne permet pas d’accéder à un mot en adresse impaire 50 Exemple de bus 16 bits Exemple : 68000 M. Deloizy UDS# & LDS# Autre système : Utilisation de BHE# et A0 M. Deloizy 51 9 Microcontrôleurs Microcontrôleurs I. Présentation Microprocesseur conventionnel + périphériques intégrés dans une puce Infineon C167 2 1 Microcontrôleurs Microcontrôleurs Intègrent : • • • • • Mémoire (RAM,ROM) Circuits d’horloge Ports parallèles, timers, timers, compteurs, ports série Convertisseurs analogiques AD / DA Périphériques spécialisés : Constituent un système autonome à eux seuls 9 I²C 9 Contrôle 9 Bus moteur CAN … 3 4 Microcontrôleurs Microcontrôleurs Avantages : • • • • Système à faible coût Encombrement réduit Meilleure fiabilité Mise en œuvre facilitée Î Adapté Adaptés • • Inconvénients : • • • • : Performance des périphériques réduite Inadaptés à la gestion de gros systèmes Utilisation simultanée de tous les périphériques impossible Complexité du système Aux grandes séries Aux systèmes embarqués 5 6 1 Microcontrôleurs Microcontrôleurs Domaines d’utilisation : Choix d’un microcontrôleur : Deux critères essentiels : ¾ Systèmes embarqués ¾ Petits systèmes économiques ¾ Systèmes de commande à faible diffusion (prototypes…) ¾ Tout système ne nécessitant pas des ressources importantes 1. Puissance du processeur • • • • Î Applications plus importantes ⇒ PC industriel Format des mots traités Fréquence d’horloge Architecture interne (optimisée ?) Jeu d’instructions et adressages, nombre de registres. Adaptation aux langages évolués. 7 8 Microcontrôleurs Microcontrôleurs Choix d’un microcontrôleur : Deux critères essentiels : 2. Le coût du composant Le coût du système de développement & Consommation & Langages disponibles et efficacité & Ressources disponibles (Internet) & Connaissance du système & Périphériques intégrés • • • • Autres critères de choix : & Mémoire interne (RAM, ROM, EEPROM…) Nombre de lignes d’E/S Nombre de compteurs, précision, … Périphériques spécialisés Î Il est pré préférable de ne pas rajouter de pé périphé riphériques autour du microcontrôleur ! → Première mise en œuvre difficile (système complexe) 9 Microcontrôleurs 10 C167 CR Infineon C167CR → Siemens → Famille C166 → Processeur 16 bits → 111 lignes d’ d’E/S → Bus CAN 11 12 2 C167 CR Architecture interne SAKSAK-C167CRC167CR-16RM C167 CR 13 14 C167 CR C167 CR High Performance 1616-bit CPU with four stage Pipeline • • • • • • • 80/60 ns minimum instruction cycle time, with most instructions executed in 1 cycle 400/300 ns multiplication (16(16-bit x 1616-bit), 800/600 ns division (32(32-bit/16bit/16-bit) Multiple high bandwidth internal data buses Register based design with multiple variable register banks Single cycle context switching support 16 MBytes linear address space for code and data (Von Neumann architecture) System stack cache support with automatic stack overflow/underflow detection Control Oriented Instruction Set with High Efficiency • • • • • Bit, byte, and word data types Flexible and efficient addressing modes for high code density Enhanced boolean bit manipulation with direct addressability of 6 Kbits for peripheral control and user defined flags Hardware traps to identify exception conditions during runtime High Level Language support for semaphore operations and efficient data access 15 16 C167 CR Integrated • • • C167 CR On-chip Memory External 2 KByte internal RAM for variables, register banks, system stack and code code 2 KByte onon-chip highhigh-speed XRAM for variables, user stack and code (not on all derivatives) 128 KByte or 32 KByte onon-chip ROM (not for ROMless devices) 17 • • • • Bus Interface Multiplexed or demultiplexed bus configurations Segmentation capability and chip select signal generation 8-bit or 1616-bit data bus Bus cycle characteristics selectable for five programmable address address areas 18 3 C167 CR 1616-PriorityPriority-Level Interrupt System • • • C167 CR • 56 interrupt nodes with separate interrupt vectors 240/180 ns typical interrupt latency (400/300 ns maximum) in case of internal program execution Fast external interrupts • • • 8-Channel Peripheral Event Controller (PEC) • • • Intelligent OnOn-chip Peripheral Subsystems Interrupt driven single cycle data transfer Transfer count option (std. CPU interrupt after programmable number of PEC transfers) Eliminates overhead of saving and restoring system state for interrupt requests • • • • • 1616-channel 1010-bit A/D Converter with programmable conversion time (7.76 ms minimum), auto scan modes, channel injection mode Two 1616-channel Capture/Compare Units with 2 independent time bases each, each, very flexible PWM unit/event recording unit with different operating operating modes, includes four 1616-bit timers/counters, maximum resolution fCPU/8 4-channel PWM unit Two Multifunctional General Purpose Timer Units GPT1: Three 1616-bit timers/counters, maximum resolution fCPU/8 GPT2: Two 1616-bit timers/counters, maximum resolution fCPU/4 Asynchronous/Synchronous Serial Channels (USART) with baud rate generator, parity, framing, and overrun error detection High Speed Synchronous Serial Channel programmable data length and and shift direction OnOn-chip CAN Bus Module, Rev. 2.0B active (not on all derivatives) Watchdog Timer with programmable time intervals Bootstrap Loader for flexible system initialization 19 20 C167 CR C167 CR 111 IO Lines with Individual Bit Addressability • • • • TriTri-stated in input mode Selectable input thresholds (not on all pins) Push/pull or open drain output mode Programmable port driver control (fast/reduced edge) Different Temperature Ranges • Infineon CMOS Process • C167 CR : Organisation mémoire Low power CMOS technology including power saving Idle and Power Down modes. 144144-pin Plastic Metric Quad Flat Pack (MQFP) Package • 21 0 to + 70 °C, – 40 to + 85 °C, – 40 to + 125 °C P-MQFP, 28 x 28 mm body, 0.65 mm (25.6 mil) lead spacing, surface mount technology 22 C167 CR : Organisation mémoire Architecture Von Neumann Espace mémoire unique pour ROM interne, RAM interne, interne, SFRs, SFRs, périphériques internes et mémoire externe. 16 M-octets adressables • • 256 segments de 64 Ko chacun chaque segment est divisé en 4 pages de 16 Ko 23 24 4 C167 CR : Organisation mémoire Mémoire interne → segment 0. 0000h … 7FFFh : ROM / Flash ou OTP interne. Peut être déplacé en 10000h … 1FFFFh pour permettre ROM externe en adresse basse. F000h … FFFFh : RAM interne et SFRs C167 CR : Organisation mémoire Octets situés en adresses paires ou impaires. Mots (16 bits) situés en adresse paire Longs mots (32 bits) rangés comme 2 mots consécutifs Adressage des bits : Code exécutable en RAM ou ROM, sauf dans les SFRs. SFRs. MSB en adresse impaire LSB en adresse paire. certains SFRs une partie de la RAM interne registres à usage général 25 C167 CR : Organisation mémoire Mémoire IRAM 26 C167 CR : Organisation mémoire • 2 Ko • 256 octets de SFRs Registres à usage général → registres de travail • Mémoire XRAM • 2 Ko. • Mémoire interne située en page 3. • Accessible comme RAM externe (sans utiliser les bus externes). • Peut être désactivée par bit XPEN de SYSCON. • Pas de Wait-states •Accessible de l'extérieur en DMA • • • Blocs de 16 mots consécutifs en RAM interne. Internal RAM Address Byte Registers Word Register <CP> + 1EH – R15 CP<CP> (Context Pointer) indique l'adresse de base (Context + 1CH – R14 <CP> + 1AH – R13 <CP> +commutation 18H – R12 Permet de contexte rapide <CP> + 16H – R11 <CP> (Switch 14H – R10 SCXT Context) ) réalise la commutation de banques et (+Switch Context <CP> + 12H – R9 <CP> + 10H – R8 précédent. une sauvegarde automatique du contexte <CP> <CP> <CP> <CP> <CP> <CP> <CP> <CP> + + + + + + + + 0EH 0CH 0AH 08H 06H 04H 02H 00H RH7 RH6 RH5 RH4 RH3 RH2 RH1 RH0 RL7 RL6 RL5 RL4 RL3 RL2 RL1 RL0 R7 R6 R5 R4 R3 R2 R1 R0 27 28 C167 CR : Organisation mémoire Mémoire externe 4 tailles de banques possibles : • 64 Ko. Mode non segmenté • 256 Ko. Mode segmenté 2 bits • • • • A15…A0 sur P0 et P1 A17,A16 sur P4 ; A15…A0 sur P0 et P1 1 Mo. Mode segmenté 4 bits • A19…A16 sur P4 ; A15…A0 sur P0 et P1 16 Mo. Mode segmenté 8 bits • C167 CR : CPU A22…A16 sur P4 ; A15…A0 sur P0 et P1 29 ALU 16 bits Pipeline à 4 étages (parallélisme) Accès aux périphériques externes par External Bus Controller → Le CPU peut continuer à fonctionner en attendant que EBC effectue un accès externe.. Périphériques internes utilisent un générateur d'horloge distinct. Contrôleur d'interruption intégré avec gestion des priorités. Traitement d'interruptions par PEC Interruptions logicielles, NMI traitées comme iT ordinaires Watchdog Modes faible consommation 30 5 C167 CR : CPU C167 CR : CPU États CPU particuliers : Reset : force le CPU dans un état prédéfini IDLE : horloge du CPU arrêtée ; horloges des périphériques actives POWERPOWER-DOWN : Toutes horloges arrêtées. Entrées des périphériques ignorées. Sortie du mode IDLE : par interruption Sortie du mode POWERPOWER-DOWN : par RESET 31 32 DECODE Cycle 6 FETCH Cycle 5 1) Recherche de l'instruction 2) Décodage de l'instruction, calcul des adressages, récupération des éventuels opérandes 3) Exécution de l'instruction. Utilisation de l'ALU l'ALU.. Mise à jour de PSW. 4) Écriture des résultats dans RAM interne ou externe Pipeline Cycle 4 Cycle 3 Pipeline Instruction exécutée en 4 étapes : Cycle 2 C167 CR : CPU Cycle 1 C167 CR : CPU I1 I2 I3 I4 I5 I6 I1 I2 I3 I4 I5 I1 I2 I3 I4 I1 I2 I3 EXECUTE WRITEBACK 33 34 C167 CR : CPU C167 CR : CPU Exemple Problèmes liés au pipeline : de problème lié au pipeline : Initialisation 4 instructions traitées simultanément des ports incorrect : Anticipation Risque de mauvaise exécution ⇒ Parfois injection d’une instruction dans le deuxième étage du pipeline quand une instruction ne peut pas être traitée complètement en 1 cycle → « instruction injectée » ⇒ BSET DP3.12 ;met le bit 12 de P3 en sortie BSET P3.9 ;P3.12 est encore une entrée ; rd/ rd/mod/ mod/wr lit P3.12 ⇒ correct : BSET DP3.12 NOP BSET P3.9 ;P3.12 est en sortie ; ;rd/ rd/mod/ mod/wr lit le latch de la sortie P3.12 35 36 6 C167 CR : CPU C167 CR : CPU Exemple de problème lié au pipeline : Contrôle des interruptions ¾ IEN ou ILVL de PSW non pris en compte instantanément : BCLR IEN … … … BSET IEN ¾ ;désactive interruptions ;instruction encore interruptible ;interruptions désactivées (début d'une séquence critique) ¾ • ;autorise interruptions (fin de la séquence critique) • ou : ATOMIC #3 BCLR IEN … BSET IEN Pile système • ;désactive immédiatement les interruptions ;interdit les interruptions ;séquence critique • • utilisation des sous programmes gestion des interruptions sauvegardes gérées par le CPU Pile de type LIFO Utilise le registre SP (Stack (Stack Pointer) SP évolue vers les adresses basses quand une donnée est rangée dans dans la pile. Seules les données 16 bits sont autorisées. STKOV et STKUN sont des registres qui permettent de contrôler les les dépassements de pile. Ils permettent également la gestion d'une pile circulaire 37 38 C167 CR : SFRs XPERXPER-SHARE BDRSTEN Visible Mode Control XBUS Peripheral Enable Bit 0:Accesses 0:Accesses to the onon-chip XX-Peripherals and their functions are disabled 1:The 1:The onon-chip XX-Peripherals are enabled and can be accessed Oscillator Watchdog Disable Bit (Cleared after reset) 0: The onon-chip oscillator watchdog is enabled and active. 1: The onon-chip oscillator watchdog is disabled and the CPU clock is always fed from the oscillator input. CSCFG Bidirectional Reset Enable Bit 0: Pin RSTIN is an input only. 1: Pin RSTIN is pulled low during the internal reset sequence after any reset. OWDDIS 0:Accesses 0:Accesses to XBUS peripherals are done internally 1:XBUS 1:XBUS peripheral accesses are made visible on the external pins XPEN XBUS Peripheral Share Mode Control 0:External 0:External accesses to XBUS peripherals are disabled 1:XBUS 1:XBUS peripherals are accessible via the external bus during hold mode VISIBLE C167 CR : SFRs Chip Select Configuration Control (Cleared after reset) 0: Latched CS mode. The CS signals are latched internally and driven to the (enabled) (enabled) port pins synchronously. 1: Unlatched CS mode. The CS signals are directly derived from the address and driven to the (enabled) port pins. 39 40 C167 CR : SFRs WRCFG Write Configuration Control (Set according to pin P0H.0 during reset) System Clock Output Enable (CLKOUT, cleared after reset) 0: CLKOUT disabled: pin may be used for general purpose IO 1: CLKOUT enabled: pin outputs the system clock signal 0: Pin BHE enabled 1: Pin BHE disabled, pin may be used for general purpose IO 41 Segmentation Disable/Enable Control (Cleared after reset) 0:Segmentation 0:Segmentation enabled (CSP is saved/restored during interrupt entry/exit) entry/exit) 1:Segmentation 1:Segmentation disabled (Only IP is saved/restored) ROMS1 Internal ROM Enable (Set according to pin EA during reset) 0:Internal 0:Internal program memory disabled, accesses to the ROM area use the the external bus 1:Internal 1:Internal program memory enabled SGTDIS BYTDIS Disable/Enable Control for Pin BHE (Set according to data bus width) ROMEN 0: Pins WR and BHE retain their normal function 1: Pin WR acts as WRL, pin BHE acts as WRH CLKEN C167 CR : SFRs Internal ROM Mapping 0:Internal 0:Internal ROM area mapped to segment 0 (00’0000H … 00’7FFFH) 1:Internal 1:Internal ROM area mapped to segment 1 (01’0000H … 01’7FFFH) 42 7 C167 CR : SFRs STKSZ C167 CR : SFRs System Stack Size N Negative Result C Selects the size of the system stack (in the internal RAM) from 32 to 512 words V Z Set, when the result of an ALU operation is negative. negative. Carry Flag Set, when the result of an ALU operation produces a carry bit. Overflow Result Set, when the result of an ALU operation produces an overflow. overflow. Zero Flag Set, when the result of an ALU operation is zero. zero. 43 44 C167 CR : SFRs E Multiplication/Division In Progress 0: There is no multiplication/division in progress 1: A multiplication/division has been interrupted USR0 End of Table FlagSet when the source operand of an instruction is 8000H or 80H MULIP C167 CR : SFRs User General Purpose Flag May be used by the application software HLDEN, ILVL, IEN : Interrupt and EBC Control Fields Define the response to interrupt requests and enable external bus arbitration. Ignoré en mode non segmenté 46 45 C167 CR : SFRs C167 CR : SFRs Pointeurs de pages de données (DDPx) → Sélection simultanée de 4 pages de données de 16 Ko dans l'ensemble de la mémoire. Pointeur de contexte (CP) 47 → Indique l'adresse de base du bloc de registres (GPR : General Purpose Registers) Registers) 48 8 C167 CR : SFRs C167 CR : SFRs Poids fort Multiplication/Division (MDH) 16x16→ 16x16→32 : 16 bits poids fort du résultat 32:16→ 32:16→16+reste(16) : MDH contient 16 bits poids fort du dividende. Après Après la division, MDH contient le reste. Quand interruption, MDH doit être sauvegardé 49 50 C167 CR : SFRs C167 CR : SFRs Contrôle des multiplications/divisions MDRIU Multiply/ Multiply/Divide Register In Use 0 : Cleared when register MDL is read via software 1 : Set when register MDL or MDH is set via software, or when a multiply or divide instruction is executed. executed. !! Internal Machine Status The multiply/ multiply/divide unit uses these bits to control internal operations. operations. Never modify these bits without saving and restoring register MDC 51 52 C167 CR : Ports parallèles PxLIN Portx Low Byte Input Level Selection 0: Pins Px.7 … Px.0 switch on standard TTL input levels 1: Pins Px.7 … Px.0 switch on special threshold input levels PxHIN C167 CR : Ports parallèles BIPEC Bus Interface Pins Edge Characteristic (Defines the outp. rise/fall time tRF) 0: Fast edge mode, rise/fall times depend on the driver’s dimensioning. 1: Reduced edge mode. BIPEC controls: PORT0, PORT1, Port4, Port 6, RD, WR, ALE, CLKOUT,BHE/WRH, READY (emulation mode only). Portx High Byte Input Level Selection 0: Pins Px.15 … Px.8 switch on standard TTL input levels 1: Pins Px.15 … Px.8 switch on special threshold input levels NBPEC Non-Bus Pins Edge Characteristic (Defines the output rise/fall time tRF) 0: Fast edge mode, rise/fall times depend on the driver’s dimensioning. 1: Reduced edge mode. NBPEC controls: Port2, Port3, Port7, Port8, RSTOUT, RSTIN(bidirectional reset mode only). 53 54 9 C167 CR : Ports parallèles C167 CR : Ports parallèles Port Fonctions alternées Alternate Function(s) Function(s) Alternate Signal(s) Signal(s) PORT0 Address and data lines when accessing external resources (e.g. memory) AD15 … AD0 PORT1 Address lines when accessing ext. resources Capture inputs of the CAPCOM units A15 … A0, CC27IO … CC24IO PORT2 Capture inputs or compare outputs of the CAPCOM units, CAPCOM timer input Fast external interrupt inputs CC15IO … CC0IO, T7IN, EX7IN … EX0IN 55 56 C167 CR : Ports parallèles Port PORT3 PORT4 Alternate Function(s) Function(s) System clock output Optional bus control signal Input/output functions of serial interfaces,timers C167 CR : Ports parallèles Alternate Signal(s) Signal(s) CLKOUT, BHE/WRH,RxD0, TxD0, MTSR, MRST,SCLK, T2IN, T3IN, T4IN,T3EUD, T3OUT, CAPIN,T6OUT, T0IN Selected segment address lines in systems with A23 …A16, more than 64 KBytes of external resources CAN1_TxD, CAN1_RxD CAN interface (where implemented) Port Alternate Function(s) Function(s) Alternate Signal(s) Signal(s) PORT5 Analog input channels to the A/D converter Timer control signal inputs AN15 … AN0, T2EUD, T4EUD, T5IN, T6IN PORT6 Bus arbitration signals, signals, Chip select output signals BREQ, HLDA, HOLD,CS4 … CS0 PORT7 Capture inputs or compare outputs of the CAPCOM units PWM output signals CC31IO … CC28IO, POUT3 … POUT0 PORT8 Capture inputs or compare outputs of the CAPCOM units CC23IO … CC16IO 57 C167 CR : Ports parallèles 58 C167 CR : Ports parallèles Port 0 Port 16 bits bidirectionnel 59 60 10 C167 CR : Ports parallèles C167 CR : Ports parallèles Port 1 Port 16 bits bidirectionnel ≈ Identique Port 0 Port direction register DP0H or DP0L bit y • DP0X.y = 0: Port line P0X.y is an input (high-impedance) • DP0X.y = 1: Port line P0X.y is an output 61 C167 CR : Ports parallèles 62 C167 CR : Ports parallèles P1L : PORT1 Low Register SFR (FF04H/82H) Reset Value: - - 00H P1H : PORT1 High Register SFR (FF06H/83H) Reset Value: - - 00H DP1L : P1L Direction Ctrl. Register ESFR (F104H/82H) Reset Value: - - 00H DP1H : P1H Direction Ctrl. Register ESFR (F106H/83H) Reset Value: - - 00H Port 2 Port 16 bits bidirectionnel 63 C167 CR : Ports parallèles 64 C167 CR : Ports parallèles Port2 Open Drain control register bit y ODP2.y = 0: Port line P2.y output driver in push/pull mode ODP2.y = 1: Port line P2.y output driver in open drain mode Port direction register DP2 bit y • DP2.y = 0: Port line P2.y is an input (high-impedance) • DP2.y = 1: Port line P2.y is an output 65 66 11 C167 CR : Ports parallèles C167 CR : Ports parallèles Port 3 Port 15 bits bidirectionnel Port direction register DP3 bit y • DP3.y = 0: Port line P3.y is an input (high-impedance) • DP3.y = 1: Port line P3.y is an output 67 C167 CR : Ports parallèles 68 C167 CR : Ports parallèles Port 4 Port 8 bits bidirectionnel ≈ Fonctionnement identique au Port 0 Port3 Open Drain control register bit y ODP3.y = 0: Port line P3.y output driver in push/pull mode ODP3.y = 1: Port line P3.y output driver in open drain mode Due to pin limitations register bit P3.14 is not connected to an IO pin. Pins P3.15 and P3.12 do not support open drain mode. 69 C167 CR : Ports parallèles P4 : PORT4 Data Register SFR (FFC8H/E4H) 70 C167 CR : Ports parallèles Reset Value: - - 00H Port 5 Port 16 bits en entrée DP4 : P4 Direction Ctrl. Register SFR (FFCAH/E5H) Reset Value: - - 00H 71 Multiplexé avec entrées analogiques 72 12 C167 CR : Ports parallèles C167 CR : Ports parallèles Port 6 Port 8 bits bidirectionnel ≈ Fonctionnement identique au Port 2 Port5 Bit y Digital Input Control P5D.y = 0: Digital input stage connected to port line P5.y P5D.y = 1: Digital input stage disconnected from port line P5.y (When being read or used as alternate input this line appears as ‘1’) 73 C167 CR : Ports parallèles P6 : PORT6 Data Register SFR (FFCCH/E6H) 74 C167 CR : Ports parallèles Reset Value: - - 00H Port 7 DP6 : P6 Direction Ctrl. Register SFR (FFCEH/E7H) Reset Value: - - 00H ODP6 : P6 Open Drain Ctrl. Reg. ESFR (F1C1H/E7H) Reset Value: - - 00H Port 8 bits bidirectionnel ≈ Fonctionnement identique au Port 2 75 C167 CR : Ports parallèles P7 : PORT7 Data Register SFR (FFD0H/E8H) 76 C167 CR : Ports parallèles Reset Value: - - 00H Port 8 DP7 : P7 Direction Ctrl. Register SFR (FFD2H/E9H) Reset Value: - - 00H ODP7 : P7 Open Drain Ctrl. Reg. ESFR (F1D2H/E9H) Reset Value: - - 00H 77 Port 8 bits bidirectionnel ≈ Fonctionnement identique au Port 2 78 13 C167 CR : Ports parallèles Ports parallèles : Application 1 P8 : PORT8 Data Register SFR (FFD4H/EAH) Reset Value: - - 00H DP8 : P8 Direction Ctrl. Register SFR (FFD6H/EBH) Reset Value: - - 00H ODP8 : P8 Open Drain Ctrl. Reg. ESFR (F1D6H/EBH) Reset Value: - - 00H Réalisation d’un simulateur logique sur le port 3. E5 et E6 permettent de mettre les sorties NAND et NOR en drain ouvert (OD) ou en pushpush-pull (PP) : E6 (b7) E5 (b6) NAND 0 0 PP PP 0 1 PP OD 1 0 OD PP 1 1 OD OD NOR 79 80 C167 CR : Timers Ports parallèles : Application 2 Timers Serrure codée Code de 3 à 6 chiffres ‘C’ : Recommencer ‘V’ : Valider LED indique : GPT1 et GPT2 (General (General Purpose Timer) Timer) GPT1 : 3 timers/compteurs timers/compteurs 16 bits avec une résolution maximale de 16 TCLK GPT2 : 2 timers/compteurs timers/compteurs 16 bits avec une résolution maximale de 8 TCLK + Code Ok (allumage 1s) Début saisie (2 clign.) capture/reload capture/reload 16 bits Activation gâche : 1 sec Timer : utilise l'horloge interne Compteur : des signaux externes pilotent l'unité de comptage On dispose de : void delay(unsigned ms) 81 82 C167 CR : Timers C167 CR : Timers T2, T3, T4 GPT1 Fonctionnements identiques. Seul T3 dispose d'une sortie T2, T3 et T4 83 84 14 C167 CR : Timers C167 CR : Timers T2CON : Timer 2 Control Register SFR (FF40H/A0H) Reset value: 0000H T3CON : Timer 3 Control Register SFR (FF42H/A1H) Reset value: 0000H TxCON : TxI Timer x Input Selection T4CON : Timer 4 Control Register SFR (FF44H/A2H) Reset value: 0000H Registres de contrôle de T2, T3, T4 Depends on the Operating Mode, see respective sections. TxM Timer x Mode Control (Basic Operating Mode) 000 : Timer Mode 001 : Counter Mode 010 : Gated Timer with Gate active low 011 : Gated Timer with Gate active high 100 : T2,T4 : Reload Mode. T3 : Reserved. Do not use this combination. combination. 101 : T2,T4 : Capture Mode. T3 : Reserved. Do not use this combination. combination. 110 : Incremental Interface Mode 111 : Reserved. Do not use this combination. 85 86 C167 CR : Timers C167 CR : Timers TxCON : TxR Timer x Run Bit 0 : Timer/Counter x stops 1 : Timer/Counter x runs TxUD Timer x Up/Down Control TxUDE Timer x External Up/Down Enable T3OE Alternate Output Function Enable Modes compteur & timer : 0: Alternate Output Function Disabled 1: Alternate Output Function Enabled T3OTL Timer 3 Output Toggle Latch Toggles on each overflow/underflow of T3. Can be set or reset by software. 87 88 C167 CR : Timers C167 CR : Timers Modes compteur & timer : TxI Pin TxEUD Bit TxUDE Bit TxUD Count Direction X 0 0 Count Up X 0 1 Count Down 0 1 0 Count Up 1 1 0 Count Down 0 1 1 Count Down 1 1 1 Count Up Mode compteur : Triggering Edge for Counter Increment/Decrement 0 0 0 None. Counter Tx is disabled 0 0 1 Positive transition (rising edge) on TxIN 0 1 0 Negative transition (falling edge) on TxIN 0 1 1 Any transition (rising or falling edge) on TxIN Tx T2 T3 T4 1 0 0 None. Counter Tx is disabled 101 Positive transition (rising edge) of output toggle latch T3OTL Negative transition (falling edge) of output 110 toggle latch T3OTL 111 89 Any transition (rising or falling edge) of output toggle latch T3OTL T2 & T4 90 15 C167 CR : Timers C167 CR : Timers Gated Timer with Gate active low or high Incremental Interface Mode Timer mode + Input clock gated by the external input pin TxIN Txl TxIN & TxEUD used to interface to an incremental encoder (A & B). Tx clocked by each transition on one or both of the external input pins which gives 22-fold or 44-fold resolution of the encoder input Triggering Edge for Counter Increment/Decrement 0 0 0 None. Counter Tx stops. If T3M.0 = ‘0’, the timer is enabled when T3IN shows a low level. A high level at this pin stops the timer. If T3M.0 = ‘1’, pin T3IN must have a high level in order to enable the timer. 0 0 1 Any transition (rising or falling edge) on TxIN. TxIN. 0 1 0 Any transition (rising or falling edge) on TxEUD. TxEUD. 0 1 1 Any transition (rising or falling edge) on any Tx input (TxIN (TxIN or TxEUD). TxEUD). 1 X X Reserved. Do not use this combination 91 92 C167 CR : Timers C167 CR : Timers Reload Mode (T2 & T4) : → T3 reloaded with T2 or T4, triggered by TxIN or T3OTL (selected by Txl, Txl, as in counter mode) Capture Mode (T2 & T4) : T3 latched into Tx (T2 or T4) in response to a signal transition at TxIN. TxIN. The capture trigger signal can be a positive, a negative, or both both a positive and a negative transition. Txl.0 et Txl.1 are used to select the active transition (as in counter counter mode) Txl.2 must be cleared. 93 C167 CR : Timers 94 C167 CR : Timers Interrupt Control for GPT1 Timers ¾ timer overflows from FFFFH to 0000H (when counting up) up) ¾ timer underflows from 0000H to FFFFH (when counting down) GPT2 T5 et T6 → TxIC Registers 95 96 16 C167 CR : Timers C167 CR : Timers T5 (auxiliaire) et T6 (principal) 16 bits résolution maximale : 8 TCL comptage et décomptage registre de capture/reload capture/reload 16 bits (CAPREL) concaténation possible de T5 sur T6 concaténation possible de l'unité Capture/Compare sur T6 T6I Timer 6 Input Selection Depends on the Operating Mode, see respective sections. T6M Timer 6 Mode Control (Basic Operating Mode) 000: Timer Mode 001: Counter Mode 010: Gated Timer with Gate active low 011: Gated Timer with Gate active high 1XX: Reserved. Reserved. Do not use this combination. combination. T6R Timer 6 Run Bit 0: Timer/ Timer/Counter 6 stops 1: Timer/ Timer/Counter 6 runs 97 98 C167 CR : Timers C167 CR : Timers T6 Mode Timer : T6UD Timer 6 Up/Down Up/Down Control (identique T3) T6UDE Timer 6 External Up/Down Up/Down Enable (identique T3) T6OE Alternate Output Function Enable 0: Alternate Output Function Disabled 1: Alternate Output Function Enabled T6OTL Timer 6 Output Toggle Latch Toggles on each overflow/ overflow/underflow of T6. Can be set or reset by software. T6SR Timer 6 Reload Mode Enable 0: Reload from register CAPREL Disabled 1: Reload from register CAPREL Enabled Mode Compteur : Fréquence de comptage donnée par : Exemple : Si Txl vaut 0 et fCPU = 20 MHz → fTX = 5 MHz (200 ns) Fonctionnement identique à T3. Mode Commandé : Mode timer avec validation du comptage quand T6IN est actif (1 ou 0 selon le mode choisi). 99 100 C167 CR : Timers T5I Timer 5 Input Selection Depends on the Operating Mode, see respective sections. T5M Timer 5 Mode Control (Basic Operating Mode) T5R Timer 5 Run Bit T5UD Timer 5 Up / Down Control T5UDE Timer 5 External Up/Down Up/Down Enable CT3 Timer 3 Capture Trigger Enable 0 : Capture trigger from pin CAPIN 1 : Capture trigger from T3 input pins C167 CR : Timers CI identique T6 identique T6 identique T6 identique T6 T5CLR Timer 5 Clear Bit 0 : Timer 5 not cleared on a capture 1 : Timer 5 is cleared on a capture T5SC 101 Register CAPREL Capture Trigger Selection (depending on bit CT3) 00 : Capture disabled 01 : Positive transition (rising edge) on CAPIN or any transition transition on T3IN 10 : Negative transition (falling edge) on CAPIN or any transition transition on T3EUD 11 : Any transition (rising or falling edge) on CAPIN or any transition transition on T3IN or T3EUD Timer 5 Capture Mode Enable 0 : Capture into register CAPREL disabled 1 : Capture into register CAPREL enabled 102 17 C167 CR : Timers C167 CR : Timers T5 Modes Timer et Commandés • T5 transféré dans CAPREL quand événement sur CAPIN ou sur entrée de T3. 1 kHz 10 Hz En utilisant T6, sortie sur P3.1, FCPU = 20 MHz Mode Rechargement Génération d’un signal carré de : • idem T2 : comptage sur T5IN ou T6OTL Mode Capture Applications : idem T6, sans signal de sortie Mode Compteur CAPREL transféré dans T6 quand dépassement de T6 (passage de FFFFh à 0000h en comptage ou 0000h à FFFFh en décomptage). Registres d'interruption associés : T5IC, T6IC et CRIC. 103 104 C167 CR : Timers C167 CR : Timers Signal carré 1kHz T6.OUT = P3.1 Fcpu = 20 MHz On utilise T6 + mode reload Période max = 65536/FT6 Si T6l = 0 ⇒ 13,1 ms T = 500µs ⇒ N = 2500 cycles T6SR=1 / T6OE=1 / T6UDE=0 / T6UD=1 / T6R=1 / T6M=0 / T6l=0 ⇒ T6CON = 82C0H ; tdtimer.c 1 #include <reg167cr.h> ; tdtimer.c 2 ; tdtimer.c 3 #define Fcpu 2E7 ; tdtimer.c 4 ; tdtimer.c 5 _sfrbit _sfrbit dp3_1 _atbit(DP3,1); _atbit(DP3,1); ; tdtimer.c 6 ; tdtimer.c 7 void Carre1KHz(void Carre1KHz(void)) ; tdtimer.c 8 { PUBLIC _Carre1KHz TDTIMER_1_PR SECTION CODE WORD PUBLIC 'CPROGRAM' _Carre1KHz PROC FAR ; tdtimer.c 9 dp3_1=1; BSET DP3.1 ; tdtimer.c 10 CAPREL=(Fcpu /4*0.5E--3+0.5)CAPREL=(Fcpu/4*0.5E 3+0.5)-1; MOV CAPREL,#09C3h ; tdtimer.c 11 T6CON=0x82C0; MOV T6CON,#082C0h ; tdtimer.c 12 } RETS _Carre1KHz ENDP 105 106 C167 CR : Timers C167 CR : Timers Signal carré 10 Hz T6.OUT = P3.1 Fcpu = 20 MHz On utilise T6 + mode reload Période max = 65536/FT6 Si T6l = 1 ⇒ 26,2 ms / si T6l = 2 ⇒ 52,4 ms T = 50 ms ⇒ N = 62500 cycles T6SR=1 / T6OE=1 / T6UDE=0 / T6UD=1 / T6R=1 / T6M=0 / T6l=2 ⇒ T6CON = 82C2H 107 ; tdtimer.c 14 ; tdtimer.c 15 PUBLIC _Carre10Hz ; tdtimer.c 16 BSET ; tdtimer.c 17 MOV ; tdtimer.c 18 MOV ; tdtimer.c 19 RETS _Carre10Hz void Carre10Hz(void Carre10Hz(void)) { _Carre10Hz PROC FAR dp3_1=1; DP3.1 CAPREL=(Fcpu /4/4*0.05+0.5)--1; CAPREL=(Fcpu/4/4*0.05+0.5) CAPREL,#0F423h T6CON=0x82C2; T6CON,#082C2h } ENDP 108 18 C167 CR : Timers C167 CR : Timers ; tdtimer.c 21 ; tdtimer.c 22 PUBLIC _Rect200_1000 ; tdtimer.c 23 BSET ; tdtimer.c 24 MOV ; tdtimer.c 25 MOV ; tdtimer.c 26 BCLR ; tdtimer.c 27 _26: ; tdtimer.c 28 ; tdtimer.c 29 MOV ; tdtimer.c 30 _27: JNB ; tdtimer.c 31 MOV ; tdtimer.c 32 _28: JB JMPR ; tdtimer.c 33 ; tdtimer.c 34 RETS _Rect200_1000 Applications : Génération d’un signal carré de : • • 1 kHz 10 Hz Génération d’un signal rectangulaire (avec T6) : TBas= Signal rectangulaire 200µs/1ms 1ms / THaut=200µs void Rect200_1000(void Rect200_1000(void)) { _Rect200_1000 PROC FAR dp3_1=1; DP3.1 T6=Fcpu /4*1e--3-1; T6=Fcpu/4*1e T6,#01387h T6CON=0x82C0; T6CON,#082C0h T6OTL=0; T6OTL while(1) while(1) { CAPREL=(Fcpu /4*200e--6+0.5)CAPREL=(Fcpu/4*200e 6+0.5)-1; CAPREL,#03E7h while(!T6OTL); while(!T6OTL); T6OTL,_27 CAPREL=(Fcpu /4*1000e--6+0.5)CAPREL=(Fcpu/4*1000e 6+0.5)-1; CAPREL,#01387h while(T6OTL); while(T6OTL); T6OTL,_28 cc_UC,_26 cc_UC,_26 } } ENDP 109 110 C167 CR : Timers C167 CR : Timers Vitesse instantanée avec un codeur incrémental 400 pts/tour pts/tour Applications : Génération d’un signal carré de : • • 1 kHz 10 Hz Génération d’un signal rectangulaire : Mesure de la vitesse instantanée d’un moteur à l’aide d’un codeur incrémental 400 points/tour. Quelles sont les limitations dans cette mesure de vitesse ? Utiliser T5 & CAPREL Principe : TBas= 1ms / THaut=200µs ω : vitesse de rotation [tours/minute] ⇒ 400ω 400ω/60 points par seconde ⇒ duré durée 1 pas : 60/400ω 60/400ω [s] Nombre d’ d’impulsions obtenues avec une horloge de fré fréquence F : N = 60F/400ω 60F/400ω Avec : 100 < N < 65536 et F = 5MHz, on obtient : 11,4 < ω < 7500 [tr/mn [tr/mn]] T5CON : T5SC=1 / T5CLR=1 / CI=01 / CT3=0 / T5UDE=0 / T5UD=0 / T5R=1 / T5M=0 / T5l=0 [1101 0000 0100 0000] ⇒ T5CON = D040H Image de la vitesse (N) obtenue dans CAPREL 111 112 Compilateur Tasking C166 Compilateur Tasking C166 C Ansi + extensions → efficacité efficacité → adaptation au microcontrôleur C16x 113 Types de données Data Type Size (bytes) Range _bit _sfrbit _esfrbit 1 bit 0 or 1 1 bit 0 or 1 1 bit 0 or 1 114 19 Compilateur Tasking C166 Compilateur Tasking C166 Types de données Types de données Data Type Size (bytes) Range Data Type Size (bytes) Range signed char 1 -128 to +127 2 0 to 65535U unsigned char 1 0 to 255U _sfr _esfr 2 0 to 65535U _xsfr 2 0 to 65535U 115 116 Compilateur Tasking C166 Compilateur Tasking C166 Types de données Data Type signed short unsigned short _bitword signed int unsigned int signed long unsigned long Size (bytes) Range -32768 to +32767 2 0 to 65535U 2 0 to 65535U 2 -32768 to +32767 2 0 to 65535U 2 -2147483648 to +2147483647 4 0 to 4294967295UL 4 Types de données Data Type Size (bytes) float 4 double 8 long double 8 Range +/+/- 1,176E1,176E-38 to +/+/- 3,402E+38 +/+/- 2,225E2,225E-308 to +/+/- 1,797E+308 +/+/- 2,225E2,225E-308 to +/+/- 1,797E+308 117 118 Compilateur Tasking C166 Compilateur Tasking C166 Types de données Data Type Size Définition des registres du microcontrôleur Range #include <reg167cr.h> _near pointer 2 16 bits (64K) when using -Mt/Mt/-Ms 14 bits (16K) when using -Mm/Mm/-Ml (default data group) _xnear pointer 2 14 bits (16K) when using -Mm/Mm/-Ml Not allowed in nonnon-segmented memory models. _far pointer 4 14 bits (16K) in any page (16M) _huge pointer 4 24 bits (16M) _shuge pointer 4 24 bits (16M), but arithmetic is done 1616-bit wide 119 120 20 Compilateur Tasking C166 Compilateur Tasking C166 Extensions du langage _bita Modèle de mémoire far/huge far/huge / shuge data allowed near data allowed <64K no - <64K >64K yes - yes >64K <64K yes yes yes >64K >64K yes yes $SEGM CPU normal code size ENTED segment data size control ed mode Model DPP usage tiny linear no no <64K small linear no yes medium paged yes large paged yes Utilisation de bits dans des entiers ou des structures en RAM bitbit-adressable → optimisation du code Exemples : _bita struct { unsigned bf1:1; unsigned pit:2; pit:2; unsigned bf2:1; } s; _bita int w; 121 122 Compilateur Tasking C166 Compilateur Tasking C166 Extensions du langage _at(adresse) Extensions du langage _atbit( name, offset ) → Indique l'adresse d'une variable globale. Exemples : → définition de bits dans sfrs ou bitwords (uiquement en classe d'allocation statique). Exemples : _near _near int i _at(0x29000); _at(0x29000); _far const char ch _at(0x2A900) _at(0x2A900) = 100; int j, * k _at(0x2B002); _at(0x2B002); int * (* * fptr)( int,, int) fptr)(int int) _at(0x12344); _at(0x12344); _sfr _sfr P0; _sfrbit _sfrbit P0_6 _atbit( _atbit( P0, 6 ); _bitword _bitword bw; bw; /* bitaddressable word */ _bit myb _atbit( _atbit( bw, bw, 3 ); 123 124 Compilateur Tasking C166 Compilateur Tasking C166 Extensions du langage _inline _inline Extensions du langage _interrupt _interrupt → définition de fonctions à utiliser intégrer directement dans le code, sans la procédure d'appel standard. Exemple : _inline _inline int add( add( int a, int b ) { return( a + b ); } void main( void ) { int c = add( add( 1, 2 ); } → définition d'une fonction d'interruption Exemple : _interrupt( _interrupt( 0x22 ) void timer( timer( void ) { ... } 125 126 21 Compilateur Tasking C166 Compilateur Tasking C166 Extensions du langage #pragma asm → insertion de lignes en assembleur terminé par #pragma endasm Syntaxe : Registres utilisés par le compilateur Register R0 #pragma asm [(pseudo_reg [=varname varname][, ][, pseudo_reg[= varname]] ]] ...)] [(pseudo_reg[= pseudo_reg[=varname #pragma endasm [(varname =pseudo_reg[, [(varname= pseudo_reg[, varname= varname=pseudo_reg] pseudo_reg] ...)] avec : varname : nom d'une variable définie en C de type char ou int, int, signée ou non. pseudo_reg : registre écrit sous la forme @[w|b|i]num @[w|b|i]num.. Usage User Stack Pointer (USP) R1R1-R5, R10, R11 General registers (codegen, codegen, temporary results, results, C return values) R6R6-R9 C register variables and saved register parameters R12R12-R15 Fast C parameter passing and C register variables num correspond à un numéro arbitraire de registre. Le compilateur choisira luilui-même le registre adéquat. 127 128 Compilateur Tasking C166 Compilateur Tasking C166 Fonctions intrinsèques → fonctions prédéfinies. Évitent l'utilisation de l'assembleur. Paramètre renvoyé par une fonction : Return type Register(s) Register(s) bit PSW.6 (USR0) char RL4 short/int short/int R4 long R4R4-R5 (R4 low word, word, R5 high word) word) float R4R4-R5 double user stack and R4 structure R4 or R4R4-R5 (near (near or far address) address) near pointer R4 far pointer R4R4-R5 (R4 page offset, R5 page number) number) huge pointer R4R4-R5 (R4 segment offset, R5 segment number) number) shuge pointer R4number) R4-R5 (R4 segment offset, R5 segment number) unsigned int _rol( _rol( unsigned int operand, operand, unsigned int count ); unsigned int _ror( _ror( unsigned int operand, operand, unsigned int count ); _bit _testclear( _testclear( _bit semaphore ); _bit _testset( t( _bit semaphore ); _testse _bit _getbit( _getbit( BITADDR operand, operand, ICE bitoffset ); void _putbit( _putbit( _bit value, BITADDR operand, operand, ICE bitoffset ); void _int166( ICE intno ); Exécute TRAP #intno #intno void _idle( _idle( void ); void _nop( _nop( void ); void _pwrdn( _pwrdn( void ); void _srvwdt( Rafraîchit Watchdog _srvwdt( void ); void _diswdt( Désactive Watchdog _diswdt( void ); void _einit( _einit( void ); void _atomic( _atomic( ICE number ); 129 130 Compilateur Tasking C166 Compilateur Tasking C166 Portabilité Code généré #include <reg167cr.h> //Code généré int fct( fct(int a) { return a*5; } main() { int i,x; for(i=0; i<100; i++); x=i/256*100; i=fct (x); i=fct(x); fct(i); fct(i); } → inclure le fichier C166.h → définit les extensions du langage pour les compilateurs autres que C166 Teste automatiquement le compilateur utilisé grâce à la macro prédéfinie _C166 131 132 22 ; C166/ST10 C compiler v7.5 r2 TASKING, Inc. Inc. ; options: -e -Ic: Ic:\c166\ c166\include -xmifp -DCPUTYPE=0x167 -FSC -OB OE ; -zautobitastructzautobitastruct-4 -zautobitazautobita-0 -zswitch_tabmem_default -s -t ; -zvolatile_union -A1 -O1 -Ms $EXTEND $NOMOD166 $STDNAMES(reg.def $STDNAMES(reg.def)) $CASE $MODEL(SMALL) NAME ESSAI_C ; essai.c 1 ; essai.c 2 #include <reg167cr.h> ; essai.c 3 ; essai.c 4 ; essai.c 5 //Code généré ; essai.c 6 int fct( fct(int a) ; essai.c 7 { PUBLIC _fct _fct ESSAI_1_PR SECTION CODE WORD PUBLIC 'CPROGRAM' _fct FAR _fct PROC ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; a = R12 ; ; essai.c 8 return a*5; MOV R4,R12 SHL R4,#02h ADD R4,R12 ; essai.c 9 } RETS _fct _fct ENDP ; essai.c 10 ; ; essai.c 10 ; essai.c 11 ; essai.c 12 PUBLIC _main PROC ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; i = R12 ; x = R12 ; ; essai.c 13 ; essai.c 14 MOV _3: CMPI1 JMPR ; essai.c 15 MOV ASHR SHR ADD ASHR MOV MUL MOV MOV ; essai.c 16 CALLS MOV ; essai.c 17 JMPS ; essai.c 18 RETV _main ENDP main() { _main FAR Compilateur Tasking C166 Code généré : utilisation de constantes #define Fcpu 20E6 #define T0l 3 //Prédivision //Prédivision par 8 (2^3) #define FT0 (Fcpu /4/(1<<Txl Txl)) )) (Fcpu/4/(1<< #define Dt0 1e1e-3 void InitTim0(void InitTim0(void)) { const unsigned Dt=65536. Dt=65536.--Fcpu*Dt0/(1<<(T0l+3)); T0REL=Dt T0REL=Dt;; } void InitTim0a(unsigned InitTim0a(unsigned Dtms) Dtms) { T0REL=65536./(1<<(T0l+3)); T0REL=65536.-Fcpu*1eFcpu*1e-3*Dtms 3*Dtms/(1<<(T0l+3)); } int i,x; for(i=0; i<100; i++); R12,#00h R12,#063h cc_SLT,_3 cc_SLT,_3 x=i/256*100; R13,R12 R13,#07h R13,#08h R13,R12 R13,#08h R14,#064h R13,R14 R13,MDL R12,R13 i=fct (x); i=fct(x); SEG _fct, _fctt _fct,_fc R12,R4 fct( fct( i ); SEG _fct, _fctt _fct,_fc } 133 ; essai.c 20 ; essai.c 21 ; essai.c 22 ; essai.c 23 ; essai.c 24 ; essai.c 25 ; essai.c 26 PUBLIC _InitTim0 ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; Dt = R12 ; ; essai.c 27 MOV ; essai.c 28 MOV ; essai.c 29 RETS _InitTim0 ; essai.c 30 //Utilisation de constantes #define Fcpu 20E6 #define T0l 3 //Prédivision //Prédivision par 8 (2^3) #define FT0 (Fcpu /4/(1<<Txl Txl)) )) (Fcpu/4/(1<< #define Dt0 1e1e-3 void InitTim0(void InitTim0(void)) { _InitTim0 PROC FAR const unsigned Dt=65536. Dt=65536.--Fcpu*Dt0/(1<<(T0l+3)); R12,#0FEC7h T0REL=Dt T0REL=Dt;; T0REL,R12 } ENDP ; essai.c 31 ; essai.c 32 PUBLIC _InitTim0a ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; Dtms = R12 ; ; essai.c 33 MOV CALLS MOV MOV CALLS MOV MOV MOV CALLS CALLS MOV CALLS MOV MOV CALLS CALLS CALLS ADD MOV ; essai.c 34 RETS _InitTim0a 134 void InitTim0a(unsigned InitTim0a(unsigned Dtms) Dtms) { _InitTim0a PROC FAR Compilateur Tasking C166 Code généré : déclarations de données int decl( decl(void) void) { extern int strlen( strlen(const char *); static int x; int y; register z; char tab[]="toto"; register char *s="titi"; x=2; y=3; z=4; return x+y+z+strlen (s)+strlen strlen(tab); (tab); x+y+z+strlen(s)+ } T0REL=65536./(1<<(T0l+3)); T0REL=65536.-Fcpu*1eFcpu*1e-3*Dtms 3*Dtms/(1<<(T0l+3)); R4,#_8 SEG __load8n,__load8n R11,R10 R4,R12 SEG __cuf28r,__cuf28r R12,R11 R11,R10 R4,#_7 SEG __load8n,__load8n SEG __mlf8r,__mlf8r R11,R12 SEG __dvf8r,__dvf8r R11,R10 R4,#_4 SEG __load8n,__load8n SEG __sbf8r,__sbf8r SEG __cfu82r,__cfu82r R0,#020h T0REL,R4 } ENDP 135 ; essai.c 63 int decl( decl(void) void) ; essai.c 64 { PUBLIC _decl _decl ESSAI_1_PR ENDS ESSAI_2_CO SECTION LDAT WORD PUBLIC 'CROM' _11_INIT LABEL BYTE DB 074h,06Fh,074h,06Fh,00h ESSAI_2_CO ENDS ESSAI_3_NB SECTION LDAT WORD PUBLIC 'CNEAR' ESSAI_3_NB_ENTRY LABEL BYTE _13 LABEL WORD DS 2 ESSAI_3_NB ENDS ESSAI_1_PR SECTION CODE _decl FAR _decl PROC SUB R0,#06h ; Locals: Locals: ; tab = offset 0 ; ; Statics: Statics: ; x = label _13 ; ; CSEs: CSEs: ; s = R12 ; ; essai.c 65 ; essai.c 66 ; essai.c 67 ; essai.c 68 ; essai.c 69 MOV MOV MOV CALLS ; essai.c 70 MOV ; essai.c 71 MOV MOV ; essai.c 72 ; essai.c 73 ; essai.c 74 MOV MOV ADD CALLS MOV MOV CALLS MOV ADD ADD ADD ; essai.c 75 ADD RETS _decl _decl ENDP extern int strlen( strlen(const char *); static int x; int y; register z; char tab[]="toto"; R4,#_11_INIT R10,R0 R3,#05h SEG __cpnnb, __cpnnb,__cpnnb register char *s="titi"; R12,#_12 x=2; R13,#02h _13,R13 y=3; z=4; return x+y+z+strlen (s)+strlen strlen(tab); (tab); x+y+z+strlen(s)+ [-R0],R12 R12,#02h R12,R0 SEG _strlen, _strlen n _strlen,_strle [-R0],R4 R12,[R0+#02H] SEG _strlen, _strlen n _strlen,_strle R12,[R0+] R0,#02h R4,R12 R4,#09h } R0,#06h 136 Compilateur Tasking C166 137 Code généré : élimination du code superflu //Variable x inutilisée void f1(int f1(int y) { int x; x=4*y; } //Variable x inutilisée (volatile) void f2(int f2(int y) { volatile int x; x=4*y; } //Elimination //Elimination du code inutile int f3(int f3(int y) { int a,b,c; a=3; b=4*a+2; c=(b<0); return c+y; } 138 23 ; essai.c 38 ; essai.c 39 ; essai.c 40 PUBLIC _f1 PROC ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; ; essai.c 41 ; essai.c 42 ; essai.c 43 RETS _f1 ENDP ; essai.c 44 ; essai.c 45 ; essai.c 46 ; essai.c 47 PUBLIC _f2 PROC SUB ; Locals: Locals: ; x = offset 0 ; ; Statics: Statics: ; ; CSEs: CSEs: ; y = R12 ; ; essai.c 48 ; essai.c 49 SHL MOV ; essai.c 50 ADD RETS _f2 ENDP //Variable x inutilisée void f1(int f1(int y) { _f1 FAR int x; x=4*y; } //Variable x inutilisée (volatile) void f2(int f2(int y) { _f2 FAR R0,#02h ; essai.c 51 ; essai.c 52 ; essai.c 53 ; essai.c 54 PUBLIC _f3 PROC ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; y = R12 ; ; essai.c 55 ; essai.c 56 ; essai.c 57 ; essai.c 58 ; essai.c 59 MOV ; essai.c 60 RETS _f3 ENDP //Elimination //Elimination du code inutile int f3(int f3(int y) { _f3 FAR Compilateur Tasking C166 Code généré : utilisation de macros #define DIM(x) (sizeof (x)/sizeof sizeof(*x)) (*x)) (sizeof(x)/ int Tab[10]; void InitTab( InitTab(void) void) { int i; for(i=0; i<DIM(Tab); i++) Tab[i]=0; } #define BSET(n,x) ((x)|=(1u<<(n))) #define BCLR(n,x) ((x)&=~(1u<<(n))) void PulseP2_3a(void PulseP2_3a(void)) { BSET(3,P2); BCLR(3,P2); } void PulseP2_3b(void PulseP2_3b(void)) { CC3IO=1; CC3IO=0; } int a,b,c; a=3; b=4*a+2; c=(b<0); return c+y; R4,R12 } volatile int x; x=4*y; R12,#02h [R0],R12 } R0,#02h 139 ; essai.c 87 ; essai.c 88 ; essai.c 89 ; essai.c 90 ; essai.c 91 PUBLIC _InitTab _InitTab ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; i = R12 ; ; essai.c 92 ; essai.c 93 MOV _16: MOV MOV SHL MOV ADD CMP JMPR ; essai.c 94 RETS _InitTab _InitTab ; essai.c 95 ; essai.c 96 ; essai.c 97 ; essai.c 98 ; essai.c 114 ; essai.c 115 PUBLIC _PulseP2_3c ; CSEs: CSEs: ; pUP2 = R12 ; ; essai.c 116 ; essai.c 117 ; essai.c 118 ; essai.c 119 ; essai.c 120 ; essai.c 121 ; essai.c 122 ; essai.c 123 ; essai.c 124 ; essai.c 125 ; essai.c 126 ; essai.c 127 ; essai.c 128 ; essai.c 129 MOV ; essai.c 130 MOV BFLDL MOV ; essai.c 131 MOV AND MOV ; essai.c 132 MOVB MOVB ; essai.c 133 MOV BFLDL MOV ; essai.c 134 RETS _PulseP2_3c ; essai.c 135 #define DIM(x) (sizeof (x)/sizeof sizeof(*x)) (*x)) (sizeof(x)/ int Tab[10]; void InitTab( InitTab(void) void) { _InitTab _InitTab PROC FAR int i; for(i=0; i<DIM(Tab); i++) Tab[i]=0; R12,#00h R13,#00h R14,R12 R14,#01h [R14+#_Ta b],R13 [R14+#_Tab],R13 R12,#01h R12,#0Ah cc_ULT,_16 cc_ULT,_16 } ENDP #define BSET(n,x) ((x)|=(1u<<(n))) #define BCLR(n,x) ((x)&=~(1u<<(n))) void PulseP2_3c(void PulseP2_3c(void)) { _PulseP2_3c PROC FAR typedef union { unsigned word_; word_; struct {unsigned char lsb, lsb,msb;} msb;} byte_; byte_; struct { unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b47:4; }bit_; bit_; }UWord; UWord; UWord *pUP2=(UWord *)(&P2); *pUP2=(UWord*)(&P2); R12,#P2 pUP2pUP2->bit_.b2=1; R13,[R12] R13,#04h,#04h [R12],R13 pUP2pUP2->bit_.b2=0; R13,[R12] R13,#0FFFBh [R12],R13 pUP2pUP2->byte_.msb=0x55; byte_.msb=0x55; RL1,#055h [R12+#01H],RL1 pUP2pUP2->bit_.b47=5; R13,[R12] R13,#0F0h,#050h [R12],R13 } ; essai.c 99 ; essai.c 100 PUBLIC _PulseP2_3a ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; ; essai.c 101 OR ; essai.c 102 AND ; essai.c 103 RETS _PulseP2_3a ; essai.c 104 ; essai.c 105 ; essai.c 106 PUBLIC _PulseP2_3b ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; ; essai.c 107 BSET ; essai.c 108 BCLR ; essai.c 109 RETS _PulseP2_3b ; essai.c 136 ; essai.c 137 PUBLIC _PulseP2_3d ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; ; essai.c 138 ; essai.c 139 BSET ; essai.c 140 BCLR ; essai.c 141 BFLDH ; essai.c 142 BFLDL ; essai.c 143 RETS _PulseP2_3d 140 void PulseP2_3a(void PulseP2_3a(void)) { _PulseP2_3a PROC FAR Compilateur Tasking C166 ENDP void PulseP2_3b(void PulseP2_3b(void)) { _PulseP2_3b PROC FAR CC3IO=1; CC3IO CC3IO=0; CC3IO } ENDP //P2H=55H 141 142 void PulseP2_3d(void PulseP2_3d(void)) { _PulseP2_3d PROC FAR Compilateur Tasking C166 static _sfrbit _sfrbit b2 _atbit(P2,2); _atbit(P2,2); b2=1; P2.2 b2=0; P2.2 _bfld(P2,0xFF00,0x5500); _bfld(P2,0xFF00,0x5500); P2,#0FFh,#055h _bfld(P2,0xF<<4,5<<4); _bfld(P2,0xF<<4,5<<4); P2,#0F0h,#050h } Code généré : utilisation d’unions void PulseP2_3c(void PulseP2_3c(void)) { typedef union { unsigned word_; word_; struct {unsigned char lsb, lsb,msb;} msb;} byte_; byte_; struct { unsigned b0:1; unsigned b1:1; unsigned b2:1; unsigned b3:1; unsigned b47:4; }bit_; bit_; }UWord; UWord; UWord *pUP2=(UWord *)(&P2); *pUP2=(UWord*)(&P2); pUP2pUP2->bit_.b2=1; pUP2pUP2->bit_.b2=0; pUP2byte_.msb=0x55; pUP2->byte_.msb=0x55; pUP2pUP2->bit_.b47=5; } void PulseP2_3d(void PulseP2_3d(void)) { static _sfrbit _sfrbit b2 _atbit(P2,2); _atbit(P2,2); b2=1; b2=0; _bfld(P2,0xFF00,0x5500); _bfld(P2,0xFF00,0x5500); _bfld(P2,0xF<<4,5<<4); _bfld(P2,0xF<<4,5<<4); //P2.7:4=5 } BSET(3,P2); P2,#08h BCLR(3,P2); P2,#0FFF7h } //P2H=55H //P2.7:4=5 ENDP ENDP 143 Code généré : Fonctions inline void inc( inc(int *p) { (*p)++; } _inline int *p) _inline void inc_( inc_(int { (*p)++; } _inline _inline int Add( Add(int a, int b) { return a+b; } int TestIncAdd1(void TestIncAdd1(void)) { int v1=2,v2=3,r; inc(&v1); inc(&v1); inc_(&v1); inc_(&v1); r=Add (v1,v2); r=Add(v1,v2); r+=Add (3,4); r+=Add(3,4); return r; } 144 24 ; essai.c 147 void inc( inc(int *p) ; essai.c 148 { PUBLIC _inc _inc _inc FAR _inc PROC ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; p = R12 ; ; essai.c 149 (*p)++; MOV R13,[R12] ADD R13,#01h MOV [R12],R13 ; essai.c 150 } RETS _inc _inc ENDP ; essai.c 151 ; essai.c 152 _inline int *p) _inline void inc_( inc_(int ; essai.c 153 { ; essai.c 154 (*p)++; ; essai.c 155 } ; essai.c 156 ; essai.c 157 _inline _inline int Add( Add(int a, int b) ; essai.c 158 { ; essai.c 159 return a+b; } ; essai.c 160 ; essai.c 161 ; essai.c 162 int TestIncAdd1(void TestIncAdd1(void)) ; essai.c 163 { PUBLIC _TestIncAdd1 _TestIncAdd1 PROC FAR SUB R0,#02h ; Locals: Locals: ; v1 = offset 0 ; CSEs: CSEs: ; r = R12 ; v2 = R12 ; $inc _#1$p = R13 $inc_#1$p ; ; essai.c 164 MOV MOV MOV ; essai.c 165 MOV MOV ADD CALLS MOV ; essai.c 166 MOV MOV ADD MOV ; essai.c 167 MOV ADD MOV ; essai.c 168 ADD ; essai.c 169 MOV ; essai.c 170 ADD RETS _TestIncAdd1 ; essai.c 171 int TestIncAdd2(void TestIncAdd2(void)) { int tb[]={0,1,2,3},*s= tb;; tb[]={0,1,2,3},*s=tb int v1=2,v2=3,r; inc(s); inc(s); inc_(s); inc_(s); r=Add (v1,v2); r=Add(v1,v2); r+=Add (3,4); r+=Add(3,4); return r; } int v1=2,v2=3,r; R12,#02h [R0],R12 R12,#03h inc(&v1); inc(&v1); [-R0],R12 R12,#02h R12,R0 SEG _inc, _incc _inc,_in R12,[R0+] inc_(&v1); inc_(&v1); R13,R0 R14,[R13] R14,#01h [R13],R14 r=Add (v1,v2); r=Add(v1,v2); R13,[R0] R13,R12 R12,R13 r+=Add (3,4); r+=Add(3,4); R12,#07h return r; R4,R12 } R0,#02h ; essai.c 172 ; essai.c 173 PUBLIC ESSAI_1_PR ESSAI_2_CO EVEN _17_INIT DW ESSAI_2_CO ESSAI_1_PR int TestIncAdd2(void TestIncAdd2(void)) { _TestIncAdd2 ENDS SECTION LDAT LABEL WORD 00h,01h,02h,03h ENDS SECTION CODE ENDP 145 ; essai.c 185 ; essai.c 186 PUBLIC _MulDivU1 ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; b = R13 ; a = R12 ; c = R14 ; ; essai.c 187 MULU DIVU MOV ; essai.c 188 RETS _MulDivU1 ; essai.c 189 ; essai.c 190 ; essai.c 191 PUBLIC _MulDivU2 ; @w1 = R12 ; @w2 = R13 ; @w3 = R14 ; Locals: Locals: ; ; Statics: Statics: ; ; CSEs: CSEs: ; a = R12 ; b = R13 ; c = R14 ; Compilateur Tasking C166 Code généré : Calcul de a*b/c unsigned MulDivU1(unsigned MulDivU1(unsigned a, unsigned b, unsigned c) { return a*b/c; } unsigned MulDivU2(unsigned MulDivU2(unsigned a, unsigned b, unsigned c) { #pragma asm(@w1=a, asm(@w1=a, @2=b, @3=c) MULU @1,@2 DIVLU @3 MOV @1,MDL #pragma endasm(a=@w1) endasm(a=@w1) return a; } unsigned MulDivU1(unsigned MulDivU1(unsigned a, unsigned b, unsigned c) { _MulDivU1 PROC FAR return a*b/c; R12,R13 R14 R4,MDL } ; essai.c 200 _inline _inline unsigned MulDivU3(unsigned MulDivU3(unsigned a, unsigned b, unsigned c) { ; essai.c 201 ; essai.c 202 #pragma asm(@w1=a, asm(@w1=a, @2=b, @3=c) ; essai.c 203 MULU @1,@2 ; essai.c 204 DIVLU @3 ; essai.c 205 MOV @1,MDL ; essai.c 206 #pragma endasm(a=@w1) endasm(a=@w1) ; essai.c 207 return a; ; essai.c 208 } ; essai.c 209 ; essai.c 210 void TestMulDivU3(void TestMulDivU3(void)) ; essai.c 211 { PUBLIC _TestMulDivU3 ESSAI_1_PR ENDS ESSAI_3_NB SECTION LDAT _18 LABEL WORD DS 2 ESSAI_3_NB ENDS ESSAI_1_PR SECTION CODE _TestMulDivU3 PROC FAR ; @w1 = R13 ; @w2 = R14 ; @w3 = R15 ; Locals: Locals: ; ; Statics: Statics: ; r = label _18 ; ; CSEs: CSEs: ; $MulDivU3#1$a = R12 ; a = R13 ; b = R14 ; c = R15 ; ; essai.c 212 static int r; ; essai.c 213 unsigned a=1000,b=200,c=127; MOV R13,#03E8h MOV R14,#0C8h MOV R15,#07Fh ; essai.c 214 r=MulDivU3(a,b,c); MOV R12,R13 MULU R13,R14 DIVLU R15 MOV R13,MDL MOV R12,R13 MOV _18,R12 ; essai.c 215 } RETS _TestMulDivU3 ENDP FAR int tb[]={0,1,2,3},*s= tb;; tb[]={0,1,2,3},*s=tb R4,#_17_INIT R10,R0 R3,#08h SEG __cpnnb, __cpnnb,__cpnnb R12,R0 int v1=2,v2=3,r; inc(s); inc(s); [-R0],R12 SEG _inc, _incc _inc,_in R12,[R0+] inc_(s); inc_(s); R13,[R12] R13,#01h [R12],R13 r=Add (v1,v2); r=Add(v1,v2); r+=Add (3,4); r+=Add(3,4); R12,#0Ch return r; R4,R12 } R0,#08h ENDP 146 ; essai.c 192 #pragma asm(@w1=a, asm(@w1=a, @2=b, @3=c) MULU R12,R13 DIVLU R14 MOV R12,MDL ; essai.c 196 #pragma endasm(a=@w1) endasm(a=@w1) MOV R13,R12 ; essai.c 197 return a; MOV R4,R12 ; essai.c 198 } RETS _MulDivU2 ENDP unsigned MulDivU2(unsigned MulDivU2(unsigned a, unsigned b, unsigned c) { _MulDivU2 PROC FAR 148 Code généré : Interruptions _interrupt( _interrupt( 0x22 ) void ItTimer( ItTimer( void ) { static int ct=0; ct=0; ct++; ct++; } 149 PROC R0,#08h ENDP 147 _inline _inline unsigned MulDivU3(unsigned MulDivU3(unsigned a, unsigned b, unsigned c) { #pragma asm(@w1=a, asm(@w1=a, @2=b, @3=c) MULU @1,@2 DIVLU @3 MOV @1,MDL #pragma endasm(a=@w1) endasm(a=@w1) return a; } void TestMulDivU3(void TestMulDivU3(void)) { static int r; unsigned a=1000,b=200,c=127; r=MulDivU3(a,b,c); } _TestIncAdd2 SUB ; Locals: Locals: ; tb = offset 0 ; ; Statics: Statics: ; ; CSEs: CSEs: ; s = R12 ; r = R12 ; ; essai.c 174 MOV MOV MOV CALLS MOV ; essai.c 175 ; essai.c 176 MOV CALLS MOV ; essai.c 177 MOV ADD MOV ; essai.c 178 ; essai.c 179 MOV ; essai.c 180 MOV ; essai.c 181 ADD RETS _TestIncAdd2 ; essai.c 218 _interrupt( _interrupt( 0x22 ) void ItTimer( ItTimer( void ) ; essai.c 219 { ESSAI_1_PR ENDS ESSAI_IR_NB SECTION PDAT WORD PUBLIC 'CINITROM' ESSAI_IR_NB_ENTRY LABEL BYTE DW 00h ESSAI_IR_NB ENDS ESSAI_ID_NB SECTION LDAT WORD PUBLIC 'CINITIRAM' ESSAI_ID_NB_ENTRY LABEL BYTE _19 LABEL WORD DS 2 ESSAI_ID_NB ENDS ESSAI_1_PR SECTION CODE _ItTimer PROC TASK ESSAI_TASK INTNO ESSAI_INUM = 022h _ItTimer PUSH DPP0 MOV DPP0,#PAG ?BASE_DPP0 PUSH DPP2 MOV DPP2,#PAG ?BASE_DPP2 NOP ; Locals: Locals: ; ; Statics: Statics: ; ct = label _19 ; ; CSEs: CSEs: ; ; essai.c 220 static int ct=0; ct=0; ; essai.c 221 ct++; ct++; SUB _19,ONES ; essai.c 222 } POP DPP2 POP DPP0 RETI _ItTimer ENDP _ItTimer 150 25 C167 CR : Interruptions C167 CR : Interruptions 56 sources d'interruption 16 niveaux de priorité Une interruption sera prise en compte par le CPU si : Cycle d’exécution d’une interruption : l'exécution du programme est suspendue l'état du programme courant est sauvegardé : IP, PSW et CSP (en mode segmenté) sont empilés l'interruption la plus prioritaire est prise en compte la routine d'interruption est exécutée quand l'instruction RETI est trouvée, le contexte initial (IP, PSW et CSP) est récupéré et l'exécution du programme peut continuer. le flag IEN de PSW est à 1 le niveau de priorité de l'interruption demandée est supérieur à celui du CPU (indiqué dans PSW). 151 152 C167 CR : Interruptions C167 CR : Interruptions Source of Interrupt or PEC Service Request Request Flag Enable Flag Interrupt Vector Vector Location Trap Number CAPCOM Register 0 CC0IR CC0IE CC0INT 00’0040H 10H/16D CAPCOM Register 1 CC1IR CC1IE CC1INT 00’0044H 11H/17D PLL/OWD XP3IR XP3IE XP3INT 00’010CH 43H/67D Registres de contrôle des interruptions GLVL Group Level Defines the internal order for simultaneous requests of the same priority. priority. 3: Highest group priority 0: Lowest group priority ILVL Interrupt Priority Level Defines the priority level for the arbitration of requests. requests. IE IR FH: Highest priority level 0H: Lowest priority levelxx levelxx Interrupt Enable Control Bit (individually enables/ enables/disables a specific source) ‘0’: Interrupt request is disabled ‘1’: Interrupt Request is enabledxx enabledxx Interrupt Request Flag ‘0’: No request pending ‘1’: This source has raised an interrupt request 153 154 C167 CR : Interruptions C167 CR : Interruptions Gestion des priorités Les priorités sont gérées par ILVL et GLVL. Si deux interruptions de même niveau sont demandées simultanément, celle dont le niveau défini dans GLVL est supérieur sera prise en compte en premier. Traps traps logiciels Utilisent l'instruction TRAP suivi d'un opérande correspondant à un vecteur d'interruption (entre 0000H et 01FCH). Exécutent le programme d'interruption associé (comme si un périphérique l'avait provoqué). Les flags d'interruption (dans xxIC) xxIC) ne sont cependant pas affectés. Le niveau de priorité du CPU dans PSW n'est pas modifié par un trap logiciel. Il ne doit pas y avoir 2 interruptions définies avec à la fois des ILVL et GLVL identiques. identiques. Une interruption de niveau 0 ne sera pas être prise en compte par par le CPU. 155 156 26 C167 CR : Interruptions C167 CR : Interruptions Traps traps matériels Sont déclenchés automatiquement à la suite d'incidents ou d'états d'états spécifiques du système lors de l'exécution du programme. Ils sont non masquables et ont toujours une priorité supérieure à celle du CPU. Si plusieurs traps matériels sont demandés simultanément, celui de plus forte priorité sera pris en compte en premier. Ils se divisent en deux classes : traps de classe A : NMI, débordements de pile système. Ces traps ont la même priorité, mais des vecteurs différents traps de classe B : code opérateur indéfini, faute de protection, accès accès illégal à un mot, accès illégal au bus externe. Ces traps ont la même priorité, mais un vecteur unique. On peut connaître la cause de déclenchement du trap en consultant le registre TFR. ILLBUS Illegal External Bus Access Flag : An external access has been attempted with no external bus defined. defined. ILLINA Illegal Instruction Access Flag : A branch to an odd address has been attempted. attempted. ILLOPA Illegal Word Operand Access Flag : A word operand access (read or write) write) to an odd address has been attempted. attempted. PRTFLT Protection Fault Flag : A protected instruction with an illegal format has been detected. detected. UNDOPC Undefined Opcode Flag : The currently decoded instruction has no valid C167CR opcode. opcode. STKUF Stack Underflow Flag : The current stack pointer value exceeds the content of register STKUN. STKOF Stack Overflow Flag : The current stack pointer value falls below the content of register STKOV. NMI Non Maskable Interrupt Flag : A negative transition (falling (falling edge) edge) has been detected on pin NMI. 157 C167 CR : PEC C167 CR : PEC Peripheral Event Controller Chaque canal est géré par les registres PECCx, PECCx, SRCPx et DSTPx 8 canaux permettant transfert automatique de données (octets ou mots) à l'intérieur du segment 0 ¾ PEC0 158 à PEC7 Mise en œuvre en association avec interruptions + rapide, - charge CPU que interruptions (programme interrompu pendant un seul cycle) PECC0 PECC1 . . . . . PECC7 SRCP0 SRCP1 . . . . . SRCP7 DSTP0 DSTP1 . . . . . DSTP7 159 160 C167 CR : PEC C167 CR : PEC COUNT → quand COUNT atteint 0, l'interruption standard est déclenchée Previous COUNT COUNT PEC Transfer Count Counts PEC transfers and influences the channel’s action BWT Byte/Word Transfer Selection 0 : Transfer a Word 1 : Transfer a Byte INC Increment Control (Modification of SRCPx or DSTPx) DSTPx) 0 0 : Pointers are not modified 0 1 : Increment DSTPx by 1 or 2 (BWT) 1 0 : Increment SRCPx by 1 or 2 (BWT) 1 1 : Reserved. Do not use this combination. (changed to ‘10’ by hardware) 161 Modified COUNT IR after PEC Service Action of PEC Channel and Comments FFH FFH ‘0’ Move a Byte/Word Continuous transfer mode, i.e. COUNT is not modified FEH … 02H FDH … 01H ‘0’ Move a Byte/Word and decrement COUNT 01H 00H ‘1’ Move a Byte/Word Leave request flag set, which triggers another request 00H 00H (‘1’) No action! Activate interrupt service routine rather than PEC channel. 162 27 C167 CR : PEC C167 CR : Convertisseur A/N PEC activée dans registre xxIC en mettant un niveau de priorité 14 ou 15 (avec count>0) count>0) Le groupe de priorité détermine le canal PEC à utiliser (priorité 14 : PEC 0 à 3, priorité 15 : PEC 4 à 7) Convertisseur A/N 16 entrées analogiques (Port 5) 163 164 C167 CR : Convertisseur A/N C167 CR : Convertisseur A/N 1 convertisseur 10 bits Échantillonneur bloqueur intégré Mode autoauto-scan ADCH ADM 165 C167 CR : Convertisseur A/N ADBSY ADC Busy Flag ADSTC 166 ADC Sample Time Control Defines the ADC sample time : ADC Wait for Read Control Le résultat de conversion doit être lu pour permettre une nouvelle conversion. ADCIN ADCRQ ADC Start Bit 0 : Stop a running conversion 1 : Start conversion(s) conversion(s) C167 CR : Convertisseur A/N 0 : ADC is idle 1 : A conversion is active. ADWR ADC Mode Selection 00 : Fixed Channel Single Conversion 01 : Fixed Channel Continuous Conversion 10 : Auto Scan Single Conversion 11 : Auto Scan Continuous Conversion ADST ADC Analog Channel Input Selection Selects the (first) ADC channel which is to be converted. Note: Valid channel numbers are 0H to FH. ADC Channel Injection Enable ADC Channel Injection Request Flag ADCTC ADC Conversion Time Control (Defines the ADC basic conversion clock fBC) 167 00 : fBC = fCPU / 4 01 : fBC = fCPU / 2 10 : fBC = fCPU / 16 11 : fBC = fCPU / 8 168 28 C167 CR : Convertisseur A/N C167 CR : Convertisseur A/N Conversion sur une voie : mettre à 1 le bit ADST (doit être préalablement à 0) ADBSY passe à 1 indiquant que la conversion est en cours Quand la conversion est terminée, ADBSY passe à 0 et ADCIR passe à 1 Mode conversion continue : la conversion est relancée automatiquement sur le même canal. ADCIR est mis à 1 à chaque fin de conversion Mettre ADST à 0 pour arrêter les conversions (après la conversion en cours) 169 170 C167 CR : Convertisseur A/N C167 CR : Convertisseur A/N Mode autoauto-scan : Conversion d'une séquence de canaux depuis le canal spécifié jusqu'au canal 0 ADCIR passe à 1 à chaque fin de conversion En mode conversion simple, ADBSY passe à 0 quand la séquence est terminée En mode conversion continue, la mise à 0 de ADST arrête la séquence (après la conversion du canal 0) Mode injection de canal : permet de convertir sur un canal pendant une conversion continue → insertion d'une conversion autorisé par ADCIN=1 et ADWR=1 en mode continu l'insertion est effectuée quand ADCRQ est mis à 1, ou par l'intermédiaire de CAPCOM2 171 172 C167 CR : Convertisseur A/N C167 CR : Convertisseur A/N Résultat de conversion 173 Résultat de conversion (injection) 174 29 C167 CR : Convertisseur A/N Interruptions associées ADCIC ADC Conversion Intr.Ctrl.Reg. C167 CR : Convertisseur A/N SFR (FF98H/CCH)Reset (FF98H/CCH)Reset value: --00H --00H ADEIC ADC Error Intr.Ctrl.Reg. SFR (FF9AH/CDH) Application : Reset value: --00H --00H Lecture de la tension analogique sur le canal 5 Chargement d’un tableau par 256 échantillons de la tension présente sur le canal 5. Utilisation du PEC. 175 176 C167 CR : PWM C167 CR : PWM PWM mode centré ou aligné sur fronts résolution de 1 à 16 bits fréquence de porteuse dépend de la résolution choisie Chaque PWM dispose de : 4 signaux PWM indépendants POUT0 à POUT3 P7.0 à P7.3 1 compteur 16 bits (PTx (PTx)) 1 registre de période 16 bits (PPx (PPx)) 1 registre de largeur d'impulsion (PWx (PWx)) 2 comparateurs PWMCON0, PWMCON1 et PWMIC contrôlent les 4 PWM. Les sorties PWM sont combinées en OU exclusif avec les latches de sortie des ports P7.0 à P7.3 → inversion possible des sorties PWM 177 178 C167 CR : PWM PTRx PMx PWM Channel x Mode Control Bit PB01 PWM Channel 0/1 Burst Mode Control Bit PSx PWM Channel x Single Shot Mode Control Bit 0 : Timer PTx clocked with CLKCPU 1 : Timer PTx clocked with CLKCPU/64 0 : Interrupt from channel x disabled 1 : Interrupt from channel x enabled 0 : No interrupt request from channel x 1 : Channel x interrupt pending (must be reset via software) PENxPWM PENxPWM Channel x Output Enable Bit PIRx PWM Channel x Interrupt Request Flag PIEx PWM Channel x Interrupt Enable Flag PWM Timer x Run Control Bit 0 : Timer PTx is disconnected from its input clock 1 : Timer PTx is running PTIx PWM Timer x Input Clock Selection C167 CR : PWM 179 0 : Channel x output signal disabled, disabled, generate interrupt only 1 : Channel x output signal enabled 0 : Channel x operates in mode 0, i.e. edge aligned PWM 1 : Channel x operates in mode 1, i.e. center aligned PWM 0 : Channel 0 and channel 1 work independently in their respective standard mode 1 : Outputs of channels 0 and 1 are ANDed to POUT0 in burst mode 0 : Channel x works in respective standard mode 1 : Channel x operates in single shot mode 180 30 C167 CR : PWM C167 CR : PWM Mode 0 : Mode aligné sur fronts Mode 1 : Mode centré PWM_Period = 2 ([PPx ([PPx]] + 1) PWM_Period = [PPx [PPx]] + 1 181 182 C167 CR : PWM C167 CR : PWM Mode Burst ET logique entre PWM0 et PWM1 Sortie sur POUT0 Mode "Single Shot" Shot" Utilisation des modes centrés ou alignés possibles. POUT1 utilisable. Sur PWM2 ou PWM3 Impulsion unique retardée de tD. tD défini par PWx. PWx. Possibilité de modifier PTx pour modifier la largeur de l'impulsion 183 184 C167 CR : PWM C167 CR : PWM Registres associés aux modules PWM : PW0 : PW1 : PW2 : PW3 : FE30H/18H FE32H/19H FE34H/1AH FE36H/1BH PT0 : PT1 : PT2 : PT3 : PP0 : PP1 : PP2 : PP3 : Application : Génération d’un signal : F030H/18H F032H/19H F034H/1AH F036H/1BH F038H/1CH F03AH/1DH F03CH/1EH F03EH/1FH Valeur moyenne : 3 volts Fréquence de hachage : 10 kHz PWx, PWx, PTx & PPx are not bitaddressable 185 186 31 C167 CR : CAPCOM C167 CR : CAPCOM Capture/Compare 2 unités CAPCOM CAPCOM1 : CC0…CC15 (P2.0 (P2.0 … P2.15) P2.15) CAPCOM2 : CC16…CC31 (P8.0 (P8.0 … P8.7, P1H.4 … P1H.7, P7.4 … P7.7) P7.7) 32 voies, 4 timers (T0, T1, T7, T8) en comptage seulement (pas de décomptage) Capture d'un timer à partir d'un événement interne ou externe Déclenchement d'un événement lorsqu'un timer atteint une valeur prédéfinie Résolution maximum : 8 cycles CPU Horloge des timers avec prédiviseurs programmables, peut provenir de l'overflow l'overflow de T6 T0 et T7 peuvent être mis en compteurs 187 188 C167 CR : CAPCOM Chaque unité CAPCOM contient : C167 CR : CAPCOM 2 timers 16 bits (T0/T1 pour CAPCOM1, T7/T8 pour CAPCOM2) 2 registres de rechargement des timers (TxREL) TxREL) 1 banque de 16 registres de capture/comparaison 16 bits : CC0…CC15 pour CAPCOM1 (P2.0 … P2.15) CC16…CC31 pour CAPCOM2 189 190 C167 CR : CAPCOM C167 CR : CAPCOM T01CON et T78CON permettent de configurer les timers. timers. Quand un timer effectue un overflow (FFFFH → 0000H) → rechargé par TxREL. TxREL. La période correspondante est donnée par : TxI Timer/ Timer/Counter x Input Selection TxM Timer/ Timer/Counter x Mode Selection 0 : Timer Mode (Input derived from internal clock) clock) . > + 3) (<Txl> Input Frequency = fCPU / 2(<Txl 1 : Counter Mode (Input from External Input or T6) TxI : • • • • • TxR 191 000 : Overflow/Underflow of GPT2 Timer 6 001 : Positive (rising (rising)) edge on pin T7IN 1) 010 : Negative (falling) falling) edge on pin T7IN 1) 011 : Any edge (rising and falling) falling) on pin T7IN 1) 1XX : Reserved 1) This selection is available for timers T0 and T7. Timers T1 and T8 will stop at this selection! Timer/ Timer/Counter x Run Control 0 : Timer/ Timer/Counter x is disabled 1 : Timer/ Timer/Counter x is enabled 192 32 C167 CR : CAPCOM C167 CR : CAPCOM CCM0 à CCM7 : Registres de contrôle des unités CAPCOM (8 registres 16 bits). Les CCMx contrôlent chacun 4 registres de capture/comparaison → configuration des 32 modules capture/comparaison CCMx (n = 4⋅x) ACCn Allocation Bit for Capture/Compare Register CCn 0 : CCn allocated to Timer T0 (CAPCOM1) / Timer T7 (CAPCOM2) 1 : CCn allocated to Timer T1 (CAPCOM1) / Timer T8 (CAPCOM2) 193 194 C167 CR : CAPCOM C167 CR : CAPCOM CCMx (n = 4⋅x) CCMODn Selection for Capture/Compare Register CCn 0 0 0 : Disable Capture and Compare Modes. The respective CAPCOM register may be used for general variable storage. storage. 0 0 1 : Capture on Positive Transition (Rising (Rising Edge) Edge) at Pin CCnIO 0 1 0 : Capture on Negative Transition (Falling (Falling Edge) Edge) at Pin CCnIO 0 1 1 : Capture on Positive and Negative Transition (Both (Both Edges) Edges) at Pin CCnIO 1 0 0 : Compare Mode 0: Interrupt Only. Only. Several interrupts per timer period (CCx updated during the timer period); period); Enables doubledouble-register compare mode for registers CC8 … CC15 and CC24 … CC31 if the corresponding bank 1 register is programmed to compare mode 1. CCMx (n = 4⋅x) CCMODn Selection for Capture/Compare Register CCn 1 0 1 : Compare Mode 1: Toggle Output Pin on each Match. Several compare events per timer period; This mode is required for double - register compare mode for registers CC0 … CC7 and CC16 … CC23 if the corresponding corresponding bank 2 register is programmed to compare mode 0. 1 1 0 : Compare Mode 2: Interrupt Only. Only one interrupt per timer period period (After the first match, even when the compare register is reloaded with a value higher than the current timer value, no compare event will occur until the allocated timer overflows). 1 1 1 : Compare Mode 3: Set Output Pin on each Match. When the first match match within the timer period is detected the interrupt request flag CCxIR is set to ‘1’ and also the output pin CCxIO will be set to ‘1’. The pin will be reset to ‘0’, when the allocated timer overflows. Only one interrupt per timer period. 195 C167 CR : CAPCOM 196 C167 CR : Interface CAN Application : Mesure de la durée d’une impulsion CAN Controller Area Network Développé au milieu des années 80 par BOSCH ΔT ? Génération d’une impulsion de 10µs 197 198 33 C167 CR : Interface CAN C167 CR : Interface CAN Faible coût : Bus série à 2 fils (1 paire torsadée) Nombreux dispositifs faible coût disponibles dans l'automobile et pour l'industrie Fiabilité : Détection d'erreur sophistiquée et gestion des erreurs Exemple : 500kbit/s, charge bus 25%, 2000 heures/an → 1 erreur détectée tous les mille ans Messages erronés détectés et répétés Chaque nœud du bus est informé en cas d'erreur Immunité élevée aux perturbations électromagnétiques 199 200 C167 CR : Interface CAN C167 CR : Interface CAN Compatible temps réel : Messages courts (0 à 8 octets de données par message) Faible temps de latence entre la demande de transmission et le début réel de la transmission Arbitrage intégré de la priorité des messages Bus multimulti-maître : Souplesse et rapidité : Les nœuds peuvent être facilement connectés et déconnectés Le nombre de nœuds n'est pas limité par le protocole Débit maximum de 1 MBit/s (bus de 40 m) et environ 40 kBit/s kBit/s (bus de 1000 m) Chaque nœud peut demander l'accès au bus Les communications ne sont pas perturbées par un nœud défaillant Les nœuds défaillants sont automatiquement déconnectés du bus 201 202 C167 CR : Interface CAN C167 CR : Interface CAN Performance en communication : Les messages peuvent s'adresser à un ou plusieurs nœuds Tous les nœuds reçoivent simultanément les messages communs Bus standard : Certifié par ISOISO-DIS 11898 (applications à haute vitesse) Certifié par ISOISO-DIS 1151911519-2 (low (low speed applications à faible vitesse) 203 204 34 C167 CR : Interface CAN C167 CR : Interface CAN Structure : Bus série asynchrone de structure linéaire avec des nœuds identiques L'adresse des nœuds est comprise dans le message, avec le niveau de priorité 2 états : récessif (niveau 1) et dominant (niveau 0) Chaque nœud est placé en parallèle sur le bus en ET câblé Détection de collision avec arbitrage non destructif 205 206 C167 CR : Interface CAN C167 CR : Interface CAN Utilisation de trames Identificateur C167 CR : Interface CAN - Identificateur sur 11 bits (CAN specification 2.0A) Trames étendues : 207 CRC Trame standard : Un seul nœud est "parleur", les autres sont "écouteurs". Donnée (0 à 8 octets) - Identificateur sur 29 bits (CAN specification 2.0B) 208 C167 CR : STK16x500 C167CR : Starter kit STK16x500 Compatible CAN 2.0B Taux de transfert maximum : 1 MBit/s Gestion de 15 messages (en émission ou réception) permettant filtrage Seul un transceiver est nécessaire pour la mise en œuvre. 209 210 35 C167 CR : STK16x500 211 36 BUS I²C I. Description • • • • • • Développé initialement par Philips Bus de type série synchrone o Bidirectionnel o Multi maîtres o Multi points o Chaque point a une adresse 2 fils (+ GND) : o SDA : données o SCL : horloge Lignes bidirectionnelles o Collecteur ouvert (nécessite une résistance de tirage) o Au repos : état haut Vitesse : o standard : 100 kbits/s o rapide (fast) : 400 kbits/s o très rapide (high speed) : 3,4 Mbits/s Versions : o 1.0 (1992) : suppression de la possibilité de programmer l’adresse d’un point mode fast ajouté format d’adresse sur 10 bits ajouté o 2.0 (1998) : mode high speed (Hs-mode) ajouté adaptation pour dispositifs alimentés en 2 volts o 2.1 (2000) : modification des timings du mode Hs II. Spécifications • SDA doit être stable quand SCL=1 SDA peut changer quand SCL=0 • Début de message : START (S) o Front montant sur SDA quand SCL=1 Fin de message : STOP (P) o Front descendant de SDA quand SCL=1 • • START et STOP sont générés par le maître o START ⇒ bus occupé o STOP ⇒ bus devient libre (après un délai) III. Transfert des données • • • • Par octet 8 bits transmis (b7 en tête), puis bit acknowledge (ACK) ACK : o L’émetteur met la ligne SDA à 1 o Le récepteur met la ligne SDA à 0 o Le maître génère l’impulsion d’horloge o Si un esclave souhaite marquer une pause (gestion interne), il peut forcer SCL à 0 pour forcer le maître à attendre o Si un esclave ne génère pas ACK sur son adresse (par ex. s’il est occupé), ACK doit rester à 1. Le maître peut alors générer : Un STOP (fin du transfert) Un START (nouveau transfert) o Si un esclave génère un ACK sur son adresse, puis sur les données suivantes et qu’à un instant donné il cesse de générer ACK : le maître doit cesser le transfert possibilité transmission plusieurs octets (bit ACK toujours présent) Transfert de données sur le bus ACK sur le bus Transfert de données complet Format avec adresse sur 7 bits • • • • • Chaque point a une adresse propre sur 7 bits Le maître envoie : o START o L’adresse de l’esclave sur 7 bits (b6 en tête) o Le sens du transfert sur 1 bit (R/W) L’esclave doit générer ACK Les données sont transférées (terminées par ACK, sauf éventuellement la dernière) Le maître envoie STOP Émission de données du maître vers un esclave Réception de données de l’esclave vers le maître Format combiné (Lectures / écritures successives) IV. Chronogrammes PARAMETER SYMBOL STANDARD-MODE MIN. FAST-MODE MAX. MIN. UNIT MAX. SCL clock frequency fSCL 0 100 0 400 kHz Hold time (repeated) START condition. After this period, the first clock pulse is generated tHD;STA 4.0 – 0.6 - ms LOW period of the SCL clock tLOW 4.7 – 1.3 – ms HIGH period of the SCL clock tHIGH 4.0 – 0.6 – ms Set-up time for a repeated START condition tSU;STA 4.7 – 0.6 – ms Data hold time: for CBUS compatible masters for I2C-bus devices tHD;DAT 5.0 0(2) – 3.45(3) – 0.9(3) ms ms Data set-up time tSU;DAT 250 - – 0(2) 100(4) – ns Rise time of both SDA and SCL signals tr – 1000 20 + 0.1Cb(5) 300 ns Fall time of both SDA and SCL signals tf – 300 20 + 0.1Cb(5) 300 ns Set-up time for STOP condition tSU;STO 4.0 – 0.6 – ms Bus free time between a STOP and START condition tBUF 4.7 – 1.3 – ms Capacitive load for each bus line Cb – 400 – 400 pF Noise margin at the LOW level for each connected device (including hysteresis) VnL 0.1VDD – 0.1VDD – V Noise margin at the HIGH level for each connected device (including hysteresis) VnH 0.2VDD – 0.2VDD – V 1. All values referred to VIHmin and VILmax levels (see Table 4). 2. A device must internally provide a hold time of at least 300 ns for the SDA signal (referred to the VIHmin of the SCL signal) to bridge the undefined region of the falling edge of SCL. 3. The maximum tHD;DAT has only to be met if the device does not stretch the LOW period (tLOW) of the SCL signal. 4. A Fast-mode I2C-bus device can be used in a Standard-mode I2C-bus system, but the requirement tSU;DAT ³ 250 ns must then be met. This will automatically be the case if the device does not stretch the LOW period of the SCL signal. If such a device does stretch the LOW period of the SCL signal, it must output the next data bit to the SDA line tr max + tSU;DAT = 1000 + 250 = 1250 ns (according to the Standard-mode I2C-bus specification) before the SCL line is released. 5. Cb = total capacitance of one bus line in pF. If mixed with Hs-mode devices, faster fall-times according to Table 6 are allowed. V. Mise en œuvre unsigned char I2cInit(void); • Initialisation du bus I²C void I2cStart(void); • Génère START sur le bus I²C unsigned char I2cMasterWrite(unsigned char x); • Émission de x sur le bus I²C • Renvoie 1 si ACK reçu, 0 sinon unsigned char I2cMasterRead(unsigned char ack) ; • Réception d’un octet sur le bus I²C • ack : état de ACK à générer après la réception de l’octet (0 : ACK, 1 : NOACK) • Renvoie l’octet reçu unsigned char I2cStop(void); • Génère STOP sur le bus I²C • Renvoie 0 si Ok, 1 sinon (SCL maintenue à 0 par ???) VI. Travaux pratiques • Horloge Temps Réel PCF8563 (Philips) [ad=0x51] • Mémoire 24C65 (Microchip) [ad=0x50] • Convertisseur numérique/analogique DAC5571 [ad=0x4C] • SDA : P3.2 SCL : P3.3 • RTC PCF8563 The PCF8563 contains sixteen 8-bit registers with an auto-incrementing address register, an on-chip 32.768 kHz oscillator with one integrated capacitor, a frequency divider which provides the source clock for the Real Time Clock/calender (RTC), a programmable clock output, a timer, an alarm, a voltage-low detector and a 400 kHz I2C-bus interface. All 16 registers are designed as addressable 8-bit parallel registers although not all bits are implemented. The first two registers (memory address 00H and 01H) are used as control and/or status registers. The memory addresses 02H through 08H are used as counters for the clock function (seconds up to years counters). Address locations 09H through 0CH contain alarm registers which define the conditions for an alarm. Address 0DH controls the CLKOUT output frequency. 0EH and 0FH are the timer control and timer registers, respectively. The seconds, minutes, hours, days, weekdays, months, years as well as the minute alarm, hour alarm, day alarm and weekday alarm registers are all coded in BCD format. When one of the RTC registers is read the contents of all counters are frozen. Therefore, faulty reading of the clock/calendar during a carry condition is prevented. Master transmits to slave receiver (write mode) : Master reads after setting word address (write word address; read data). • 24C65 64K 5.0V I2C™Smart Serial™ EEPROM o Device Addressing A control byte is the first byte received following the start condition from the master device. The control byte consists of a four bit control code, for the 24C65 this is set as 1010 binary for read and write operations. The next three bits of the control byte are the device select bits (A2, A1, A0). They are used by the master device to select which of the eight devices are to be accessed. These bits are in effect the three most significant bits of the word address. The last bit of the control byte (R/W) defines the operation to be performed. When set to a one a read operation is selected, when set to a zero a write operation is selected. The next two bytes received define the address of the first data byte (Figure 4-1). Because only A12..A0 are used, the upper three address bits must be zeros. The most significant bit of the most significant byte is transferred first. Following the start condition, the 24C65 monitors the SDA bus checking the device type identifier being transmitted. Upon receiving a 1010 code and appropriate device select bits, the slave device (24C65) outputs an acknowledge signal on the SDA line. Depending upon the state of the R/W bit, the 24C65 will select a read or write operation. o Byte Write Following the start condition from the master, the control code (four bits), the device select (three bits), and the R/W bit which is a logic low is placed onto the bus by the master transmitter. This indicates to the addressed slave receiver (24C65) that a byte with a word address will follow after it has generated an acknowledge bit during the ninth clock cycle. Therefore the next byte transmitted by the master is the high-order byte of the word address and will be written into the address pointer of the 24C65. The next byte is the least significant address byte. After receiving another acknowledge signal from the 24C65 the master device will transmit the data word to be written into the addressed memory location. The 24C65 acknowledges again and the master generates a stop condition. This initiates the internal write cycle, and during this time the 24C65 will not generate acknowledge signals (Figure 4-1). FIGURE 4-1: BYTE WRITE o Random Read Random read operations allow the master to access any memory location in a random manner. To perform this type of read operation, first the word address must be set. This is done by sending the word address to the 24C65 as part of a write operation (R/W bit set to 0). After the word address is sent, the master generates a start condition following the acknowledge. This terminates the write operation, but not before the internal address pointer is set. Then the master issues the control byte again but with the R/W bit set to a one. The 24C65 will then issue an acknowledge and transmit the eight bit data word. The master will not acknowledge the transfer but does generate a stop condition which causes the 24C65 to discontinue transmission (Figure 4-4). FIGURE 4-4: RANDOM READ • DAC5571 8-BIT DIGITAL-TO-ANALOG CONVERTER The DAC5571 contains four separate modes of operation. These modes are programmable via two bits (PD1 and PD0). When both bits are set to zero, the device works normally with normal power consumption of 150 µA at 5 V. However, for the three power-down modes, the supply current falls to 200 nA at 5 V (50 nA at 3 V). Not only does the supply current fall but the output stage is also internally switched from the output of the amplifier to a resistor network of known values. This has the advantage that the output impedance of the device is known while in power-down mode. There are three different options: The output is connected internally to AGND through a 1-kΩ resistor, a 100kΩ resistor, or it is left open-circuited (high impedance). Réalisation d’un noyau temps réel multi-tâches But : • • • • • Activation « simultanée » de plusieurs processus Contrôle du temps de cycle Système multi-tâches préemptif Gestion des priorités, synchronisations Réalisation en langage évolué (C) sur microcontrôleur C167 Principe : L’ordonnanceur des tâches (scheduler) est construit à partir d’une interruption périodique déclenchée par un timer. À chaque interruption, on interrompt la tâche en cours et on bascule sur la tâche suivante : Interruption 1 4 2 5 6 3 Tâche 1 Tâche 2 Tâche 3 Les numéros indiquent l’ordre d’exécution lors du déclenchement des interruptions Répartition des tâches au cours du temps : Tâche 1 Tâche 2 Tâche 3 ∆t1 ∆t2 ∆t3 ∆t1 ∆t2 ∆t3 ∆t1 t Remarques : • La tâche 2 occupe plus d’espace de temps sur un cycle : elle est prioritaire. Son processus s’exécutera le plus rapidement. Inversement, la tâche 3 sera la plus lente. • L’ordonnanceur est réalisé par une interruption (placée sur chaque trait vertical). Cette interruption doit être la plus rapide possible, afin de ne pas empiéter sur les temps d’exécution des tâches « utiles ». Plus le découpage temporel est rapide, plus le temps relatif dédié à la gestion du système devient significatif : on observe alors une perte d’efficacité. Réalisation pratique : • Une tâche est constituée d’une fonction standard (pouvant bien sûr appeler d’autres fonctions). o Les fonctions seront réentrantes (pas de données statiques, sauf nécessité) o La fonction principale n’aura pas de point de sortie. On pourra mettre fin à son exécution en appelant une fonction spécifique (de gestion du noyau temps réel). • Pour réaliser l’opération de commutation des tâches, on utilise une interruption (la plus prioritaire possible) déclenchée par un timer (T3). Il est nécessaire de bien maîtriser le mécanisme de fonctionnement des interruptions. Rappel : • Lorsqu’une interruption est prise en compte par le processeur : o le traitement du programme en cours est arrêté (momentanément) o les registres PSW, CSP et IP sont empilés par le processeur (dans cet ordre) PSW contient l’état du processeur juste avant la prise en compte de l’interruption CSP est le registre contenant le segment programme en cours d’utilisation (uniquement en mode segmenté) IP contient l’adresse de l’instruction qui aurait due être exécutée, en l’absence d’interruption. o Le champ ILVL de PSW mémorise le niveau d’interruption en cours, afin de prévenir toute interruption de niveau inférieur ou égal à celle en cours de traitement. o Le programmeur traite à partir de ce moment l’action qui doit être réalisée par l’interruption On doit préalablement sauvegarder tous les registres utilisés par l’interruption, afin que celle-ci s’exécute de manière transparente : Elle ne doit pas perturber le traitement du programme interrompu. De manière classique, on utilise la pile pour effectuer cette sauvegarde de contexte. Lorsque le traitement est terminé, le contexte doit être restitué. L’instruction RETI est alors utilisée afin de reprendre le cours normal du programme. o RETI effectue les actions suivantes : Récupération de IP depuis la pile (IP reprend alors l’adresse permettant de poursuivre le programme initial) Récupération de CSP (on revient dans le segment de programme initial) Récupération de PSW initial o Le programme initial reprend à l’endroit où il avait été interrompu. À partir de l’observation de ce mécanisme, la réalisation du basculement des tâches paraît simple : il suffit de modifier l’adresse de retour dans la pile, pendant le fonctionnement de l’interruption, pour permettre de poursuivre l’exécution d’une autre tâche à la fin de l’interruption… En réalité, pour que ce mécanisme puisse fonctionner, il faut que les tâches ne perçoivent pas les interruptions qui correspondent en réalité à l’exécution des autres tâches. La difficulté essentielle réside, lors du basculement des tâches à sauvegarder le contexte de la tâche en cours et à récupérer le contexte de la tâche suivante à activer. Quel est le contexte lié à une tâche ? • Les registres PSW, CSP et IP • Tous les registres du processeur (R0 à R15) et CP (adresse de base des registres) • Les registres DDP0 à DDP3 (segments de pages de données) • Les registres MDC, MDH et MDL (utilisés par les multiplications et divisions) • Les espaces de pile utilisés par chaque tâche doivent être indépendants (voir ci-après). Il faut donc sauvegarder les registres de gestion de pile (SP, STKUN et STKOV). • De même, si les tâches utilisent des « piles utilisateurs », ces dernières doivent être propres à chaque tâche et leur pointeur de gestion devra être sauvegardé. Données empilées par la tâche A Nécessité d’utiliser une pile propre à chaque tâche : Dans le cas où une pile commune serait utilisée, lors de l’interruption de la tâche A, on obtiendrait dans la pile : PSW CSP Sommet de pile (SP) Contexte de A IP Données empilées par la tâche A Suite à la commutation de tâche, on bascule sur la tâche B. En fin d’interruption, on obtient alors : PSW CSP Sommet de pile (SP) Contexte de B IP Si la tâche B avait empilé des données préalablement à l’interruption, elle ne les retrouverait pas : elle récupère les données empilées par A. Il est donc nécessaire de créer des espaces de pile distincts pour chaque tâche. Code généré : Observation du code généré par le compilateur Tasking C166 lors d’une interruption (modèle Small) : Source C : _interrupt(0x23)(1) _using(iTT3_RB)(2) void iTT3(void) { T3=2000; } Notes : (1). _interrupt permet de générer un code supplémentaire au niveau de la fonction afin de sauvegarder le contexte. Cette dernière sera terminée par l’instruction RETI. 0x23 correspond au numéro du vecteur d’interruption liée au timer 3 du C167 (2). _using(xxx) demande au compilateur de créer et d’utiliser un espace de registres propre à la fonction d’interruption. Cet espace sera situé à l’adresse désignée par xxx. Code généré : ; test.c 6 _interrupt(0x23) _using(iTT3_RB) void iTT3(void) ; test.c 7 { _iTT3 PROC TASK TEST_TASK INTNO TEST_INUM = 023h MOV iTT3_RB,R0(1) Charge le nouveau jeu de registre (basé en iTT3_RB) (2) SCXT CP,#iTT3_RB Sauvegarde et initialisation de MDC (pour mult. & divisions) SCXT MDC,#010h PUSH DPP0 MOV DPP0,#PAG ?BASE_DPP0 Sauvegarde des registres de pages de données PUSH DPP2 MOV DPP2,#PAG ?BASE_DPP2 PUSH MDH Sauvegarde de MDH et MDL (pour mult. & divisions) PUSH MDL ; test.c 9 T3=2000; Traitement de l’interruption (écrit par le programmeur) MOV T3,#07D0h ; test.c 10 } POP MDL POP MDH POP DPP2 Récupération du contexte POP DPP0 POP MDC POP CP Retour au programme initial (qui a été interrompu) RETI _iTT3 ENDP Notes : (1). R0 est une pile utilisateur (gestion du tas en C). La valeur courante de R0 est placée à la base des registres dans le nouveau jeu de registres utilisé par l’interruption : cela rend le tas accessible par la routine d’interruption. (2). SCXT reg,#val sauvegarde dans la pile système le registre reg. Puis, ce registre est chargé par la valeur indiquée. Données empilées par la tâche en cours d’exécution La configuration de la pile est donc la suivante, au début du traitement effectif de l’interruption : PSW CSP IP CP MDC DDP0 DDP2 MDH SP Le contexte total à sauvegarder est donc composé de : • 9 mots empilés par le compilateur (de MDL à PSW) • SP, STKUN et STKOV • R0 (pile utilisateur) MDL Pour chaque tâche, les espaces mémoires suivants devront être réservés : • Une pile système • Un jeu de registres (16 mots) • Une pile utilisateur Pour définir une tâche, il faudra au minimum les informations suivantes : • Le nom de la fonction associée (un pointeur sur la fonction) • Un indicateur de priorité (par exemple le nombre de cycles d’exécution à chaque découpage temporel) • Un indicateur d’activité (une tâche peut être active ou non) • Un indicateur de demande d’activité (une tâche peut être démarrée par une autre tâche) Ce qui se transcrit en C : #define DIM(x) (sizeof(x)/sizeof(*x)) #define SZ_CONTEXTE 9 typedef struct { void (*fct)(void); unsigned dt; unsigned pile[48]; unsigned regs[16]; unsigned contexte[SZ_CONTEXTE] ; unsigned sp,spun,spov; unsigned *usp; struct { unsigned active:1; unsigned requete:1; }etat; }T_TACHE; // // // // // pile système espace de registres sauvegarde du contexte pointeurs de pile et gestion débordements pointe sur pile utilisateur // état d'activation // activation demandée _iram T_TACHE TACHE[]= { {fct1,10000}, {fct2,20000} }; // Tableau des tâches (en RAM interne ... // ... pour pile et registres) // Tâche A avec priorité // Tâche B (exécution 2 fois plus rapide) #define NBT DIM(TACHE) // Nombre de tâches définies T_TACHE *T; // Pointe sur la tâche en cours unsigned USPT[NBT][256]; // Pile utilisateur pour chaque tâche Avant de démarrer le système, il est nécessaire de réaliser quelques initialisations, comme indiqué dans la fonction suivante : void InitKernel(void) { char i; T_TACHE *t=TACHE; SYSCON|=0xE000; //Pile linéaire (au lieu de circulaire, par défaut) T=t; // Initialisation du ptr de tâche global for(i=0; i<NBT; i++) { t->sp=(unsigned)(t->pile+DIM(t->pile)); // Init. sp au sommet de pile t->usp=USPT[i]+DIM(USPT[i]); // Init pile utilisateur au sommet t->etat.active=0; // La tâche n’est pas active t->etat.requete=1; // On demande l’activation au démarrage t++; } T3=T->dt; // Initialisation Timer 3 (prochaine iT) T3CON=0x00C0; // T3 : Timer décompteur à Fcpu/8 T3IC=0x77; // [01 1101 11] iT niv.13/gr3 } Commutation des tâches : Pour réaliser le basculement des tâches, il est nécessaire de réaliser les sauvegardes et récupération des contextes complets des tâches. Ceci est réalisé de la manière suivante : • Sauvegarde du contexte de la tâche en cours d’exécution (si elle est active) • Recherche de la prochaine tâche à activer (dans la liste des tâches) • Si la tâche est en cours d’exécution (elle a déjà été activée) : récupération du contexte. Sinon, initialisations pour réaliser le premier appel de la tâche • Programmer l’instant de la prochaine interruption (selon la priorité affectée à la tâche). Sauvegarde du contexte de la tâche en cours : unsigned *ps,*pd ; ps=(unsigned *)SP; // (unsigned*) nécessaire car SP défini unsigned T->sp=SP; // sauvegarde valeur de SP T->spov=STKOV; // sauvegarde des limites de pile (STKOV T->spun=STKUN; // et STKUN) pd=T->contexte; // où sauvegarder le contexte... CopieContexte(pd,pd+SZ_CONTEXTE,ps); // copie du contexte placé dans la pile La fonction CopieContexte est définie ainsi : _inline void CopieContexte(unsigned *pd, unsigned *pdf, unsigned *ps) { while(pd!=pdf) *(pd++)=*(ps++); } Paramètres : • pd : pointeur vers la zone destination (où s’effectue l’écriture) • ps : pointeur vers la zone source (mémoire lue) • pdf : fin de la zone destination (après la zone destination) Mémoire destination pd Mémoire source pdf ps _inline a été choisi pour • une meilleure efficacité • éviter l’usage de la pile (SP) pour l’appel de la fonction et la transmission des paramètres : En effet, cette fonction est destinée à réaliser des sauvegardes et restitutions de la mémoire avec la pile, ce qui serait rendu plus compliqué si elle-même utilisait la pile. Recherche de la prochaine tâche : T_TACHE *t0; t0=T; do { T++; if(T==TACHE+NBT) T=TACHE; if(T->etat.active) { ……………………………………………………………… break; } if(T->etat.requete) { ……………………………………………………………… break; } }while(T!=t0); // Partir de la tâche en cours // Commencer la recherche // // // // // // Passer à la tâche suivante Si fin de liste : revenir au début Si la tâche est déjà active ... Récupération contexte tâche ...... Quitter (la tâche va se poursuivre) // Si la tâche n’est pas encore active, mais qu’elle // doit démarrer // Démarrage tâche // Quitter (la tâche va démarrer) // Faire la recherche tant que l’on est pas revenu // à la tâche initiale. Récupération du contexte d’une tâche active : Les données ont été mémorisées lors d’une précédente sauvegarde. Elles sont donc restituées simplement de la manière suivante : STKOV=T->spov; STKUN=T->spun; SP=T->sp; ps=(unsigned *)T->sp; pd=(unsigned *)SP; CopieContexte(pd,pd+SZ_CONTEXTE,ps); Note : • Lorsque l’on modifie SP, il est nécessaire de modifier également les registres STKOV et STKUN. Pendant ce temps, on veille à ne pas modifier SP, sans quoi le système de protection de pile peut être déclenché. Lancement d’une nouvelle tâche : static unsigned contexte[9] ; unsigned *ps,*pd,spun,spov; Initialisation de la pile dans la nouvelle tâche (les variables spun et spov sont nécessaires ca, lors der leur affectation, le compilateur fait appel à une fonction interne et modifie donc SP. Voir note précédente) : spov=(unsigned)(T->pile); spun=(unsigned)(T->pile+DIM(T->pile)); SP=(unsigned)(T->pile+DIM(T->pile)-SZ_CONTEXTE); STKOV=spov; STKUN=spun; Récupération d’un contexte initial (celui de la fonction main) : ps=contexte; pd=(unsigned *)SP; CopieContexte(pd,pd+SZ_CONTEXTE,ps); Modification de IP dans la pile -> on donne l’adresse de la tâche à exécuter : pd[6]=(unsigned)(T->fct); Indication de la localisation des registres (modification de la valeur de CP dans la pile) : pd[5]=(unsigned)(T->regs); Mise à jour du registre R0 dans la pile utilisateur liée à la tâche : *(T->regs)=(unsigned)(T->usp); La tâche devient active : T->etat.active=1; La requête d’activation a été prise en compte : T->etat.requete=0; Prochaine interruption : Pour gérer les priorités, chaque tâche s’exécute pendant un laps de temps qui lui est propre. On recharge le timer 3 à une valeur prédéfinie pour la tâche en cours : T3=T->dt; Le timer se décrémente au rythme de Fcpu/8. Lorsqu’il atteint 0, la prochaine interruption est déclenchée. Par exemple, si T->dt a la valeur 10000 et que Fcpu vaut 20 MHz, la durée résultante est de 4 ms. Cela signifie que cette tâche s’exécutera par tranches de 4 ms. Écriture de la fonction d’interruption complète : _interrupt(0x23) void iTT3(void) { static unsigned contexte[9],*ps,*pd,spun,spov; // static utilisé pour éviter static T_TACHE *t0; // l’utilisation de la pile if(!T->etat.active) // pas de tache active { // sauvegarde contexte "main" ps=(unsigned *)SP; pd=contexte; CopieContexte(pd,pd+SZ_CONTEXTE,ps); } else // si la tâche en cours est active { // sauvegarde contexte ps=(unsigned *)SP; T->sp=SP; T->spov=STKOV; T->spun=STKUN; pd=T->contexte; CopieContexte(pd,pd+SZ_CONTEXTE,ps); } t0=T; do { T++; if(T==TACHE+NBT) T=TACHE; if(T->etat.active) { //Récupération contexte tâche STKOV=T->spov; STKUN=T->spun; SP=T->sp; ps=(unsigned *)T->sp; pd=(unsigned *)SP; CopieContexte(pd,pd+SZ_CONTEXTE,ps); break; } if(T->etat.requete) { // démarrage tâche spov=(unsigned)(T->pile); spun=(unsigned)(T->pile+DIM(T->pile)); SP=(unsigned)(T->pile+DIM(T->pile)-SZ_CONTEXTE); STKOV=spov; STKUN=spun; ps=contexte; pd=(unsigned *)SP; CopieContexte(pd,pd+SZ_CONTEXTE,ps); pd[6]=(unsigned)(T->fct); pd[5]=(unsigned)(T->regs); *(T->regs)=(unsigned)(T->usp); T->etat.active=1; T->etat.requete=0; break; } }while(T!=t0); T3=T->dt; }