version 15/05/2025
rev 25/05/2025
Test MCP23017 avec PIC 18F27K42
ce test est en rapport avec le sujet : commande de Portail , sur Fantaspic
Hardware :
MCP23017
configuration
Prototype
complet
Test
INTB MCP23017
Chronometrage
de chaque changement d'etat port MB
Test
ecriture sur port MA MCP23017 +
clignotement
Hardware :
Alimentation VCC= 5V
Carte Base 18F27K42
Led sur RA4 ..PIC18F
Fosc interne 64Mhz
MCP23017 sur breadboard
2 BP N.O. sur entree MB1 pin2 et MB34 pin 4
UART1 115200bds TX sur RC6, RX sur RC7
1 led sur MA4 pin 25
YAT terminal sur PC
Prolific TTL/USB cable
Pickit4 programmer
MCP23017 expander 16 I/O
sur bus I2C
Prototype de test sur breadboard
Schema partie MCP
Adresse I2C1 7 bits : 0x22
Prototype complet :
PIC Config via MCC :
MCP23017 Configuration
attention:
notation PortB pour le port B du PIC18F , mais MB pour le portB
du MCP23017
Le MCP23017 est piloté en I2C à l'adresse (7bits) 0x22 ( pins
adresses : A0=0,A1=1,A2=0)
Le port MB est configuré en (8) entrées
Le port MA en (8)sorties
Un changement d'etat sur le PORT MB genere une interruption via
lla sortie INT B du MCP.
Registres du MCP23017 :
/TABLE 1-6: CONTROL REGISTER SUMMARY (IOCON.BANK = 0)
// page 11
#define MCP23017_ADDR 0x22 // adresse 7 bits ! (A0=0 A1=1 A2=0 )
#define MCP_IODIRA 0x00
#define MCP_IODIRB 0x01
#define MCP_IPOLA 0x02
#define MCP_IPOLB 0x03
#define MCP_GPINTENA 0x04
#define MCP_GPINTENB 0x05
#define MCP_DEFVALA 0x06
#define MCP_DEFVALB 0x07
#define MCP_INTCONA 0x08
#define MCP_INTCONB 0x09
#define MCP_IOCONA 0x0A
#define MCP_IOCONB 0x0B
#define MCP_GPPUA 0x0C
#define MCP_GPPUB 0x0D
#define MCP_INTFA 0x0E
#define MCP_INTFB 0x0F
#define MCP_INTCAPA 0X10
#define MCP_INTCAPB 0x11
#define MCP_GPIOA 0x12
#define MCP_GPIOB 0x13
#define MCP_OLATA 0x14
#define MCP_OLATB 0x15
Datasheet MCP23017_features_01043a.pdf
//
--- Init MCP23017 pour interruptions sur PORT MB
void MCP23017_Init(void) {
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_IODIRB, 0xFF); //
IODIRB = 0xFF (entrée)
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_GPINTENB, 0xFF); //
Interrupt-on-change
I2C1_Write1ByteRegister(MCP23017_ADDR,MCP_DEFVALB,0xFF);
I2C1_Write1ByteRegister(MCP23017_ADDR,MCP_GPPUB,0xFF);
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_INTCONB, 0x00); //
Comparaison avec l'état précédent
//I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_INTCONB, 0xFF); //
Comparaison avec l'étatDEFVALB
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_IOCONB,0x44); // Bank=0
INTB active low, open-drain
}
INTB MCP23017 relié à pin B1 du Port B PIC18F27K42
armement interruptions coté PIC
void __interrupt(irq(IRQ_IOC),high_priority) IOC_ISR(void)
{
unsigned char i;
const
char *p2="ALERT\r\n";
if ( (IOCCF & 0x01)==1) // RC0
{
Led_Rouge=0; // allume led
k1_PWM=0;
k2_PWM=0;
PWM1_LoadDutyValue(k1_PWM); // plus de cde PWM sur le PONT H
PWM2_LoadDutyValue(k2_PWM);
IOCCF = 0x00;
}
if ((IOCBF & 0x02)==2) // RB1 <-INTB du MCP23017
{ mcp_timestamp = SMT1_GetTimeUs();
// Lecture "temps réel" dans l'ISR
mcp_flag = true;
IOCBF = 0x00;
}
}
* le traitement RC0 a un lien avec le
traitement Surcharge Amperes du capteur INA229
On memorise le chrono (SMT1) en cours à l' instant de l'interrupt
INTB
Test du flag Interruption MCP23017 INTB
par interruption IOCB pin B1 du PIC18F
if (mcp_flag)
{
IT_Flag=I2C1_Read1ByteRegister(MCP23017_ADDR,MCP_INTFB);
CAPB=I2C1_Read1ByteRegister(MCP23017_ADDR,MCP_INTCAPB);
MCP_B = MCP23017_ReadGPIOB();
sprintf(CRam1," %lu.%lu mS IT_Flag = 0x%02X CAPB= 0x%02X",mcp_timestamp/1000,mcp_timestamp%1000,
IT_Flag ,CAPB); // ok
Print(CRam1);
CRLF1();
mcp_flag = false;
}
le test INTB est OK
!
le compteur SMT1 24 bits sert à chronometrer, certains
évenements ou parties de codes.
exemple capture d'appui sur les Switches BP 2 et 4:
(0.640) N= 19 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
(0.590) 6453.495 mS IT_Flag = 0x00
CAPB= 0x02
(0.065) N= 20 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
(0.136) 6535.074 mS IT_Flag = 0x00
CAPB= 0x02
(0.521) N= 21 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
(0.649) N= 22 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
(0.144) 7133.053 mS IT_Flag = 0x00
CAPB= 0x08
(0.000) 7212.565 mS IT_Flag = 0x00 CAPB= 0x08
(0.522) N= 23 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
nota : on recupere quelle est la PIN MCP qui a générer l'interrupt
et quel éait l'etat du port MB à cet instant
Problemes rencontrés :
Probleme sur Affichage des valeurs IT_Flag et CAPB
issues de la capture du flag INTB MC23017
OK avec
sprintf(CRam1," %lu.%03d mS IT_Flag
= 0x%02X CAPB= 0x%02X",mcp_timestamp/1000,mcp_timestamp%1000,IT_Flag,CAPB);
CAPB est bien vu à 0x02
(13:42:08.922) N= 21 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
MCP_B = 0xFF
(13:42:09.561) N= 22 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
MCP_B = 0xFF
(13:42:10.213) N= 23 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
7231.436 mS IT_Flag = 0x00 CAPB= 0x02
(13:42:10.860) N= 24 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
MCP_B = 0xFF
MAIS bad avec
sprintf(CRam1," %lu.%03d mS CAPB=
0x%02X",mcp_timestamp/1000,mcp_timestamp%1000,CAPB); //
bad
CAPB est vu à 0x00 au lieu de 0x02
(13:45:07.669) N= 41 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
MCP_B = 0xFD
(13:45:08.320) N= 42 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
13507.815 mS CAPB= 0x00
(13:45:08.964) N= 43 PWM1= 0 PWM2= 0 4.99 V 0.001 A . Seuil=0.600
MCP_B = 0xFF
En fait le vrai probleme est en amont, sur l'affichage
de mcp_timestamp, valeur unsigned long 32 bits..
et le resultat de mcp_timestamp%1000 que
j'avais considré comme un int , puisque toujours inferieur à
1000 !
mais comme mcp_timestamp est un uL , le formattage devait etre
perturbé, par 1 seule valeur 8 bits suivante..
alord que dans le test plus haut , j'ajoutait 2 valeurs 8 bits =16
bits ..bref , la cause exacte est enfouie dans le compilo !
Remede :
Caster le resulat de Mcp_timestamp%1000 en un unsigned Long
sprintf(CRam1," %lu.%lu
mS CAPB= 0x%02X",mcp_timestamp/1000,mcp_timestamp%1000,CAPB);
OK !
Probleme majeur :
impossibilite de lire la valeur du port MB via l'interruption
IOCB1
car l'I2C1 n'est pas ré-entrant.
On ne peut lire le port MCP23017 QUE dans le MAIN ...
il s'ensuit un décalage temporel lié à la durée de la boucle
principale , seule la datation de l'évenement
est temps réel ..mais pas le traitement ,qui sera Asynchrone, en
retard , par rapport à l'évenement.
un peu de lectrure sur 5.1.2.1
Reentrancy - onlinedocs.microchip.com
Contre mesure :
multiplier l'occurence du test du flag dans le main program ...mais
il faudrait AUSSI multiplier l'action lié
à l'evenement => donc INTB
inutile, uniquement lire le MCP en pooling dans
la boucle main..
sauf à l'utiliser directement pour une réaction au niveau
Hardware ...
ou pour verifier un sequencement temporel ...
Diminuer tous les temps morts de la boucle principale ..
Les Evenements critiques ne doivent donc pas etre concernés par
un resultat
de fonction NON réentrante ou récurssive.
Nota :
L'interrupt RC0 est OK, car c'est la sortie hardware du INA226
qui l'envoie et que le traitement n' a pas de lien avec
la lecture I2C de l'INA226 ....
Le code lié à ce test comporte aussi :
*la gestion d'un LCD 4x20 cars sur I2C1 ,
* module ITB2 driver de puissace pour moteur DC ( ici en 12V) ,piloté
par 2 sortie PWM1 et PWM2 du PIC
* module de mesure Courant (et tension) moteur INA226 piloté via
I2C1, avec sortie ALERT sur RC0 du PIC18F
(utilise un shunt 15Amp 150mv soit 0,01 ohm)
ALERT message à 0,6Amps (testé en frainant le rotor) =>
actions : arret par Enable=0 et Cdes PWM à zero.
* Liaison UART permettant de regler plusieurs valeurs de PWM1=xxxx
et PWM2, et faire la commande M/A moteur: MA=1 ou MA=0
Affiche aussi Umoteur,I moteur ,PWM1,PWM2 ,et l'etat MCP23017
*gestion du chronometre utilisant le compteur SMT1 24 bits à +-1µS.
Init_I2C() 100Khz;
Test presence devices sur Bus I2C1
@ decimal # 68 soit @Device 7bits = 0X22
MCP23017 2 ports 8bits
@ decimal # 78 soit @Device 7bits = 0X27 PCF8754 for LCD 2x16cars
@ decimal # 128 soit @Device 7bits = 0X40 INA226 Current sensor
exemple d'affichage sur YAT terminal
(0.580) N= 40 PWM1= 0
PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.581) N= 41 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.579) N= 42 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.580) N= 43 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.152) 12605.143 mS CAPB= 0xFD IT_Flag = 0x02
(0.063) N= 44 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.161) 12718.454 mS CAPB= 0xFF IT_Flag = 0x02
(0.052) N= 45 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.554) N= 46 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.581) N= 47 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
..............
(0.135) MA=1
(0.423) Recu :MA=1
(0.060) ITB2 Enabled
(0.000) N= 94 PWM1= 500 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
(0.582) N= 122 PWM1= 500 PWM2= 0 5.34 V 0.034 A
. Seuil=0.600
(0.581) N= 123 PWM1= 500 PWM2= 0 5.34 V 0.032 A . Seuil=0.600
(0.582) N= 124 PWM1= 500 PWM2= 0 5.34 V 0.033 A . Seuil=0.600
(0.581) N= 125 PWM1= 500 PWM2= 0 5.34 V 0.033 A . Seuil=0.600
(0.232) PWM1=1000
(0.326) Recu :PWM1=1000
(0.009) Saisie OK PWM1-RC2 1000 98.0%
(0.051) N= 126 PWM1= 1000 PWM2= 0 5.34 V 0.034 A . Seuil=0.600
(0.585) N= 127 PWM1= 1000 PWM2= 0 5.30 V 0.070 A . Seuil=0.600
(0.579) N= 128 PWM1= 1000 PWM2= 0 5.29 V 0.082 A . Seuil=0.600
(0.581) N= 129 PWM1= 1000 PWM2= 0 5.24 V 0.139 A
. Seuil=0.600
.......
(0.583) N= 149 PWM1= 1000 PWM2= 0 12.17 V 0.085 A . Seuil=0.600
(0.583) N= 150 PWM1= 1000 PWM2= 0 12.08 V 0.160 A . Seuil=0.600
(0.583) N= 151 PWM1= 1000 PWM2= 0 12.00 V 0.531
A . Seuil=0.600 ...freinage moteur
(0.258) ALERT
(0.324) N= 152 PWM1= 0PWM2= 0 0.00 V -0.001 A . Seuil=0.600
1ere valeur entre parenthese = durée boucle
principale ~ 580mS
Lancement du programme :
Presentation :
BASE 18F27K42 + LCD4X20+ PWM1,2,3,4 Analog RA0,1,2,3
Directory :C:\MPLABX_Projects\18F27K42_PMW_CCP1234_2025
Project : 18F27K42_PMW_CCP1234_2025
Source : main.c , rev :_250512
Config Internal Fosc 64MHz
Autres :
LCD_4bits_I2C_2025-05, UART1_Functions.h , mcc.h,
A inclure:
Dialogue_Operateur_PC_via_UART_2023-0905
LCD_chars_Speciaux_2024.h, Eeprom : Eeprom...........
Hardware : BASE 18F27K42, I2C1: LCD4x20,INA226,IBT 2 Mosfet,MCP23017
+ UART1
Schema: Carte_Portail_2_Vantaux_24v_H-en-MOSFET_INA226-HIP4082_FQP30N06L_V5.0.3.pdf
by H.T.
Compiled May 12 2025 at 11:58:09 UTC version XC8
:2360
Init_I2C() 100Khz;
Test presence devices sur Bus I2C1
@ decimal # 68 soit @Device 7bits = 0X22
MCP23017 2 ports 8bits
@ decimal # 78 soit @Device 7bits = 0X27 PCF8754 for LCD 2x16cars
@ decimal # 128 soit @Device 7bits = 0X40 INA226 Current sensor
version Prototype : LCD Bleu a l'adresse 0x27 !
adresse LCD= 39 soit 0X27
Sequence d'Init LCD 4x20 via I2C1 PCF8574
.123456789A
Initialisation PWM1,2 avec FReq 3,9KHz (Timer2)
* PWM1 sur RC2 (TMR2)=0%
* PWM2 sur RC1 (TMR2)=0%
Init INA226 mesure de courant via I2C, shunt de
150mV pou 15Amps
Config INA226_CONF_REG,0x43FF (was 0x4127 )
Calibration register 05h (pour shunt 0,01 ohm et 8 Amps)
Mask/Alert MASK_EN_REG register 06h <- 0x8001
Alert MASK_EN_REG register 07h <- 2400 pour
0.6 A
Mesure de courant 0 mA
Seuil d'alerte 0.600 Amperes
INA Manufactuer 0x5449
INA Identifiant 0x2260
Fin de parametrage INA226... OK
Init MCP23017
Test differentes valeurs de Duty-cycle via le clavier terminal
YAT
Activer la sortie PWMy avec MA=1 (arret via MA=0)
Entrer une valeur PWMy=xxxx puis <enter> avec y=1 ou 2 au
clavier
Init SMT1 compteur 24b
Test chrono avec TMR6 x 10 boucles
Init TRM6 100mS
.......... SMT1 Nb Tics 1000102
Fin tempo de 1 sec via TMR6
N= 0 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
N= 1 PWM1= 0 PWM2= 0 0.00 V -0.001 A . Seuil=0.600
Chronometrage avec SMT1 compteur 24 bits
Chronometrage_via_SMT1.inc
Exemple
txt=&TEXTE[0];
CPrint("\r\n Test chrono avec TMR6 x 10 boucles\r\n");
CPrint(" Init TRM6 100mS\r\n");
TMR6_Init_100ms();
Start_Chrono();
do
{
PrintChar('.');
__delay_ms(25);
}
while(Cpt6<10);
Stop_Chrono(1);
Resultat :
Test chrono avec TMR6 x 10 boucles
Init TRM6 100mS
..................................... SMT1 Nb Tics 1025230 uS
Fin tempo de 1 sec via TMR6
nota : +2,5mS ! mesuré sur tempo 1sec
mais avec modif OSCTUNE=0x10
nouvelle essai donne
Test chrono avec TMR6 x 10 boucles
Init TRM6 100mS
........................................ SMT1 Nb Tics 1000336
uS
Fin tempo de 1 sec via TMR6
Les valeurs réelles obtenues pour les tempo , dependent de FOSC interne 64MHz qui peut etre ajustée
de +- 3%
surement meilleur avec un oscillateur à QUARTZ !
rev : 15/05/2025
MPLAB IDE 6.0 et XC8
Directory: C:\MPLABX_Projects\18F27K42_PMW_CCP1234_2025
Project : 18F27K42_PMW_CCP1234_2025-0512.X.zip
main : main_18F27K42_MCP23017_0512.X.c
Chargeur : 18F27K42_PMW_CCP1234_2025-0512.X.hex
Test
Ecriture sur port MA MCP23017
Hardware
Init
3 leds tirées au Gnd sur PORTA Pin 21,22,23
//Mask
pour MCP_OLATA
#define Flash 1
#define Sirene 2
#define Buzzer 4
volatile int Clignote=0;
// pour test des sorties MCP_A avec terminal
volatile uint8_t Flash_Out=0;
volatile uint8_t Sirene_Out=0;
volatile uint8_t Buzzer_Out=0;
// variable de travail, pour stockage valeurs registres
MCP
volatile uint8_t MCP_A=0;
volatile uint8_t MCP_B=0;
volatile uint8_t IT_Flag;
volatile uint8_t CAPB;
volatile bool mcp_flag = false;
Fonctions MCP23017 :
uint8_t MCP23017_ReadGPIOB(void);
void new_MCP23017_Init(void);
void MCP23017_Write_Register(uint8_t registre, uint8_t donnee);
void MCP23017_SetBits_PORTA(uint8_t mask, uint8_t state);
Initialisation du MCP23017_Init(void)
void
MCP23017_Init (void) {
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_IODIRA, 0x00); //
IODIRA = 0x00 (Sorties)
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_OLATA, 0x07); //leds
tirées au + sur 0,1,2 outputs
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_IODIRB, 0xFF); //
IODIRB = 0xFF (entrée)
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_GPINTENB, 0xFF); //
Interrupt-on-change
I2C1_Write1ByteRegister(MCP23017_ADDR,MCP_DEFVALB,0xFF);
I2C1_Write1ByteRegister(MCP23017_ADDR,MCP_GPPUB,0xFF);
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_INTCONB, 0x00); //
Comparaison avec l'état précédent
//I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_INTCONB, 0xFF); //
Comparaison avec l'étatDEFVALB
I2C1_Write1ByteRegister(MCP23017_ADDR, MCP_IOCONB,0x44); // Bank=0
INTB active low, open-drain
}
Lecture du PORTB du MCP23017
uint8_t
MCP23017_ReadGPIOB(void) {
uint8_t value;
value = I2C1_Read1ByteRegister(MCP23017_ADDR, MCP_GPIOB);
return value;
}
Ecriture sur MCP23017
void
MCP23017_Write_Register(uint8_t registre, uint8_t donnee)
{
I2C1_Write1ByteRegister(MCP23017_ADDR, registre,donnee);
}
Ecriture sur 1 ou plusieurs bits du port MA MCP23017
void
MCP23017_SetBits_PORTA(uint8_t mask, uint8_t state)
{
uint8_t Etat_EnCours = I2C1_Read1ByteRegister(MCP23017_ADDR, MCP_GPIOA);
uint8_t Nouvel_Etat=0;
if (state) {
Nouvel_Etat= Etat_EnCours | mask; // Mise à 1 des bits
spécifiés par le masque
} else {
Nouvel_Etat= Etat_EnCours & ~mask; // Mise à 0 des bits
spécifiés par le masque
}
MCP23017_Write_Register(MCP_OLATA, Nouvel_Etat);
}
exemple de Commande d'une sortie MCP MA
// test sortie "Flash" sur Port MA MCP23017
la variable Clignote regroupe les flags de clignotement
correspondants au bits à 1 du port de sortie.
si la sortie est à 1 , et que le Flag est est à 1 => celle
ci clignote
au rythme de la duree de boucle principale ..avec test Nb_Boucles
pair
( on pourrait aussi utiliser TMR6 et Bit500mS)
On peut ainsi faire clignoter une ou plusieurs sorties..
A chaque tour de boucle, s'affiche sur le terminal ,
exmple:
N= 123 PWM1= 750 PWM2= 0 14.19 V 0.057
A . Seuil=0.600 Flash Buz* MA=0x05 MB=0xFF
le N° de boucle, la consigne PWM1 et PWM2, la tension Moteur, le
courant moteur, le seuil d'alerte,
sortie Fla ,Sir,Buz sir à l'etat ON , plus le caractere * si
elle clignote , la valeur du port de sortie MA, et du port d'entree
MB
La frequence du clignotement est issue de la duree de la boucle
principale, ici <600mS
La mesure INA , le rafraichissement des cdes PWM se fait aussi à
chaque tour de boucle..
Affichage terminal YAT
Fichier de configuration Terminal : Terminal_MCP23017_test_2025-0520.yacp
Modif dialogue Operateur
Dialogue_UART_MCP23017_2025-0520.inc
rajout possibilité de modifier le seuil ALERT INA226
if ( (*(p0)=='S') && (*(p0+1)=='L') && ( *(p0+2)=='=')
& ( *(p0+3)=='0') & ( *(p0+4)=='.') )
{
cx=*(p0+5);
if ( (cx>'0') & (cx<'9'))
{
CPrint(" Nouveau Seuil=0.");
PrintChar(cx);
cx=cx-48;
// Alert MASK_EN_REG register 07h <- 2400 pour 0.6 A
// 2400 pour 0.6Amps
k=(uint8_t)cx*400;
tmp[0]=INA226_ALERT_LIMIT_REG;
tmp[1]=(k >> 8);
tmp[2]=(uint8_t)(k & 0x00FF);
Addr=INA226_ADDR;
p1=&tmp[0];
cx=3;
I2C1_WriteNBytes(Addr, p1, cx);
Addr= INA226_ADDR;
tmp[0]=0;
tmp[1]=0;
p1=&tmp[0];
I2C1_ReadDataBlock(Addr, INA226_ALERT_LIMIT_REG, p1,3);
k=(tmp[0]<<8) + tmp[1];
//Seuil_Alerte= 8.192 * (double)k / 32768.0;
Seuil_Alerte= (double)k / 4.0;
sprintf(CRam1," Seuil d'alerte %3.3f Amperes\r\n",Seuil_Alerte);
Print(CRam1);
}
else
{
CPrint(" Erreur parametre\r\n" );
}
if(cx=='0') Clignote=0;
CRLF1();
p0=0;
}
Flag_Buffer1=0;
}
rev :21/05/2025
MPLAB IDE 6.0 et XC8
Directory: C:\MPLABX_Projects\18F27K42_PMW_CCP1234_2025
Project : 18F27K42_PMW_CCP1234_2025-0521.X.zip
main : main_18F27K42_MCP23017_0521.X.c
à suivre aussi ICI