Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Autres architectures Assembleur Discussion :

[8051] Une petite carte multifonction utile en dépannage et à la maison


Sujet :

Autres architectures Assembleur

  1. #1
    Membre actif
    [8051] Une petite carte multifonction utile en dépannage et à la maison
    Bonjour à tous,

    Je profite de ce confinement forcé pour reprendre mes projets électroniques qui dorment sur mes étagères.

    Et en particulier ma carte à microcontrôleur à base de 8051 que j'ai fabriquée... en mars 2002

    Je n'avais pas réussi à la faire fonctionner à l'époque, et je n'ai pas eu le temps de m'y consacrer ensuite.
    J'ai toujours regretté de ne pas avoir terminé ce projet.
    Ensuite j'ai terminé mes études et trouvé un travail dans lequel je ne programme pas ou alors seulement des macros en VBA de temps en temps.
    Bien sûr j'ai quelques projets perso.

    Le microcontrôleur est une puce ATMEL AT89C2051, avec 2Ko de ROM flash, et 15 broches d'E/S.

    Je voulais gérer un afficheur LCD et un clavier 8 touches avec les 7 bits accessibles du port P3, en laissant le port P1 entièrement libre pour des extensions.

    La programmation en assembleur c'est assez sportif, surtout avec seulement 2Ko de ROM. En plus sur cette carte pas d'ISP à chaque fois il faut retirer la puce et la mettre dans le programmeur.
    La programmation, c'était pas mieux avant

    Les interruptions apportent leur lot de surprises (surtout quand les broches ont plusieurs fonctions , et qu'on essaye de gérer des boutons poussoirs avec des rebonds ) il est parfois préférable de ne pas y recourir et de gérer un maximum de choses dans une boucle principale.

    Toutes les variables sont globales, et on programme tout avec des GOTO...
    Un choc pour moi qui d'habitude devellope avec C# ou VB.net en tachant de respecter au mieux la POO...
    Ça permet d'optimiser au maximum, mais le débogage est atroce

    Je me suis bien amusé avec cette carte !

    J'ai optimisé le code du mieux que je pouvais, j'ai réussi à faire une dizaine de fonctions :
    - minuterie
    - chien de garde
    - double compteur (compte le nombre d’événements et la durée totale à l'état 1)
    - BP et inter antirebond
    - porte logique à 7 entrées
    - générateur ASCII, gray, décimal
    - double commande de moteurs pas à pas
    - le menu principal permet de visualiser l'état du port P1 en binaire avec des leds, en hexadécimal et en décimal

    L'assembleur apporte la satisfaction de faire un maximum de choses avec un minimum de ressources matérielles

    Je me suis senti un peu dans la peau des développeurs des années 80 et 90 à l'époque où il fait faire tourner des logiciels et des jeux sur des ordinateurs avec peu de mémoire et de capacité de calcul. Je suis né en 1980, j'ai commencé l'informatique avec un Amiga 1200, une merveilleuse machine, les programmeurs de l'époque ont fait des logiciels et des jeux magnifiques avec peu de ressources. J'ai connu l'époque des "démos" ou des hackers arrivaient à pousser les machines dans leurs limites pour faire de la 3D ou afficher plus de couleurs que ce que la machine permettait à l'origine.

    Au niveau électronique la carte fait office d'alimentation secourue grâce à la pile ; il y a un buzzer et des dip switchs utilisables par le programme mais aussi par une extension extérieure.

    Voici le schéma :



    Voici quelques photos de la carte :







    Il y a une petite vidéo de démonstration ici : https://drive.google.com/open?id=1bb...UngshvbDolpfp6

    Voici le code source en assembleur - j'utilise toute la ROM flash de 2ko :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    736
    737
    738
    739
    740
    741
    742
    743
    744
    745
    746
    747
    748
    749
    750
    751
    752
    753
    754
    755
    756
    757
    758
    759
    760
    761
    762
    763
    764
    765
    766
    767
    768
    769
    770
    771
    772
    773
    774
    775
    776
    777
    778
    779
    780
    781
    782
    783
    784
    785
    786
    787
    788
    789
    790
    791
    792
    793
    794
    795
    796
    797
    798
    799
    800
    801
    802
    803
    804
    805
    806
    807
    808
    809
    810
    811
    812
    813
    814
    815
    816
    817
    818
    819
    820
    821
    822
    823
    824
    825
    826
    827
    828
    829
    830
    831
    832
    833
    834
    835
    836
    837
    838
    839
    840
    841
    842
    843
    844
    845
    846
    847
    848
    849
    850
    851
    852
    853
    854
    855
    856
    857
    858
    859
    860
    861
    862
    863
    864
    865
    866
    867
    868
    869
    870
    871
    872
    873
    874
    875
    876
    877
    878
    879
    880
    881
    882
    883
    884
    885
    886
    887
    888
    889
    890
    891
    892
    893
    894
    895
    896
    897
    898
    899
    900
    901
    902
    903
    904
    905
    906
    907
    908
    909
    910
    911
    912
    913
    914
    915
    916
    917
    918
    919
    920
    921
    922
    923
    924
    925
    926
    927
    928
    929
    930
    931
    932
    933
    934
    935
    936
    937
    938
    939
    940
    941
    942
    943
    944
    945
    946
    947
    948
    949
    950
    951
    952
    953
    954
    955
    956
    957
    958
    959
    960
    961
    962
    963
    964
    965
    966
    967
    968
    969
    970
    971
    972
    973
    974
    975
    976
    977
    978
    979
    980
    981
    982
    983
    984
    985
    986
    987
    988
    989
    990
    991
    992
    993
    994
    995
    996
    997
    998
    999
    1000
    1001
    1002
    1003
    1004
    1005
    1006
    1007
    1008
    1009
    1010
    1011
    1012
    1013
    1014
    1015
    1016
    1017
    1018
    1019
    1020
    1021
    1022
    1023
    1024
    1025
    1026
    1027
    1028
    1029
    1030
    1031
    1032
    1033
    1034
    1035
    1036
    1037
    1038
    1039
    1040
    1041
    1042
    1043
    1044
    1045
    1046
    1047
    1048
    1049
    1050
    1051
    1052
    1053
    1054
    1055
    1056
    1057
    1058
    1059
    1060
    1061
    1062
    1063
    1064
    1065
    1066
    1067
    1068
    1069
    1070
    1071
    1072
    1073
    1074
    1075
    1076
    1077
    1078
    1079
    1080
    1081
    1082
    1083
    1084
    1085
    1086
    1087
    1088
    1089
    1090
    1091
    1092
    1093
    1094
    1095
    1096
    1097
    1098
    1099
    1100
    1101
    1102
    1103
    1104
    1105
    1106
    1107
    1108
    1109
    1110
    1111
    1112
    1113
    1114
    1115
    1116
    1117
    1118
    1119
    1120
    1121
    1122
    1123
    1124
    1125
    1126
    1127
    1128
    1129
    1130
    1131
    1132
    1133
    1134
    1135
    1136
    1137
    1138
    1139
    1140
    1141
    1142
    1143
    1144
    1145
    1146
    1147
    1148
    1149
    1150
    1151
    1152
    1153
    1154
    1155
    1156
    1157
    1158
    1159
    1160
    1161
    1162
    1163
    1164
    1165
    1166
    1167
    1168
    1169
    1170
    1171
    1172
    1173
    1174
    1175
    1176
    1177
    1178
    1179
    1180
    1181
    1182
    1183
    1184
    1185
    1186
    1187
    1188
    1189
    1190
    1191
    1192
    1193
    1194
    1195
    1196
    1197
    1198
    1199
    1200
    1201
    1202
    1203
    1204
    1205
    1206
    1207
    1208
    1209
    1210
    1211
    1212
    1213
    1214
    1215
    1216
    1217
    1218
    1219
    1220
    1221
    1222
    1223
    1224
    1225
    1226
    1227
    1228
    1229
    1230
    1231
    1232
    1233
    1234
    1235
    1236
    1237
    1238
    1239
    1240
    1241
    1242
    1243
    1244
    1245
    1246
    1247
    1248
    1249
    1250
    1251
    1252
    1253
    1254
    1255
    1256
    1257
    1258
    1259
    1260
    1261
    1262
    1263
    1264
    1265
    1266
    1267
    1268
    1269
    1270
    1271
    1272
    1273
    1274
    1275
    1276
    1277
    1278
    1279
    1280
    1281
    1282
    1283
    1284
    1285
    1286
    1287
    1288
    1289
    1290
    1291
    1292
    1293
    1294
    1295
    1296
    1297
    1298
    1299
    1300
    1301
    1302
    1303
    1304
    1305
    1306
    1307
    1308
    1309
    1310
    1311
    1312
    1313
    1314
    1315
    1316
    1317
    1318
    1319
    1320
    1321
    1322
    1323
    1324
    1325
    1326
    1327
    1328
    1329
    1330
    1331
    1332
    1333
    1334
    1335
    1336
    1337
    1338
    1339
    1340
    1341
    1342
    1343
    1344
    1345
    1346
    1347
    1348
    1349
    1350
    1351
    1352
    1353
    1354
    1355
    1356
    1357
    1358
    1359
    1360
    1361
    1362
    1363
    1364
    1365
    1366
    1367
    1368
    1369
    1370
    1371
    1372
    1373
    1374
    1375
    1376
    1377
    1378
    1379
    1380
    1381
    1382
    1383
    1384
    1385
    1386
    1387
    1388
    1389
    1390
    1391
    1392
    1393
    1394
    1395
    1396
    1397
    1398
    1399
    1400
    1401
    1402
    1403
    1404
    1405
    1406
    1407
    1408
    1409
    1410
    1411
    1412
    1413
    1414
    1415
    1416
    1417
    1418
    1419
    1420
    1421
    1422
    1423
    1424
    1425
    1426
    1427
    1428
    1429
    1430
    1431
    1432
    1433
    1434
    1435
    1436
    1437
    1438
    1439
    1440
    1441
    1442
    1443
    1444
    1445
    1446
    1447
    1448
    1449
    1450
    1451
    1452
    1453
    1454
    1455
    1456
    1457
    1458
    1459
    1460
    1461
    1462
    1463
    1464
    1465
    1466
    1467
    1468
    1469
    1470
    1471
    1472
    1473
    1474
    1475
    1476
    1477
    1478
    1479
    1480
    1481
    1482
    1483
    1484
    1485
    1486
    1487
    1488
    1489
    1490
    1491
    1492
    1493
    1494
    1495
    1496
    1497
    1498
    1499
    1500
    1501
    1502
    1503
    1504
    1505
    1506
    1507
    1508
    1509
    1510
    1511
    1512
    1513
    1514
    1515
    1516
    1517
    1518
    1519
    1520
    1521
    1522
    1523
    1524
    1525
    1526
    1527
    1528
    1529
    1530
    1531
    1532
    1533
    1534
    1535
    1536
    1537
    1538
    1539
    1540
    1541
    1542
    1543
    1544
    1545
    1546
    1547
    1548
    1549
    1550
    1551
    1552
    1553
    1554
    1555
    1556
    1557
    1558
    1559
    1560
    1561
    1562
    1563
    1564
    1565
    1566
    1567
    1568
    1569
    1570
    1571
    1572
    1573
    1574
    1575
    1576
    1577
    1578
    1579
    1580
    1581
    1582
    1583
    1584
    1585
    1586
    1587
    1588
    1589
    1590
    1591
    1592
    1593
    1594
    1595
    1596
    1597
    1598
    1599
    1600
    1601
    1602
    1603
    1604
    1605
    1606
    1607
    1608
    1609
    1610
    1611
    1612
    1613
    1614
    1615
    1616
    1617
    1618
    1619
    1620
    1621
    1622
    1623
    1624
    1625
    1626
    1627
    1628
    1629
    1630
    1631
    1632
    1633
    1634
    1635
    1636
    1637
    1638
    1639
    1640
    1641
    1642
    1643
    1644
    1645
    1646
    1647
    1648
    1649
    ;    --------------------------------------------------------------------------------------------------------------------------------- 
    ;    |            UTILISATION DES REGISTRES - BANQUE 0 (Attention la pile utilise la zone mémoire des banques 1, 2 et 3)             |
    ;    --------------------------------------------------------------------------------------------------------------------------------- 
    ;    |     USAGE     | 0 MINUTERIE   | 1 WATCH DOG   | 2 DOUBLE CPT  | 3 BP / INTER  | 4 PORTE LOG   | 5/6 COMPTEUR  | 7 MOTEURS     |
    ;    |    GENERAL    |               |               |   TEMPORISAT  |   ANTIREBOND  |   7 ENTREES   | ASCII GRAY/DE |   PAS A PAS   |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R0 | Pointeur aff. | Pointeur dans | Pointeur dans | Pointeur dans |               | Choix sous    | Vitesse       | Vitesse       | R0 |
    ;    | LCD hexadecim | interruption  | interruption  | interruption  |               | menu impair   |               |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R1 |               |               |               | Comptage 11e  |               |               | Choix durée   | Choix durée   | R1 |
    ;    |               |               |               | de secondes A |               |               | pause         | pause         |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----|
    ; R2 | Caractère à   |               |               |               |               |               |               |               | R2 |
    ;    | afficher LCD  |               |               |               |               |               |               |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R3 | Numéro touche |               |               |               |               |               |               |               | R3 |
    ;    | enfoncée      |               |               |               |               |               |               |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----|
    ; R4 |               | Comptage 11e  | Comptage 11e  | Comptage 11e  |               | Choix sous    | Temp. calcul  | Mode 1, 2 ou  | R4 |
    ;    |               | de secondes   | de secondes   | de secondes B |               | menu 7 5 3 1  | binaire gray  | demi pas      |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R5 | Index dans    |               |               |               |               |               |               |               | R5 |
    ;    | texte LCD     |               |               |               |               |               |               |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R6 | Temp. dans    | Temp ss-menu  | Temp ss-menu  |               |               | Index dans    | Temp. valeur  |               | R6 |
    ;    | contrôle P1   | et +/- TimeX  | et +/- TimeX  |               |               | boucle        | ASCII à conv  |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ; R7 | Temp. dans    | Temp. divers  | Temp. divers  | Temp. divers  |               |               | ASCII / GR/DE |               | R7 |
    ;    | contrôle P1   | interruption  | interruption  | interruption  |               |               |               |               |    |
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----|
    ;PSW1|               |               |               |               |               |               |               |               |PSW1|
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ;PSW5|               |               |               |               |               |               |               |               |PSW5|
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ;SM 0|               | Aff dans int  | Aff dans int  |               | Choix BP/I    |               | GRAY / DECIML |               |SM 0|
    ;----|---------------|---------------|---------------|---------------|---------------|---------------|---------------|---------------|----| 
    ;
    ; ----------------------------------------------------------------------------------------------------------------- 
    ; |                             UTILISATION DES BROCHES DU PORT P1 EN Entrées/SORTIES                             |
    ; ----------------------------------------------------------------------------------------------------------------- 
    ; | 0 MINUTERIE   | 1 WATCH DOG   | 2 DOUBLE CPT  | 3 BP / INTER  | 4 PORTE LOG   | 5 COMPTEUR    | 7 MOTEURS     |
    ; |               |               |   TEMPORISAT  |   ANTIREBOND  |   7 ENTREES   | 6 ASC GRA DEC |   PAS A PAS   |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;0|               | Entrée        | Entrée        | SORTIE        | Entrée        | SORTIE        | SORTIE        |0|
    ; |               | Reset W       | Compteur A    | BP 1          | 1             | 0             | M1 A-         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;1|               | Entrée        | Entrée        | SORTIE        | Entrée        | SORTIE        | SORTIE        |1|
    ; |               | Reset W       | Compteur B    | BP 2          | 2             | 1             | M1 A+         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-|
    ;2|               | Entrée        |               | SORTIE        | Entrée        | SORTIE        | SORTIE        |2|
    ; |               | Reset W       |               | BP 3          | 3             | 2             | M1 B-         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;3|               | Entrée        |               | SORTIE        | Entrée        | SORTIE        | SORTIE        |3|
    ; |               | Reset W       |               | BP 4          | 4             | 3             | M1 B+         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-|
    ;4|               | Entrée        |               | SORTIE        | Entrée        | SORTIE        | SORTIE        |4|
    ; |               | Reset W       |               | BP 5          | 5             | 4             | M2 A-         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;5| Entrée        | Entrée        |               | SORTIE        | Entrée        | SORTIE        | SORTIE        |5|
    ; | Buzzer OK     | Reset W       |               | BP 6          | 6             | 5             | M2 A+         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;6| SORTIE        | SORTIE        |               |               | Entrée        | SORTIE        | SORTIE        |6|
    ; | Buzzer /enabl | Buzzer /enabl |               |               | 7             | 6             | M2 B-         | |
    ;-|---------------|---------------|---------------|---------------|---------------|---------------|---------------|-| 
    ;7| SORTIE RAZ WD | SORTIE RAZ WD |               |               | SORTIE        | SORTIE        | SORTIE        |7|
    ; | Sonnerie      | Sonnerie      |               |               |               | 7             | M2 B+         | |
    ;-------------------------------------------------------------------------------------------------------------------- 
    ;
    ; ------------------------------------------------------------------------------------------------------------------- 
    ; |  LE PORT P3 EST UTILISE DE FACON NON MODIFIABLE PAR LE CLAVIER ET L'AFFICHEUR LCD                               |
    ; ------------------------------------------------------------------------------------------------------------------- 
     
    ;Variables :
    TEMPR0	EQU 3Ah
    TEMPA	EQU 39h
    TEMPHEX	EQU 38h
    CPT_B3	EQU 37h
    CPT_B2	EQU 36h
    CPT_B1	EQU 35h
    TimeH	EQU	34h 
    TimeM	EQU	33h 
    TimeS	EQU	32h 
    CPT_A3	EQU 31h
    CPT_A2	EQU 30h
    ;Variables dans la zone adressable par bit :
    CPT_A1	EQU 2Fh
    TempoH	EQU	2Eh 
    TempoM	EQU	2Dh 
    TempoS	EQU	2Ch 
    RSTWDOG EQU	2Bh
    PAUSE2	EQU	2Ah
    PAUSE1	EQU	29h
    TEMP_B2	EQU	28h
    TEMP_B  EQU	27h
    SMENU	EQU	26h 
    POS1	EQU	25h 
    POS2	EQU	24h 
    SEMAPHO	EQU	23h 
    MENU	EQU	22h
    NEW_P1	EQU 21h
    OLD_P1	EQU 20h
     
    ;Config :
    ORG     0000h
    	;CLR	A; Optimisation : mettre à 0 A et faire plusieurs MOV xxx,A économise de la ROM par rapport à MOV xxx,#0
    	MOV	IE,#10000010b	;Interruptions Timer 0 activées  : EA  --  --  ES  T1  I1  T0  I0
    	MOV	IP,#00000010b	;Priorités                       : --  --  --  --  T1  I1  T0  I0
    	;MOV	TCON,A ;A=0     ;Interruptions Timer désactivées : TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
        AJMP    Start	        ;Saut vers programme principal
     
    ORG	000Bh
    	AJMP	InterCpt0	;Routine d'interruption timer 0 
     
    ;ORG     30h	Si des interruptions ne sont pas utilisées, alors on peut commencer avant 30h
     
    ; Constantes :   
    ;----------------1234567890123456-----
    TexteM_AProposDe: 
    	DB	'Carte 8051 v61.6';,00H
    TexteM_AProposDe2: 
    	DB	' (C) Remy LUCAS ';,00H
    TexteM_Principal: 
    	DB	' /8        OK <>';,00H
    TexteM_0: 
    	DB	'Minuterie       ';,00H ;OK
    TexteM_1: 
    	DB	'Chien de garde  ';,00H ;OK	
    TexteM_2: 
    	DB	'Double compteur ';,00H ;OK	
    TexteM_3: 
    	DB	'Antirebonds [BP]';,00H ;OK	
    TexteM_4: 
    	DB	'Porte logique 7E';,00H ;OK	
    TexteM_5: 
    	DB	'Generateur ASCII';,00H ;OK	
    TexteM_6: 
    	DB	'Gen. GRAY/DEC: G';,00H ;OK	
    TexteM_7: 
    	DB	'Moteur pas a pas';,00H ;OK	
    TexteM_ControlePort: 
    	DB	'Liberez sorties ';,00H ;OK	
    TexteM0_ErreurBuzzer:
    	DB	'Allumez buzzer !';,00H 	
     
    TexteM0_BACK: 
    TexteMi_BACK: 
    	DB	' BACK';,00H ;	
    TexteM0_RUN: 
    	DB	'  RUN';,00H ;	
    TexteM0_CONT: 
    	DB	'CONT.';,00H ;	
    TexteM0_PAUSE: 
    	DB	'PAUSE';,00H ;	
    TexteM0_STOP: 
    	DB	' STOP';,00H ;	
    TexteM1: 
    	DB	'A=0 B=0 RUN';,00H ;Compteur impulsions	
    TexteM2: 
    	DB	'0/1 0/1 0/1';,00H ;Inter et BP antirebond	
    TexteM4_2:    
    	DB	' OR  XOR  AND  1';,00H ;Porte logique
    TexteM5: 
    	DB	'000 00 <V0>';,00H ;Compteur ASCII et GRAY
    TexteM7: 
    	DB	'M1 M2 <V0>1';,00H ;Moteurs pas à pas	
    TableauPasAPas: ;On pourrait stocker sur 4 octets au lieu de 8 mais les calculs supplémentaires occuperaient bien plus que les 4 octets gagnés 
    	DB	00000001b	
    	DB	00000101b	
    	DB	00000100b	
    	DB	00000110b	
    	DB	00000010b	
    	DB	00001010b	
    	DB	00001000b	
    	DB	00001001b	
    TableauControleP1: ;Contrôle de l'état du port P1 avant d'entrer dans un menu :
    	;Chaque broche utilisée en entrée correspond à un 0 :
    	;   76543210
    	DB	11011111b ;0 Minuterie
    	DB	11000000b ;1 Watch Dog
    	DB	11111100b ;2 Double cpt temp
    	DB	11111111b ;3 BP/I antirebond
    	DB	10000000b ;4 Porte 7 entrees 
    	DB	11111111b ;5 Compteur ASCII 
    	DB	11111111b ;6 Compteur GRAY 
    	DB	11111111b ;7 Moteurs pas à pas 
     
    ;== INITIALISATION ========================================================================================================================
    Start:
    ;	MOV	IE,#10000010b	;Interruptions Timer 0 activées  : EA  --  --  ES  T1  I1  T0  I0
    ;	MOV	IP,#00000010b	;Priorités                       : --  --  --  --  T1  I1  T0  I0
    ;	MOV	TCON,A ;A=0     ;Interruptions Timer désactivées : TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
    	MOV	TMOD,#00000001b	;Temporisateur 16 bits           : Gate C/T M1 M0 Gate C/T M1 M0     (T1 / T0)
     
    	MOV 	P3,#01000100b   ; D7 (1) D6 D5 D4 (in) EN RS		
     
    	;Initialisation - LCD 
    	ACALL BigPause
     
    	;CLR	P3.0 ;RS=0 RS est déjà à 0 grâce à MOV 	P3,#01000100b   ; D7 (1) D6 D5 D4 (in) EN RS
    	MOV TEMP_B,#00000010b ; Mode 4 bits
    	ACALL	EcrireL
     
    	; On / off
    	MOV	R2,#00000100b
    	ACALL	LcdCommande
    	; Entry mode set
    	MOV	R2,#00000110b
    	ACALL	LcdCommande
    	; Display control
    	MOV	R2,#00001100b
    	ACALL	LcdCommande
     
    	MOV	MENU,#0
     
    	;Ecriture de texte dans le LCD :
    	ACALL	LcdCommande_Ligne1_Colonne0
    	MOV	DPTR,#TexteM_AProposDe
    	ACALL	LcdTexte
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM_AProposDe2
    	ACALL	LcdTexte
    	ACALL	ClavierAttendreTouche
     
    RetourProgrammePrincipal:
    	MOV	P1,#11111111b
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM_Principal
    	ACALL	LcdTexte
    	AJMP	ToucheEnfoncee_Fin ;pour forcer l'affichage
     
    ;== PROGRAMME PRINCIPAL ===================================================================================================================
    Boucle:
    ;	ACALL	ClavierAttendreTouche
    	ACALL	Incrementer_LS138
    	JNB	P3.2,ToucheEnfoncee
     
    	MOV	R2,#11000100b ; Ligne 2 Colonne 4
    	ACALL	LcdCommande
     
    	MOV	A,P1
    	ACALL LcdOctetHexaEtDecimal
     
    	AJMP	Boucle
    ToucheEnfoncee:
     
    ; TOUCHE 6 > ============================
    	CJNE	R3,#0,ToucheEnfoncee_Pas6
    	INC 	MENU
    	AJMP	ToucheEnfoncee_Fin
    ToucheEnfoncee_Pas6:
     
    ; TOUCHE 4 < ============================
    	CJNE	R3,#2,ToucheEnfoncee_Pas4
    	DEC 	MENU
    	AJMP	ToucheEnfoncee_Fin
    ToucheEnfoncee_Pas4:
     
    ; TOUCHE E ==============================
    	CJNE	R3,#3,ToucheEnfoncee_Fin ;ToucheEnfoncee_Autre
     
    ;Contrôle du port P1 - il faut trouver si une des broches qui sera utilisée en sortie est forcée à la masse
    ;Lecture de la configuration du port à vérifier :
    	MOV	DPTR,#TableauControleP1 	;Adresse du tableau de données
    	MOV	A,MENU			;Index
    	MOVC	A,@A+DPTR		;Lecture
    	MOV	R6,A
     
    ;Contrôle du port :
    	MOV	A,P1
    	CPL	A
    	ANL	A,R6 ;Masque - Chaque '1' correspond à un bit utilisé en sortie
    	JZ	Controle_Port_P1_OK
     
    	;L'etat du port P1 n'est pas bon :
    	;Sauvegarde du résultat du contrôle dans R6 :
    	MOV	R6,A
     
    	;Affichage message d'erreur :
    	ACALL	LcdCommande_Ligne1_Colonne0
    	MOV	DPTR,#TexteM_ControlePort
    	ACALL	LcdTexte
     
    	;On affiche l'état du port de façon ergnonomique :
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	A,R6
    	MOV	R6,#8
    	MOV	R7,#0
    Controle_Port_P1_AffichageBit:
    	RRC	A
    	JC	Controle_Port_P1_Affichage1
    	MOV	R2,#00101110b; "."
    	ACALL	LcdChar
    	AJMP	Controle_Port_P1_AffichageFin
    Controle_Port_P1_Affichage1:
    	MOV	TEMP_B,R7
    	ACALL	LcdChiffre_TEMP_B
    Controle_Port_P1_AffichageFin:
    	INC	R7
    	DJNZ	R6,Controle_Port_P1_AffichageBit
    	ACALL	M4_LcdChar_ESPACE
    	ACALL	M4_LcdChar_ESPACE
     
    ;FinEtRetour:
    	ACALL	MegaPause
    	ACALL	ClavierAttendreTouche
    	AJMP	RetourProgrammePrincipal
    Controle_Port_P1_OK:
     
    	MOV	A,MENU
    	RL	A
    	MOV	DPTR,#MenuChoix
    	JMP	@A+DPTR
    MenuChoix:
    	AJMP	M0
    	AJMP	M1
    	AJMP	M2
    	AJMP	M3 
    	AJMP	M4
    	AJMP	M5
    	AJMP	M6
    	AJMP	M7
     
    ToucheEnfoncee_Fin:
    	ANL	MENU,#00000111b ;Astuce comme il y a 8 entrées de menu (0 à 7) il suffit de garder les 3 premiers bits de MENU
     
    	;ACALL	Pause
     
    ;Mise à jour de l'affichage LCD en fonction des sorties calculées :
     
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
     
    	MOV	R2,MENU
    	INC	R2
    	ACALL	LcdChiffre
     
    	;MOV	R2,#10000000b ; Ligne 1 Colonne 0
    	ACALL	LcdCommande_Ligne1_Colonne0
     
    	;Comme les 8 textes possibles sont de même longeurs et stockés à la suite :
    	MOV	A,MENU			
    	;MOV	B,#16  ;longueur d'un texte (attention suite à une autre modif il n'y a plus d'octet null)
    	;MUL	AB     ;A = Menu * 16
    	SWAP	A ;equivaut à une multiplication par 16 pour un nombre inférieur à 16
    	ADD	A,#TexteM_0
    	MOV	DPH,#0 ;Octet supérieur de DPTR
    	MOV	DPL,A  ;Octet inférieur de DPTR
     
    	ACALL	LcdTexte
     
    	ACALL 	MegaPause
    	AJMP Boucle
     
    AJMP	$                       ;Fin
     
    ;== 0 - MINUTERIE / CHIEN DE GARDE ========================================================================================================
    ; Particularité : certaines fonctions sont réalisées avec des entrées et des sorties de P1 voir tableau ci-dessus
    M1:
    ;WDOG
    	MOV 	P1,#00111111b ; broches P1.0 à P1.5 en entrées
    	AJMP	M0_WDOG
    M0:
    ;MINUTERIE
    	MOV 	P1,#00100000b ; broche P1.5 en entrée
    	;MOV 	P1,#00111111b ; broches P1.0 à P1.5 en entrées
    M0_WDOG:
     
    	CLR A
    	MOV	SMENU,A ;A=0
     
    	MOV	TempoH,A ;A=0
    	MOV	TempoM,#10
    	MOV	TempoS,A ;A=0
     
    	ACALL	M0_Raz_Decompte
     
    	MOV	R2,#10001000b ; Ligne 1 Colonne 8
    	ACALL	LcdCommande
    	ACALL	LcdTexteVide5
     
    	MOV	R2,#11001000b ; Ligne 2 Colonne 8
    	ACALL	LcdCommande
    	ACALL	LcdTexteVide5
     
    	ACALL	M0_Afficher_DECOMPTE
     
    	ACALL	M0_Afficher_TEMPO
    	ACALL	M0_Affichage_SMENU
    	;ACALL	M0_Actualiser_MODE
     
    	ACALL	MegaPause ; Evite appui sur 'E' détecté
     
    M0_Boucle:
    	ACALL	ClavierAttendreTouche
     
    	CLR SEMAPHO.0 ;MOV	AFF,#0
    	MOV	R6,SMENU
    	MOV	A,R3
    	RL	A ;Multiplication par deux ; une instruction "AJMP xxxx" fait deux octets
    	MOV	DPTR,#M0_MenuChoix
    	JMP	@A+DPTR
    M0_MenuChoix:  ;L'ordre des AJMP ci-dessous correspond aux valeurs de R3
    	AJMP	M0_Menu0_Touche6_R
    	AJMP	M0_Menu1_ToucheA_A
    	AJMP	M0_Menu2_Touche4_L
    	AJMP	M0_Menu3_ToucheE_E
    	AJMP	M0_Menu4_Touche2_DN
    	AJMP	M0_Menu5_Touche8_UP
    	AJMP	M0_Menu6_Touche3_PDN
    	AJMP	M0_Menu7_Touche9_PUP
    M0_Menu1_ToucheA_A:   ;=============================================
    	CJNE	R6,#0,M0_Menu1_ToucheA_A_Pas0 ;0-Stop/Reglage : touche "BACK"
    	CLR	TCON.4 ;Timer 0 arrêt
    	AJMP	RetourProgrammePrincipal; 
    M0_Menu1_ToucheA_A_Pas0:
    	CJNE	R6,#1,M0_Menu1_ToucheA_A_Pas1 ;1-Run : touche "BACK"
    	CLR	TCON.4 ;Timer 0 arrêt
    	MOV	SMENU,#0
    	ACALL	M0_Raz_Decompte 
    	ACALL 	M0_Afficher_DECOMPTE
    	ACALL	M0_Affichage_SMENU
    	AJMP	M0_ToucheEnfoncee_Fin
    M0_Menu1_ToucheA_A_Pas1:
    	CJNE	R6,#3,M0_ToucheEnfoncee_Fin_Bis   ;3-Alarme : touche "STOP"
    	CLR	TCON.4 ;Timer 0 arrêt
    	CLR	P1.7 ;Sonnerie
    	CLR	P1.6
    	;MOV 	P1,#00100000b ; Revient au même que les deux CLR et occupe moins de code
    	MOV	SMENU,#0
    	ACALL	M0_Raz_Decompte 
    	ACALL   M0_Afficher_DECOMPTE
    	ACALL	M0_Affichage_SMENU
    M0_ToucheEnfoncee_Fin_Bis:
    	AJMP	M0_ToucheEnfoncee_Fin
    M0_Menu0_Touche6_R:   ;=============================================
    	CJNE	R6,#0,M0_Menu1_ToucheA_R_Pas0 ;0-Stop/Reglage : touche "RUN"
     
    	;On veut que la minuterie démarre si:
    	; - Si MENU = 0 (watchdog)
    	; - Si MENU = 1 (minuterie) ET si P1.5 = 0 (retour inter buzzer "on" par forçage à la masse de P1.5)
    	JB	MENU.0,M0_Test_Buzzer_Fin
    	JNB	P1.5,M0_Test_Buzzer_Fin
    	;Affichage Message d'erreur
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM0_ErreurBuzzer
    	ACALL	LcdTexte
    	ACALL	MegaPause
    	;Attente validation utilisateur
    	ACALL	ClavierAttendreTouche
    	;Restauration affichage
    	ACALL	M0_Afficher_DECOMPTE
    	ACALL	LcdTexteVide5
    	ACALL	M0_Affichage_SMENU
    	;Retour au début
    	AJMP	M0_ToucheEnfoncee_Fin 
    	M0_Test_Buzzer_Fin:
     
    	MOV	SMENU,#1
    	ACALL	M0_Affichage_SMENU
    	ACALL	Pause
    	ACALL	M0_TimerMarche_InitWDOG
    	AJMP	M0_ToucheEnfoncee_Fin
    M0_Menu1_ToucheA_R_Pas0:
    	CJNE	R6,#1,M0_Menu1_ToucheA_R_Pas1 ;1-Run : touche "PAUSE"
    	CLR	TCON.4 ;Timer 0 arrêt
    	MOV	SMENU,#2
    	ACALL	M0_Affichage_SMENU
    	AJMP	M0_ToucheEnfoncee_Fin
    M0_Menu1_ToucheA_R_Pas1:
    	CJNE	R6,#2,M0_ToucheEnfoncee_Fin   ;2-Paused : touche "CONT"
    	MOV	SMENU,#1
    	ACALL	M0_Affichage_SMENU
    	ACALL	Pause
    	ACALL	M0_TimerMarche_InitWDOG
    	AJMP	M0_ToucheEnfoncee_Fin
    M0_Menu2_Touche4_L:   ;=============================================
    	MOV	R6,TempoS
    	ACALL	M0_R6_DEC59
    	MOV	TempoS,R6
    	AJMP	M0_ToucheEnfoncee_FinAff
    M0_Menu3_ToucheE_E:   ;=============================================
    	MOV	R6,TempoS
    	ACALL	M0_R6_INC59
    	MOV	TempoS,R6
    	AJMP	M0_ToucheEnfoncee_FinAff
    M0_Menu4_Touche2_DN:  ;=============================================
    	MOV	R6,TempoM
    	ACALL	M0_R6_DEC59
    	MOV	TempoM,R6
    	AJMP	M0_ToucheEnfoncee_FinAff
    M0_Menu5_Touche8_UP:  ;=============================================
    	MOV	R6,TempoM
    	ACALL	M0_R6_INC59
    	MOV	TempoM,R6
    	AJMP	M0_ToucheEnfoncee_FinAff
    M0_Menu6_Touche3_PDN: ;=============================================
    	;On laisse les heures aller jusque 255
    	DEC	TempoH
    	;MOV	R6,TempoH
    	;ACALL	M0_R6_DEC99
    	;MOV	TempoH,R6
    	AJMP	M0_ToucheEnfoncee_FinAff
    M0_Menu7_Touche9_PUP: ;=============================================
    	;On laisse les heures aller jusque 255
    	INC	TempoH
    	;MOV	R6,TempoH
    	;ACALL	M0_R6_INC99
    	;MOV	TempoH,R6
    ;	AJMP	M0_ToucheEnfoncee_FinAff
    M0_ToucheEnfoncee_FinAff:
    	SETB SEMAPHO.0 ;MOV	AFF,#1
    	JNB	TCON.4,M0_Aff
    	AJMP	M0_Pas_Aff
    M0_Aff:
    	;Le timer 0 ne marche pas, on peut afficher (sinon l'affichage est géré par l'interruption T0)
    	ACALL M0_Afficher_TEMPO
    	CLR SEMAPHO.0 ;MOV	AFF,#0
    M0_Pas_Aff:	
    M0_ToucheEnfoncee_Fin:
     
    	ACALL	MegaPause
    	AJMP M0_Boucle
     
    M0_R6_INC59:
    	INC	R6
    	CJNE	R6,#60,M0_R6_INC59_OK
    	MOV	R6,#0
    M0_R6_INC59_OK:
    RET
     
    M0_R6_DEC59:
    	DEC	R6
    	CJNE	R6,#255,M0_R6_DEC59_OK
    	MOV	R6,#59
    M0_R6_DEC59_OK:
    RET
     
    ;On laisse les heures aller jusque 255
    ;M0_R6_INC99:
    ;	INC	R6
    ;	CJNE	R6,#100,M0_R6_INC99_OK
    ;	MOV	R6,#0
    ;M0_R6_INC99_OK:
    ;RET
    ;M0_R6_DEC99:
    ;	DEC	R6
    ;	CJNE	R6,#255,M0_R6_DEC99_OK
    ;	MOV	R6,#99
    ;M0_R6_DEC99_OK:
    ;RET
     
    M0_TimerMarche_InitWDOG:
    	;MOV	R7,MENU
    	JNB	MENU.0,M0_TimerMarche_InitWDOG_Fin ;CJNE	R7,#1,M0_TimerMarche_InitWDOG_Fin
    	MOV	A,P1
    	ANL	A,#00111111b ; seulement les bits 0 à 5
    	MOV	RSTWDOG,A
    M0_TimerMarche_InitWDOG_Fin:
    	SETB	TCON.4 ;Timer 0 MARCHE
    RET
     
    InterCpt0: ;INTERRUPTION COMPTEUR ****************
    	;IMPORTANT - Il faut sauvegarder et restaurer A et PSW pour que l'interruption ne créée pas de dégâts ailleurs dans le code :
    	PUSH	ACC 
    	PUSH	PSW
    	;ATTENTION Ne pas utiliser ailleurs dans les portions de code pouvant être interrompues par cette interruption :
    	; - des registres utilisés par l'interruption
    	; - des variables utilisés par l'interruption
    	; - l'afficheur LCD qui est utilisé par l'interruption
    	;aussi les portions de codes pouvant êtres interrompues par l'interruption sont très limitées (gestion clavier Minuterie / Wdog et Compteur temporisateur)
     
    	MOV	A,MENU
    	CJNE	A,#2,M0_InterCpt0
    	ACALL	M2_InterCpt0 ;Code d'interruption pour le Compteur temporisateur
    	AJMP	InterCpt0_Exit
    M0_InterCpt0:
     
    	;Code d'interruption pour la minuterie / watch dog :
     
    	;CLR A ;A=0 - Utilisé pour économiser du code car MOV Ri,A est plus court que MOV Ri,#0
     
    	;Affichage tempo (cas de figure où l'utilisateur la modifie en mode RUN) :
    	JNB	SEMAPHO.0,InterCpt0_Pas_Aff
    	ACALL 	M0_Afficher_TEMPO
    	CLR	SEMAPHO.0 ;MOV	AFF,A ;A=0
    InterCpt0_Pas_Aff:	
     
    	;Il faut scruter les entrées du WDOG lorsqu'on est en mode WDOG :
    	JNB	MENU.0,InterCpt0_Minuterie 
     
    	MOV	A,P1
    	ANL	A,#00111111b ; seulement les bits 0 à 5
    	CJNE	A,RSTWDOG,InterCpt0_ResetWDOG
    	AJMP	InterCpt0_FinWDOG
    InterCpt0_ResetWDOG:
    	MOV	RSTWDOG,A
    	ACALL 	M0_Raz_Decompte
    	AJMP	InterCpt0_Fin
    InterCpt0_FinWDOG:
     
    InterCpt0_Minuterie:
    	;Sous-comptage :
    	DJNZ	R4,InterCpt0_Exit
    	MOV	R4,#11; ;11 impulsions pour une seconde #############
     
    	;Le code qui suit s'éxecute très précisément une fois par seconde :
     
    	;Clignotement de la sonnerie :
    	MOV	A,SMENU
    	CJNE	A,#3,InterCpt0_PasSonnerie
    	CPL	P1.6 ;P1.7 reste allumé fixe, P1.6 clignote ; on a ainsi une sortie de sonnerie fixe et une clignotante
    	;Modif : on veut continuer à compter lorsque la sonnerie sonne !
    	;AJMP	InterCpt0_Exit ;IMPORTANT car en mode sonnerie on ne compte plus on ne fait que clignoter
    InterCpt0_PasSonnerie:
     
    	;Comptage du temps :
    	MOV	R0,#TimeS
    	ACALL	M0_INC_Time
     
    	;Il faut comparer Time et Tempo !
    	MOV	A,TimeS
    	CJNE	A,TempoS,InterCpt0_Fin
    	MOV	A,TimeM
    	CJNE	A,TempoM,InterCpt0_Fin
    	MOV	A,TimeH
    	CJNE	A,TempoH,InterCpt0_Fin
    	;*** Time = Tempo
    	CLR	TCON.4 ;Timer 0 arrêt
    	JB	MENU.0,InterCpt0_WDOG 
    	;*** => Minuterie déclenchée : on allume la sonnerie
    	MOV	SMENU,#3
    	ACALL	M0_Affichage_SMENU
    	SETB	P1.7 ;Sonnerie
    	SETB	TCON.4 ;Timer 0 MARCHE ;On veut faire clignoter ! On va tester SMENU==3 pour le clignotement
    	AJMP	InterCpt0_Fin
    InterCpt0_WDOG:	
    	;*** => WDOG déclenché : on fait une petite impulsion de RESET et on redémarre
    	SETB	P1.7 ;Reset WDOG
    	ACALL	MegaPause
    	CLR	P1.7 ;Reset WDOG
    	ACALL 	M0_Raz_Decompte
    	SETB	TCON.4 ;Timer 0 MARCHE
     
    InterCpt0_Fin:
    	;Affichage du temps :
    	ACALL 	M0_Afficher_DECOMPTE
     
    InterCpt0_Exit:
    	;Important il faut recharger le compteur à chaque fois pour avoir la bonne durée :
    	ACALL	M0_Precharge_Timer
     
    	;IMPORTANT - Il faut restaurer A et PSW pour que l'interruption ne créée pas de dégâts ailleurs dans le code :
    	POP	PSW
    	POP	ACC
    RETI ;********************************************
     
    M0_Raz_Decompte:
    	;CLR	A
    	;MOV	TimeH,A
    	;MOV	TimeM,A
    	;MOV	TimeS,A
    	;MOV	R4,#11 ;11 impulsions pour une seconde #############
    	ACALL	M2_RESET_B ;Optimisation pour économiser du code, même si M2_RESET_B fait plus de choses
    M0_Precharge_Timer:
    	;On précharge le registre 16 bits du timer pour ajuster finement la valeur d'une seconde :
    	MOV	TH0,#14h
    	MOV	TL0,#84h
    RET
     
    ;Utilisation du registre R0 en pointeur
    M0_Afficher_TEMPO:
    	;MOV	R2,#10000000b ; Ligne 1 Colonne 0
    	ACALL	LcdCommande_Ligne1_Colonne0
    	MOV	R0,#TempoH
    	AJMP M0_Afficher_HHMMSS
    M0_Afficher_DECOMPTE:
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	R0,#TimeH
    M0_Afficher_HHMMSS:
    	MOV	A,@R0;H 
    	;On laisse les heures aller jusque 255
    	ACALL	LcdOctet3Digits
    	;ACALL	LcdOctet2Digits
    	MOV	R2,#01101000b ;Caractère 'h'
    	ACALL	LcdChar
    	DEC	R0
    	MOV	A,@R0;M 
    	ACALL	LcdOctet2Digits
    	MOV	R2,#00111010b ;Caractère ':'
    	ACALL	LcdChar
    	DEC	R0
    	MOV	A,@R0;S 
    	ACALL	LcdOctet2Digits
    RET
     
    M0_Affichage_SMENU:
    	MOV	R2,#10001011b ; Ligne 1 Colonne 11
    	ACALL	LcdCommande
    	;
    	MOV	R6,SMENU
    	;
    	CJNE	R6,#0,M0_Affichage_SMENU_Pas0 ; SOUS MENU "STOP / REGLAGE" ===================
    	MOV	DPTR,#TexteM0_BACK ; RETOUR MENU PRINCIPAL
    	ACALL	LcdTexte5
    	MOV	DPTR,#TexteM0_RUN ; ALLER VERS MENU "RUN"
    	AJMP	M0_Affichage_SMENU_Fin
    M0_Affichage_SMENU_Pas0:
    	CJNE	R6,#1,M0_Affichage_SMENU_Pas1 ; SOUS MENU "RUN" ==============================
    	MOV	DPTR,#TexteM0_BACK ; RETOUR MENU "STOP / REGLAGE"
    	ACALL	LcdTexte5
    	MOV	DPTR,#TexteM0_PAUSE ; ALLER VERS MENU "PAUSED"
    	AJMP	M0_Affichage_SMENU_Fin
    M0_Affichage_SMENU_Pas1:
    	CJNE	R6,#2,M0_Affichage_SMENU_Pas2 ; SOUS MENU "PAUSED" ===========================
    	ACALL	LcdTexteVide5
     
    	MOV	DPTR,#TexteM0_CONT ; REPRENDRE et ALLER VERS MENU "RUN"
    	AJMP	M0_Affichage_SMENU_Fin
    M0_Affichage_SMENU_Pas2:
    	;CJNE	R6,#3,M0_Affichage_SMENU_Pas3 ; SOUS MENU "ALARME" ===========================
    	MOV	DPTR,#TexteM0_STOP ; ARRETER et ALLER VERS MENU "STOP / REGLAGE"
    	ACALL	LcdTexte5
    	ACALL	LcdCommande_Ligne2_Colonne11
    	ACALL	LcdTexteVide5
    	RET
    	;
    M0_Affichage_SMENU_Fin:
    	;MOV	R2,#11001011b ; Ligne 2 Colonne 11
    	ACALL	LcdCommande_Ligne2_Colonne11
    	ACALL	LcdTexte5
    RET
     
    ;== 1 - COMPTEUR IMPULSIONS ===============================================================================================================
    M2:
    	MOV 	P1,#00000011b ; Les deux entrées P1.0 et P1.1 utilisées pour les compteurs A et B
    	ACALL	M2_RESET_A
    	ACALL	M2_RESET_B
    M2_RetourMenuPrincipal:
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM1
    	ACALL	LcdTextePlusBACK
    	ACALL	MegaPause
    M2_Boucle:
    	ACALL	ClavierAttendreTouche
     
    	CJNE	R3,#1,M2_ToucheEnfoncee_Pas1 ;Touche A
    	AJMP	RetourProgrammePrincipal
    M2_ToucheEnfoncee_Pas1:
    	CJNE	R3,#7,M2_ToucheEnfoncee_Pas7 ;Touche 9 PUP
    	ACALL	M2_RESET_A
    	AJMP	M2_ToucheEnfoncee_Fin
    M2_ToucheEnfoncee_Pas7:
    	CJNE	R3,#5,M2_ToucheEnfoncee_Pas5 ;Touche 8 UP
    	ACALL	M2_RESET_B
    	AJMP	M2_ToucheEnfoncee_Fin
    M2_ToucheEnfoncee_Pas5:
    	CJNE	R3,#3,M2_ToucheEnfoncee_Fin ;M2_ToucheEnfoncee_Pas3 ;Touche E
    	AJMP	M2_RUN
     
    M2_ToucheEnfoncee_Fin:
    	ACALL	BigPause
    	AJMP M2_Boucle
     
    M2_InterCpt0: ;++ INTERRUPTION COMPTEUR TEMPORISATEUR ++++++
    	;On arrive ici exactement 11 fois par seconde 
    	;IMPORTANT : Une partie du travail de gestion de l'interruption est déjà fait par InterCpt0 qui appelle cette procédure
     
    	;Comptage sur front montant (entrée à 0 auparavent qui vient de passer à 1) :
    	;L'état précédent est dans OLD_P1
     
    	;Lecture des entrées de façon synchrone :
    	MOV	NEW_P1,P1
     
    	JB	OLD_P1.0,M2_InterCpt0_Suite_Scrutation_A
    	;L'entrée A était à 0 avant
    	JNB	NEW_P1.0,M2_InterCpt0_Fin_Scrutation_A
    	;L'entrée A est à 1 maintenant
    	MOV	R0,#CPT_A1
    	ACALL	M2_Comptage
    	ACALL	M2_Afficher_CPT_A
    M2_InterCpt0_Suite_Scrutation_A:
    	;L'entrée A était à 1 avant
    M2_InterCpt0_Fin_Scrutation_A:
     
    	JB	OLD_P1.1,M2_InterCpt0_Suite_Scrutation_B
    	;L'entrée B était à 0 avant
    	JNB	NEW_P1.1,M2_InterCpt0_Fin_Scrutation_B
    	;L'entrée B est à 1 maintenant
    	MOV	R0,#CPT_B1
    	ACALL	M2_Comptage
    	ACALL	M2_Afficher_CPT_B
    M2_InterCpt0_Suite_Scrutation_B:
    	;L'entrée B était à 1 avant
    M2_InterCpt0_Fin_Scrutation_B:
     
    	;Mesure du temps - Sous-comptage avec R1 pour A et R4 pour B:
    	JNB	NEW_P1.0,M2_InterCpt0_Mesure_Duree_A ;Entrée A
    	DJNZ	R1,M2_InterCpt0_Mesure_Duree_A
    	MOV	R1,#11; ;11 impulsions pour une seconde
    	MOV	R0,#TempoS
    	ACALL	M0_INC_Time
    	ACALL 	M0_Afficher_TEMPO ;A
    M2_InterCpt0_Mesure_Duree_A:
     
    	JNB	NEW_P1.1,M2_InterCpt0_Mesure_Duree_B ;Entrée B
    	DJNZ	R4,M2_InterCpt0_Mesure_Duree_B
    	MOV	R4,#11; ;11 impulsions pour une seconde
    	MOV	R0,#TimeS
    	ACALL	M0_INC_Time
    	ACALL 	M0_Afficher_DECOMPTE ;B
    M2_InterCpt0_Mesure_Duree_B:
     
    	;Sauvegarde du nouvel état précédent :
    	MOV	OLD_P1,NEW_P1
     
    RET ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++
     
     
    M2_Comptage:
    	MOV	R7,#2
    M2_Comptage_Suite:
    	INC	@R0
    	MOV	A,@R0
    	CJNE	A,#100,M2_Comptage_Fin
    	;On est arrivé à 100 :
    	MOV	@R0,#0
    	INC	R0
    	DJNZ	R7,M2_Comptage_Suite
    M2_Comptage_Fin:
    RET
     
    M0_INC_Time:
    	INC	@R0
    	MOV	A,@R0
    	CJNE	A,#60,M0_INC_Time_OK
    	MOV	@R0,#0
     
    	INC	R0
     
    	INC 	@R0
    	MOV	A,@R0
    	CJNE	A,#60,M0_INC_Time_OK
    	MOV	@R0,#0
     
    	INC	R0
     
    	INC 	@R0
    	MOV	A,@R0
    ;On laisse les heures aller jusque 255:
    ;	CJNE	A,#100,M0_INC_Time_OK
    ;	MOV	@R0,#0
    M0_INC_Time_OK:
    RET
     
    M2_RUN:
    	ACALL 	M0_Afficher_TEMPO ;A
    	ACALL	M2_Afficher_CPT_A
    	ACALL 	M0_Afficher_DECOMPTE ;B
    	ACALL	M2_Afficher_CPT_B
     
    	;Il faut lancer le comptage :
    	;MOV	OLD_P1,P1 - Il ne faut pas initialiser OLD_P1 sinon on oublie de compter la première fois si on démarre avec des entrées à 1
    	SETB	TCON.4 ;Timer 0 MARCHE
     
    	ACALL	MegaPause
    	ACALL	ClavierAttendreTouche
     
    M2_RUN_ToucheEnfoncee:
    	;Il faut arrêter le comptage :
    	CLR	TCON.4 ;Timer 0 arrêt
     
    	;On remet l'affichage :
    	ACALL	Pause
    	;MOV	R2,#10000000b ; Ligne 1 Colonne 0
    	ACALL	LcdCommande_Ligne1_Colonne0
    	MOV	DPTR,#TexteM_2 
    	ACALL	LcdTexte
    	AJMP M2_RetourMenuPrincipal	
     
    M2_RESET_A:
    	MOV	R1,#11 ;Init compteur A
    	CLR	OLD_P1.0
    	MOV	R0,#TempoS
    	AJMP	M2_RESET
    M2_RESET_B:
    	MOV	R4,#11 ;Init compteur B
    	CLR	OLD_P1.1
    	MOV	R0,#TimeS
    M2_RESET:
    	MOV	R7,#6 ;6 octets de xxxxS à CPT_x3
    	CLR	A
    M2_RESET_Suite:
    	MOV	@R0,A
    	INC	R0
    	DJNZ	R7,M2_RESET_Suite
    RET
     
    M2_Afficher_CPT_A:
    	;On laisse les heures aller jusque 255
    	MOV	R2,#10001001b ; Ligne 1 Colonne 9
    	;MOV	R2,#10001000b ; Ligne 1 Colonne 8
    	MOV	R0,#CPT_A3
    	AJMP M2_Afficher_CPT
    M2_Afficher_CPT_B:
    	;On laisse les heures aller jusque 255
    	MOV	R2,#11001001b ; Ligne 2 Colonne 9
    	;MOV	R2,#11001000b ; Ligne 2 Colonne 8
    	MOV	R0,#CPT_B3
    M2_Afficher_CPT:
    	ACALL	LcdCommande
    	;On laisse les heures aller jusque 255
    	;MOV	R2,#00100000b ;Caractère ' '
    	;ACALL	LcdChar
    	MOV	R2,#01111000b ;Caractère 'x'
    	ACALL	LcdChar
    	MOV	A,@R0;3
    	ACALL	LcdOctet2Digits
    	DEC	R0
    	MOV	A,@R0;2 
    	ACALL	LcdOctet2Digits
    	DEC	R0
    	MOV	A,@R0;1 
    	ACALL	LcdOctet2Digits
    RET
     
    ;== 2 - INTER ANTIREBONDS =================================================================================================================
    M3:
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM2
    	ACALL	LcdTextePlusBACK
    	SETB	SEMAPHO.0 ; Choix BP/I
    	MOV 	P1,#00010101b
    M3_Boucle:
    	ACALL	ClavierAttendreTouche
     
    	MOV	A,R3
    	RL	A ;Multiplication par deux ; une instruction "AJMP xxxx" fait deux octets
    	MOV	DPTR,#M3_MenuChoix
    	JMP	@A+DPTR
    M3_MenuChoix:  ;L'ordre des AJMP ci-dessous correspond aux valeurs de R3
    	AJMP	M3_Menu0_Touche6_R
    	AJMP	RetourProgrammePrincipal; M3_Menu1_ToucheA_A
    	AJMP	M3_Menu2_Touche4_L
    	AJMP	M3_Menu3_ToucheE_E
    	AJMP	M3_Menu4_Touche2_DN
    	AJMP	M3_Menu5_Touche8_UP
    	AJMP	M3_Menu6_Touche3_PDN
    	AJMP	M3_Menu7_Touche9_PUP
    M3_Menu0_Touche6_R:   ;=============================================
    	;Mode Poussoirs / Inter
    	CPL	SEMAPHO.0 ;Inversion sémaphore
    	MOV 	P1,#00010101b ;Reset sorties
    	;Affichage :
    	MOV	R2,#10001101b ; Ligne 1 Colonne 13
    	ACALL	LcdCommande
    	JNB	SEMAPHO.0,M3_AffichageInter
    	MOV	R2,#01000010b ; Caractère "B"
    	ACALL	LcdChar
    	MOV	R2,#01010000b ; Caractère "P"
    	ACALL	LcdChar
    	AJMP	M3_AffichageFin
    	M3_AffichageInter:
    	MOV	R2,#01001001b ; Caractère "I"
    	ACALL	LcdChar
    	ACALL	M4_LcdChar_ESPACE
    M3_AffichageFin:
    	ACALL	MegaPause
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu3_ToucheE_E:   ;=============================================
    	SETB	P1.4
    	CLR	P1.5 	
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu2_Touche4_L:   ;=============================================
    	CLR	P1.4
    	SETB	P1.5 	
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu4_Touche2_DN:  ;=============================================
    	CLR	P1.2
    	SETB	P1.3 	
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu5_Touche8_UP:  ;=============================================
    	SETB	P1.2
    	CLR	P1.3 	
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu6_Touche3_PDN: ;=============================================
    	CLR	P1.0
    	SETB	P1.1 	
    	AJMP	M3_ToucheEnfoncee_Fin
    M3_Menu7_Touche9_PUP: ;=============================================
    	SETB	P1.0
    	CLR	P1.1 	
    ;	AJMP	M3_ToucheEnfoncee_Fin
    M3_ToucheEnfoncee_Fin:
     
    	ACALL	BigPause
     
    	JNB	SEMAPHO.0,M3_Inter
     
    	;Mode bouton poussoir - On attend le relâchement de la touche :
    M3_PoussoirContinuer:
    	ACALL 	Pause
    	JNB	P3.2,M3_PoussoirContinuer
    	MOV 	P1,#00010101b
     
    M3_Inter:
    	AJMP M3_Boucle
     
    ;== 4 - PORTE LOGIQUE 7 ENTREES ===========================================================================================================
    M4_LcdChar_EGAL:
    	MOV	R2,#00111101b 
    	AJMP	MA_LcdChar_XXX_Fin
    M4_LcdChar_ESPACE:
    	MOV	R2,#00100000b 
    	AJMP	MA_LcdChar_XXX_Fin
    M4_LcdChar_INV:
    	MOV	R2,#00101111b 
    MA_LcdChar_XXX_Fin:
    	ACALL	LcdChar
    RET
     
    M4_Calcul_Sortie:
    	;On récupère les entrées :
    	MOV	A,P1
    	ANL	A,#01111111b ;le bit 7 est la sortie, les autres les entrées
     
    	;ATTENTION !!! Les instructions CJNE modifient C !!!
    	CJNE	R4,#5,M4_Calcul_Sortie_PasXOR
    	;FONCTION XOR
    	MOV	C,PSW.0
    	AJMP	M4_Calcul_Sortie_Fin
     
    M4_Calcul_Sortie_PasXOR:
    	CJNE	R4,#7,M4_Calcul_Sortie_PasOR
    	;FONCTION OR
    	SETB	C
    	JNZ	M4_Calcul_Sortie_Fin
    	CLR	C
    	AJMP	M4_Calcul_Sortie_Fin
     
    M4_Calcul_Sortie_PasOR:
    	CJNE	R4,#3,M4_Calcul_Sortie_PasAND
    	;FONCTION AND
    	ORL	A,#10000000b
    	;A=1xxxxxxx
    	CPL	A
    	CLR	C
    	JNZ	M4_Calcul_Sortie_Fin
    	SETB	C
    	AJMP	M4_Calcul_Sortie_Fin
     
    M4_Calcul_Sortie_PasAND:
    	;FONCTION =1
    	;A=0xxxxxxx
    	MOV	R6,#7
    	M4_Calcul_Sortie_1_Boucle:
    	CJNE	A,#00000001b,M4_Calcul_Sortie_1_Suite
    	SETB	C
    	AJMP	M4_Calcul_Sortie_Fin
    	M4_Calcul_Sortie_1_Suite:
    	RR	A
    	DJNZ	R6,M4_Calcul_Sortie_1_Boucle
    	CLR	C
     
    M4_Calcul_Sortie_Fin:
    	;CJNE	R0,#1,M4_Calcul_Sortie_PasInversion ATTENTION !!! Les instructions CJNE modifient C !
    	MOV	A,R0
    	JNZ	M4_Calcul_Sortie_PasInversion
    	CPL	C
    	M4_Calcul_Sortie_PasInversion:
     
    	;Affichage sortie :
    	MOV	P1.7,C
    RET
     
    M4:
    	MOV	P1,#01111111b ;Configuration des broches en entrées sauf P1.7 qui est la sortie
    	MOV	R3,#3
    	;
    	;ACALL	LcdCommande_Ligne1_Colonne0
    	;MOV	DPTR,#TexteM4
    	;ACALL	LcdTextePlusBACK
    	MOV	R2,#10001011b ; Ligne 1 Colonne 11
    	ACALL 	LcdCommande
    	ACALL 	LcdTexteBACK
    	;
    	AJMP	M4_ToucheEnfoncee
     
    M4_Boucle:
    	ACALL	Incrementer_LS138
    	JNB	P3.2,M4_ToucheEnfoncee
    	ACALL	M4_Calcul_Sortie
    	AJMP M4_Boucle
    M4_ToucheEnfoncee:
    	CJNE	R3,#1,M4_Touche_Pas1
    	ACALL	RetourProgrammePrincipal 
    M4_Touche_Pas1:
    ;	     AFFICHAGE :
    ;        0123456789012345
    ;	    ' OR  XOR  AND  1'
    ;R3=R4=   7   5    3    -     R0=0  / INV
    ;R3=      6   4    2    0     R0=1  =
    ;R4 - R0 = R3
     
    ;CALCUL DE R0 ET DE R4 :
    	MOV	A,R3
    	MOV	R0,#0
    	JB	ACC.0,M4_R3_Impair
    	MOV	R0,#1
    	INC	A
    M4_R3_Impair:
    	MOV	R4,A
     
    	ACALL	M4_Calcul_Sortie
     
    	;EFFACAGE :
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM4_2
    	ACALL	LcdTexte
     
    	;ECRITURE TEXTE :
    	;CJNE	R4,#7,M4_R4_Pas7 ;FONCTION OR / NOR
    	MOV	R2,#11000000b ; Ligne 2 Colonne 0
    M4_R4_Pas7:
    	CJNE	R4,#5,M4_R4_Pas5 ;FONCTION XOR / NXOR
    	MOV	R2,#11000100b ; Ligne 2 Colonne 4
    M4_R4_Pas5:
    	CJNE	R4,#3,M4_R4_Pas3 ;FONCTION AND / NAND
    	MOV	R2,#11001001b ; Ligne 2 Colonne 9
    	AJMP	M4_R4_Pas1
    M4_R4_Pas3:
    	CJNE	R4,#1,M4_R4_Pas1 ;FONCTION =1 
    	MOV	R2,#11001110b ; Ligne 2 Colonne 14
    M4_R4_Pas1:
    	ACALL	LcdCommande
    	CJNE	R0,#0,M4_R0_Pas0
    	ACALL	M4_LcdChar_INV
    	AJMP	M4_R0_0
    M4_R0_Pas0:
    	ACALL	M4_LcdChar_EGAL
    M4_R0_0:
     
    	ACALL	MegaPause
    	AJMP M4_Boucle
     
    ;== 5 - COMPTEUR ASCII ====================================================================================================================
    M5:
    	MOV	R7,#1
    	AJMP	M6_BIS
     
    ;== 6 - COMPTEUR GRAY =====================================================================================================================
    M6:
    	MOV	R7,#0
    M6_BIS:
    	CLR	SEMAPHO.0 ;Choix GRAY / DECIMAL
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM5
    	ACALL	LcdTextePlusBACK
    	CLR	A
    	MOV	R0,A ;A=0 Vitesse=0
    	MOV	R6,A ;A=0
    	MOV 	P1,R6
    	ACALL	MegaPause ; Evite appui sur 'E' détecté
    M6_Boucle:
    	ACALL	ClavierAttendreTouche
     
    	MOV	A,R0 ;Copie vitesse dans R1
    	MOV	R1,A
     
    	MOV	A,R3
    	RL	A ;Multiplication par deux ; une instruction "AJMP xxxx" fait deux octets
    	MOV	DPTR,#M6_MenuChoix
    	JMP	@A+DPTR
    M6_MenuChoix:  ;L'ordre des AJMP ci-dessous correspond aux valeurs de R3
    	AJMP	M6_Menu0_Touche6_R
    	AJMP	RetourProgrammePrincipal; M6_Menu1_ToucheA_A
    	AJMP	M6_Menu2_Touche4_L
    	AJMP	M6_Menu3_ToucheE_E
    	AJMP	M6_Menu4_Touche2_DN
    	AJMP	M6_Menu5_Touche8_UP
    	AJMP	M6_Menu6_Touche3_PDN
    	AJMP	M6_Menu7_Touche9_PUP
    M6_Menu3_ToucheE_E:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	CJNE	R7,#1,M6_Changement_GRAY_DECIMAL
    	;Code uniquement pour le mode "ASCII" :
    	MOV	A,R6
    	JZ M6_P1_deja_zero
    	MOV	R6,#00000000b
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_P1_deja_zero:
    	MOV	R6,#11111111b
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Changement_GRAY_DECIMAL:
    	CPL	SEMAPHO.0
    	MOV	R2,#10001111b ; Ligne 1 Colonne 15
    	ACALL	LcdCommande
    	MOV	R2,#01000100b ; Caractère "D"
    	JB	SEMAPHO.0,M6_Changement_DECIMAL
    	MOV	R2,#01000111b ; Caractère "G"
    M6_Changement_DECIMAL:
    	ACALL	LcdChar
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu0_Touche6_R:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	ACALL	M7_VitessePlus
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu2_Touche4_L:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	ACALL	M7_VitesseMoins
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu4_Touche2_DN:  ;=============================================
    	CJNE	R7,#1,M6_ToucheEnfoncee_Fin
    	;Code uniquement pour le mode "ASCII" :
    	MOV	A,R6
    	ADD 	A,#240
    	MOV R6,A
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu5_Touche8_UP:  ;=============================================
    	CJNE	R7,#1,M6_ToucheEnfoncee_Fin
    	;Code uniquement pour le mode "ASCII" :
    	MOV	A,R6
    	ADD 	A,#16
    	MOV	R6,A
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu6_Touche3_PDN: ;=============================================
    	DEC	R6
    	AJMP	M6_ToucheEnfoncee_Fin
    M6_Menu7_Touche9_PUP: ;=============================================
    	INC	R6
    M6_ToucheEnfoncee_Fin:
     
    	CJNE	R7,#1,M6_EcritureGray
    	;Code uniquement pour le mode "ASCII" :
    	MOV 	P1,R6 
    	AJMP	M6_EcritureFin
    M6_EcritureGray:
    	JB	SEMAPHO.0,M6_EcritureDecimal
    	;ICI IL FAUT CONVERTIR EN CODE GRAY !!!
    	MOV A, R6
    	MOV R4, A
    	CLR C
    	RRC A
    	XRL A, R4
    	MOV P1,A
    	AJMP	M6_EcritureFin
    M6_EcritureDecimal:	
    	;ICI IL FAUT ALLUMER LE BIT DONT LE N° EST LE NOMBRE DEFINIT PAR LES 3 PREMIERS BITS DE R6
    	MOV B, R6
    	ANL	B,#00000111b
    	MOV	A,#00000001b
    M6_EcritureDecimal_RL:
    	RL	A
    	DJNZ	B,M6_EcritureDecimal_RL
    	MOV P1,A
    M6_EcritureFin:
     
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	A,R6
    	;ACALL 	LcdOctet3Digits
    	ACALL	LcdOctetHexaEtDecimal
     
    	ACALL	M7_Pause
     
    	AJMP M6_Boucle
     
    ;== 7 - MOTEUR PAS A PAS ==================================================================================================================
    M7:
    	;MOV	R2,#11000000b ; Ligne 2 Colonne 0
    	ACALL	LcdCommande_Ligne2_Colonne0
    	MOV	DPTR,#TexteM7
    	ACALL	LcdTextePlusBACK
    	CLR A
    	MOV	R4,A ;A=0 ;MODE un/deux/demi
    	MOV	POS1,A ;A=0 ;Position Moteur 1
    	MOV	POS2,A ;A=0 ;Position Moteur 2
    	MOV	R0,A ;A=0 Vitesse=0
    	MOV	R1,A ;A=0 
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Boucle:
    	ACALL	ClavierAttendreTouche
     
    	MOV	A,R0 ;Copie vitesse dans R1
    	MOV	R1,A
     
    	MOV	A,R3
    	RL	A ;Multiplication par deux ; une instruction "AJMP xxxx" fait deux octets
    	MOV	DPTR,#M7_MenuChoix
    	JMP	@A+DPTR
    M7_MenuChoix:  ;L'ordre des AJMP ci-dessous correspond aux valeurs de R3
    	AJMP	M7_Menu0_Touche6_R
    	AJMP	RetourProgrammePrincipal; M7_Menu1_ToucheA_A
    	AJMP	M7_Menu2_Touche4_L
    	AJMP	M7_Menu3_ToucheE_E
    	AJMP	M7_Menu4_Touche2_DN
    	AJMP	M7_Menu5_Touche8_UP
    	AJMP	M7_Menu6_Touche3_PDN
    	AJMP	M7_Menu7_Touche9_PUP
    M7_Menu3_ToucheE_E:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	INC	R4
    	CJNE	R4,#3,M7_ModePasTropGrand
    	MOV	R4,#0
    M7_ModePasTropGrand:
    	ACALL	M7_ChangerMode
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu2_Touche4_L:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	ACALL	M7_VitesseMoins
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu0_Touche6_R:   ;=============================================
    	MOV	R1,#0 ;PAUSE pour les touches "on/off" pour éviter clignotement
    	ACALL	M7_VitessePlus
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu4_Touche2_DN:  ;=============================================
    	DEC	POS2
    	CJNE	R4,#2,M7_DN_MOT2_DemiPas
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_DN_MOT2_DemiPas:
    	DEC	POS2
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu5_Touche8_UP:  ;=============================================
    	INC	POS2
    	CJNE	R4,#2,M7_UP_MOT2_DemiPas
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_UP_MOT2_DemiPas:
    	INC	POS2
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu6_Touche3_PDN: ;=============================================
    	DEC	POS1
    	CJNE	R4,#2,M7_DN_MOT1_DemiPas
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_DN_MOT1_DemiPas:
    	DEC	POS1
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_Menu7_Touche9_PUP: ;=============================================
    	INC	POS1
    	CJNE	R4,#2,M7_UP_MOT1_DemiPas
    	AJMP	M7_ToucheEnfoncee_Fin
    M7_UP_MOT1_DemiPas:
    	INC	POS1
    ;	AJMP	M7_ToucheEnfoncee_Fin
    M7_ToucheEnfoncee_Fin:
     
    ;Séquences de commande :
    ;<1>    <2>    <1/2>       Position
    ;0001          0001    A   0 000b
    ;       0101   0101  C A   1 001b  2
    ;0100          0100  C     2 010b
    ;       0110   0110  C B   3 011b  2
    ;0010          0010    B   4 100b
    ;       1010   1010  D B   5 101b  2
    ;1000          1000  D     6 110b
    ;       1001   1001  D A   7 111b  2
    ;Il faut calculer R6 à partir de POS1 et POS2
     
    	ANL	POS1,#00000111b
    	ANL	POS2,#00000111b
     
    	;Le code suivant fait A=TableauPasAPas(POS1)
    	MOV	DPTR,#TableauPasAPas 	;Adresse du tableau de données
    	MOV	A,POS1			;Index
    	MOVC	A,@A+DPTR		;Lecture
     
    	MOV 	R6,A
     
    	MOV	DPTR,#TableauPasAPas 	;Adresse du tableau de données
    	MOV	A,POS2			;Index
    	MOVC	A,@A+DPTR		;Lecture
    	SWAP	A
     
    	ORL	A,R6
    	MOV 	P1,A
     
    	ACALL	M7_Pause
     
    	AJMP M7_Boucle
     
    M7_Pause:
    	;CALCUL DE LA PAUSE A FAIRE :
    	MOV	A,#11111111b
    	CJNE	R1,#0,M7_CalculPause
    	AJMP	M7_CalculPause_Fin
    M7_CalculPause:
    	MOV	A,#00000001b
    M7_CalculPause_Continuer:
    	RR	A
    	DJNZ	R1,M7_CalculPause_Continuer
    M7_CalculPause_Fin:
    	MOV	PAUSE2,A
    	ACALL	Pause2Cont
    RET	
     
    M7_VitessePlus:
    	INC	R0
    	CJNE	R0,#9,M7_ChangerVitesse
    	MOV	R0,#0
    	AJMP	M7_ChangerVitesse
    M7_VitesseMoins:	
    	DEC	R0
    	CJNE	R0,#255,M7_ChangerVitesse
    	MOV	R0,#8
    M7_ChangerVitesse:
    	MOV	R2,#11001001b ; Ligne 2 Colonne 9
    	MOV	A,MENU
    	CJNE	A,#7,M7_ChangerVitesse_MenuPas7
    	MOV	R2,#11001000b ; Ligne 2 Colonne 8
    M7_ChangerVitesse_MenuPas7:
    	ACALL	LcdCommande
    	MOV	A,R0
    	MOV	R2,A
    	ACALL	LcdChiffre 
    RET
     
    M7_ChangerMode:
    	;ACALL	LcdCommande_Ligne2_Colonne11
    	MOV	R2,#11001010b ; Ligne 2 Colonne 10
    	ACALL	LcdCommande
    	CJNE	R4,#0,M7_ChangerMode_Pas0
    	;MOV	DPTR,#TexteM7_Un
    	MOV	R2,#00110001b ;Caractère '1'
    	;Mise en cohérence sorties si deux sorties sont actives :
    	JNB	POS1.0,M7_Coherence1 
    	INC 	POS1
    	M7_Coherence1:
    	JNB	POS2.0,M7_Coherence2 
    	INC 	POS2
    	M7_Coherence2:
    	AJMP	M7_ChangerMode_Fin
    M7_ChangerMode_Pas0:
    	CJNE	R4,#1,M7_ChangerMode_Pas1
    	;MOV	DPTR,#TexteM7_Deux
    	MOV	R2,#00110010b ;Caractère '2'
    	;Mise en cohérence sorties si une sortie est active :
    	JNB	POS1.0,M7_Coherence3 
    	AJMP	M7_ChangerMode_Fin
    	M7_Coherence3:
    	DEC 	POS1
    	JNB	POS2.0,M7_Coherence4 
    	AJMP	M7_ChangerMode_Fin
    	M7_Coherence4:
    	DEC 	POS2
    	AJMP	M7_ChangerMode_Fin
    M7_ChangerMode_Pas1:
    	;MOV	DPTR,#TexteM7_Demi
    	MOV	R2,#01000100b ;Caractère 'D'
    	;Pas besoin de mise en cohérence !
    M7_ChangerMode_Fin:
    	ACALL	LcdChar
    RET
     
    ;== GESTION CLAVIER ET LCD ================================================================================================================
     
    ClavierAttendreTouche:
    	ACALL	Incrementer_LS138
    	JB	P3.2,ClavierAttendreTouche
    RET
     
    Incrementer_LS138:
    	;ATTENTION TEMP_B est utilisé dans les fonctions de l'afficheur LCD, qui peuvent être appellées en interruption
    	INC	R3                  
    	MOV TEMP_B2,R3
    	ANL	TEMP_B2,#00000111b
    	MOV R3,TEMP_B2
    	MOV	C,TEMP_B2.0
    	MOV	P3.5,C
    	MOV	C,TEMP_B2.1
    	MOV	P3.4,C
    	MOV	C,TEMP_B2.2
    	MOV	P3.3,C
    	ACALL	Pause
    RET
     
    LcdTextePlusBACK:
    	MOV	R5,#11 ;***
    	ACALL	LcdTexteStart
    LcdTexteBACK:
    	MOV	DPTR,#TexteMi_BACK
    LcdTexte5:
    	MOV	R5,#5 ;***
    	AJMP	LcdTexteStart
    LcdTexte:
    	MOV	R5,#16 ;***
    LcdTexteStart:
    	SETB	P3.0 ;RS=1
    LcdTexteDebut:
    	CLR	A
    	MOVC	A,@A+DPTR
    	JZ	LcdTexteFin ;On pourrait supprimer cette instruction vu qu'aucun texte ne se termine plus par un octet null
    	INC	DPTR
    	MOV	R2,A
    	ACALL	EcrireH
    	DEC	R5;*** R5--
    	CJNE	R5,#0,LcdTexteDebut ;*** R5 définit la longeur des textes et évite de stocker un octet null après chaque texte
    LcdTexteFin:
    RET
     
    LcdTexteVide5:
    	MOV	R5,#5 ;***
    LcdTexteVideX:
    	;MOV	R2,#00100000b 
    	LcdTexteVide5_Suite:
    	ACALL	M4_LcdChar_ESPACE
    	DJNZ	R5,LcdTexteVide5_Suite
    RET
     
    LcdCommande_Ligne1_Colonne0:
    	MOV	R2,#10000000b ; Ligne 1 Colonne 0
    	AJMP	LcdCommande
    LcdCommande_Ligne2_Colonne11:
    	MOV	R2,#11001011b ; Ligne 2 Colonne 11
    	AJMP	LcdCommande
    LcdCommande_Ligne2_Colonne0:
    	MOV	R2,#11000000b ; Ligne 2 Colonne 0
    LcdCommande:
    	CLR	P3.0 ;RS=0
    	ACALL	EcrireH
    RET
     
    ;LcdCommandeL:
    ;	CLR	P3.0 ;RS=0
    ;	MOV TEMP_B,R2
    ;	ACALL	EcrireL
    ;RET
     
    LcdOctetHexaEtDecimal:
    	MOV	TEMPA,A
    	MOV	TEMPR0,R0 ;IMPORTANT : Il faut sauvegarder et restaurer R0
    	ACALL	LcdOctetHexa
    	MOV	R0,TEMPR0 ;IMPORTANT : Il faut sauvegarder et restaurer R0
    	ACALL	M4_LcdChar_ESPACE
    	MOV	A,TEMPA
    	ACALL	LcdOctet3Digits
    RET
     
    LcdOctetHexa: ;Afficher l'octet contenu dans A en hexadécimal de 00 à FF
    	; HEXA          LCD
    	; 0000.0000  0  0011.0000
    	; 0000.0001  1  0011.0001
    	; 0000.0010  2  0011.0010
    	; 0000.0011  3  0011.0011
    	; 0000.0100  4  0011.0100
    	; 0000.0101  5  0011.0101
    	; 0000.0110  6  0011.0110
    	; 0000.0111  7  0011.0111
    	; 0000.1000  8  0011.1000
    	; 0000.1001  9  0011.1001
    	; ---- ----  -  ---- ----
    	; 0000.1010  A  0100.0001
    	; 0000.1011  B  0100.0010
    	; 0000.1100  C  0100.0011
    	; 0000.1101  D  0100.0100
    	; 0000.1110  E  0100.0101
    	; 0000.1111  F  0100.0110
    	MOV	TEMPHEX,#0
    	MOV	R0,#TEMPHEX
    	;TEMPHEX = 0000.0000  A = aaaa.bbbb
    	XCHD	A,@R0
    	;TEMPHEX = 0000.bbbb  A = aaaa.0000
    	SWAP	A
    	;TEMPHEX = 0000.bbbb  A = 0000.aaaa
    	ACALL	LcdOctetHexa2
    	;TEMPHEX = 0000.bbbb  A = yyyy.xxxx
    	XCH	A,@R0
    	;TEMPHEX = yyyy.xxxx  A = 0000.bbbb
    LcdOctetHexa2:	
    	CJNE	A,#10,LcdOctetHexa_Suite ;SI A<10 ALORS C=1 SINON C=0
    LcdOctetHexa_Suite:
    	JC	LcdOctetHexa_09	;saut si C=1 (donc A<10)
    	DEC	A
    	ANL A,#00000111b
    	ORL	A,#01000000b 
    	MOV	R2,A
    	ACALL	LcdChar
    RET
    LcdOctetHexa_09:
    	MOV	R2,A
    	ACALL	LcdChiffre
    RET
    ;
    LcdOctet3Digits: ;Afficher l'octet contenu dans A en décimal de 000 à 255
    	MOV B, #100
    	DIV AB		; division par 100
    	MOV R2, A	; résultat (centaines)
    	ACALL	LcdChiffre
    	MOV A, B	; reste dans A
    LcdOctet2Digits: ;Afficher l'octet contenu dans A en décimal de 00 à 99
    	MOV B, #10
    	DIV AB		; division par 10
    	MOV R2, A	; résultat (dizaines) 
    	ACALL	LcdChiffre
    	MOV R2, B	; reste (unités)
    LcdChiffre:
    	MOV TEMP_B,R2
    LcdChiffre_TEMP_B:
    	ORL	TEMP_B,#00110000b ;Astuce : pour un écran LCD, les chiffres de 0 à 9 correspondent respectivement à 00110000 et à 001101001
    	MOV R2,TEMP_B
    LcdChar:
    	SETB	P3.0 ;RS=1
    EcrireH:
    	MOV TEMP_B,R2
    	MOV	C,TEMP_B.7
    	MOV	P3.7,C
    	MOV	C,TEMP_B.6
    	MOV	P3.5,C
    	MOV	C,TEMP_B.5
    	MOV	P3.4,C
    	MOV	C,TEMP_B.4
    	MOV	P3.3,C
    	ACALL	PulseP31
    EcrireL:
    	MOV	C,TEMP_B.3
    	MOV	P3.7,C
    	MOV	C,TEMP_B.2
    	MOV	P3.5,C
    	MOV	C,TEMP_B.1
    	MOV	P3.4,C
    	MOV	C,TEMP_B.0
    	MOV	P3.3,C
    PulseP31:
    	ACALL Pause
    	SETB	P3.1
    	ACALL Pause
    	CLR	P3.1
    Pause:	
    	MOV	PAUSE1,#15 ;Réglage de la temporisation PAUSE
    PauseCont:
    	DJNZ	PAUSE1,PauseCont ;2 cycles - 1 cycle dure 12 impulsions d'horloge soit 1,5µs
    RET
     
    MegaPause:
    	MOV	PAUSE2,#255 ;Réglage de la temporisation MEGA PAUSE
    	AJMP	Pause2Cont
    BigPause:  
    	MOV	PAUSE2,#25 ;Réglage de la temporisation BIG PAUSE
    Pause2Cont:
    	MOV	PAUSE1,#255
    Pause1Cont:
    	DJNZ	PAUSE1,Pause1Cont 
    	DJNZ	PAUSE2,Pause2Cont 
    RET
     
     
    END	;Fin du fichier


    Je me sers de cette carte tous les jours en minuterie de cuisine - elle est vraiment précise (j'ai réussi à avoir qu'une seule seconde de retard par jour) - et la fonction chien de garde qui est une minuterie redéclenchable est très pratique... pour cuire des crêpes !

    Cette carte sera utile pour dépanner ou mettre au point d'autres cartes.

    J'ai toujours regretté de ne pas avoir terminé ce projet à base de 8051, voilà une bonne chose de faite !

    Ce message pourra peut être aider ceux qui doivent encore travailler avec des 8051, ou rappeler pas mal de souvenirs à d'autres

    J'utilise :
    - le logiciel MIDE-51 pour compiler
    - NotePad++ pour éditer mon code (attention l'éditeur intégré à MIDE-51 est pas mal buggué on peut massacrer un fichier )
    - un programmateur MINI PRO USB très pratique et pas cher (il permet de programmer de nombreuses puces mais aussi de tester de nombreux circuits logiques TTL et CMOS)

    Le livre de Philippe KAUFFMANN "Mise en oeuvre et applications du microcontrôleur 8051" m'a beaucoup aidé (édition 1996, payé 200 Francs à l'époque), même si la datasheet de l'ATMEL 89C2051 est très complète.

    Maintenant je vais me mettre aux Arduinos et Rasberry pi avec un projet domotique maison

    A bientôt !

  2. #2
    Expert éminent
    Merci pour ce retour , c'est intéressant

    Citation Envoyé par electroremy Voir le message

    Je me suis senti un peu dans la peau des développeurs des années 80 et 90 à l'époque où il fait faire tourner des logiciels et des jeux sur des ordinateurs avec peu de mémoire et de capacité de calcul. Je suis né en 1980, j'ai commencé l'informatique avec un Amiga 1200, une merveilleuse machine, les programmeurs de l'époque ont fait des logiciels et des jeux magnifiques avec peu de ressources. J'ai connu l'époque des "démos" ou des hackers arrivaient à pousser les machines dans leurs limites pour faire de la 3D ou afficher plus de couleurs que ce que la machine permettait à l'origine.
    Je connais ce sentiment vu que pendant mon temps libre je code sur de vielles machines
    Et je connais ces contrainte aussi , j'ai du faire un moment en asm un driver sonore avec 2ko de code sur un 1 MHz

    Je connais que l'Amiga que de nom , je suis né bien plus tard mais j'aurais bien voulu connaître l'Amgia 500 en tout cas

  3. #3
    Membre confirmé
    j'ai retrouvé des at89C4051 (les même mais avec 4Ko je crois) et pareil j'avais jamais réussi a le faires fonctionner. il faut dire que j'avait essayé de fabriquer le programmateur moi même. par contre je ne me souviens plus du compilateur et du programmateur a utiliser avec tout ça. est que ça se vend encore?

  4. #4
    Membre actif
    Citation Envoyé par bifur Voir le message
    j'ai retrouvé des at89C4051 (les même mais avec 4Ko je crois) et pareil j'avais jamais réussi a le faires fonctionner. il faut dire que j'avait essayé de fabriquer le programmateur moi même. par contre je ne me souviens plus du compilateur et du programmateur a utiliser avec tout ça. est que ça se vend encore?
    J'utilise :
    - le logiciel MIDE-51 pour compiler, il marche sous Windows 7
    - NotePad++ pour éditer mon code (attention l'éditeur intégré à MIDE-51 est pas mal buggué on peut massacrer un fichier )
    - pour programmer mes puces ATMEL, un programmateur MINI PRO USB très pratique et pas cher (il permet de programmer de nombreuses puces mais aussi de tester de nombreux circuits logiques TTL et CMOS)

    J'avais fabriqué un programmateur qui fonctionnait avec le port parallèle (voir ici : http://electroremy.free.fr/elec-mo-atmel.html) mais ce port n'est plus pris en charge par les PC récents.

    A bientôt

  5. #5
    Responsable Systèmes

    Si tu souhaites reprendre d'anciens projets, je te recommendes de regarder du coté d'Arduino, et/ou du Raspberry. Cela te permettra d'avoir du matériel plus moder qu'un 8051, avec possibilité d'utiliser du C, et surtout pas de soucis de programmation d'Eprom, ni d'approvisionnement (je ne sais pas si le 8051 se trouve facilement).
    Ma page sur developpez.com : http://chrtophe.developpez.com/ (avec mes articles)
    Mon article sur la création d'un système : http://chrtophe.developpez.com/tutor...s/minisysteme/
    Mon article sur le P2V : http://chrtophe.developpez.com/tutoriels/p2v/
    Consultez nos FAQ : Windows, Linux, Virtualisation

  6. #6
    Membre actif
    Citation Envoyé par chrtophe Voir le message
    Si tu souhaites reprendre d'anciens projets, je te recommendes de regarder du coté d'Arduino, et/ou du Raspberry. Cela te permettra d'avoir du matériel plus moder qu'un 8051, avec possibilité d'utiliser du C, et surtout pas de soucis de programmation d'Eprom, ni d'approvisionnement (je ne sais pas si le 8051 se trouve facilement).
    Oui, Arduino et Raspberry sont au programme...

    J'ai commencé avec un NanoESP qui me donne un peu de fil a retordre pour une application particulière (https://www.developpez.net/forums/d2...t-bug-bizarre/) mais que j'arrive à faire fonctionner en serveur TCP

    Sinon, les 8051 ne sont pas morts loin de la...

    On trouve les puces AT89Cx051 (X étant la quantité de ROM en kO) à moins de 2€

    Le soucis avec les Raspberry Pi (et dans une moindre mesure avec les Arduinos) est que leur consommation électrique ne se prête pas à une alimentation sur pile longue durée.

    Pour une application vraiment économe en énergie il faut faire son propre circuit.
    Les AT89Cx051 consomment peu et peuvent être alimentés jusque 2,7V :
    - conso à 12 Mhz : 5,5mA sous 3V
    - conso à 12 Mhz, Idle mode : 1mA sous 3V
    - conso en mode power down : 20µA sous 3V
    Les AT89Cx051 peuvent descendre en fréquence très bas (on peut faire fonctionner leur horloge à quelques Hz seulement, pour certaines applications de contrôle ou d'électrotechnique c'est suffisant).

    Autre avantage de la programmation en assembleur : si c'est un peu difficile au début on s'y fait avec l'habitude et surtout on maîtrise vraiment tout.
    Le C++ des Arduinos semble pratique, les librairies super pratiques mais quand on tombe sur un bug c'est l'enfer... Un peut comme l'enfer des DLL et OCX avec Visual Basic.

    Les Arduinos offrent l’avantage de ne pas s'embêter à faire un circuit imprimé, surtout quand on a besoin de toutes les interfaces et des alimentations

    Mais pour une application précise parfois il ne faut pas grand chose... Pour une application précise alimentée sur pile, un AT89Cx051 sur un morceau de véroboard avec quelques composants discret suffit, prendra moins de place et consommera moins de courant. En assembleur on maîtrise tout on n'est pas piégé avec une nouvelle version d'IDE dont les nouvelles librairies ne sont plus compatibles, avec des problèmes de firmware et de bootloader.

    De plus la disponibilité et la compatibilité à long terme d'une puce 8051 seule est sûrement plus longue que celle d'un modèle précis de carte Arduino.

    En tout cas je suis content d'avoir d'abord fait mes armes avec ma propre carte 8051 et un programme 100% maison en assembleur avant d'attaquer le monde des Arduinos.
    C'est plus sain, ça me permet de ne pas être prisonnier d'un écosystème, ni d'utiliser un marteau pour enfoncer une punaise.

    A bientôt