Architecture du système :
1.Microcontrôleur principal STC15F2K16S2
Le STC15F2K16S2 représente un microcontroller fondé sur un kernel 8051 optimisé, pouvant atteindre une fréquence d'horloge de 35MHz (différent du STC89C51, aucun oscillateur externe n'est requis). Ce circuit intègre 16KB de mémoire Flash pour le programme et 512B de SRAM pour les données, accompagnés d'un module ADC 10 bits haute précision sur 8 canaux.
2.Circuit d'alimentation
La tension d'entrée VIN est fixée à 15V, avec un régulateur de tension standard.
Cette tension de 15V alimente également le capteur de force à poutre parallèle.
3.Capteur de force à poutre parallèle
Un modèle courant de capteur de force à poutre parallèle.
Principe de fonctionnement basé sur les jauges de contrainte.
Conventionnellement, le fil rouge correspond à l'entrée positive (E+), le fil noir à l'entrée négative (E-), les fils vert ou bleu à la sortie positive (S+), et le fil blanc à la sortie négative (S-). La tension d'alimentation du capteur varie de 5 à 15V, avec une sortie de 0 à 20mV.
4.Circuit d'amplification
Configuration classique d'amplification.
Le signal analogique faible issu du capteursubit un amplification définie, avec un circuit de limitation intégré.
L'AD620 constitue un amplificateur d'instrumentation classique basse consommation et haute précision, particulièrement adapté à l'amplification de signaux différentiels faibles. Une résistance externe R1 (potentiomètre 10kΩ) détermine le gain selon la formule G=1+49.4kΩ/R1, où 49.4kΩ représente la valeur du réseau de résistance精密 interne du芯片 AD620, constant fundamental de la formule de gain.
L'OP07 est un amplificateur opérationnel ultra-faible décalage et dérive réduite, configuré en amplificateur non-inverseur avec un gain G=1+R2/R3.
Le filtre passe-bas RC formé par R4 et C1 élimine les bruits haute fréquence pour un signal de sortie plus stable.
La diode Zener 1N5234B est connectée en inverse entre la sortie et la masse, assurant une fonction de protection par limitation de tension.
5.Afficheur LCD1602
Un écran LCD1602 standard.
Conception matérielle globale
Conception du PCB
Conception logicielle
1.Conversion ADC
Utilisation de l'environnement de développement associé.
Accès aux programmes d'exemple.
Sélection de l'exemple ADC souhaité.
Choix des fonctions correspondantes.
float ReadSensorValue(unsigned char channel)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | channel | ADC_START;
_nop_(); //Attente de 4 cycles NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//Attente fin de conversion
ADC_CONTR &= ~ADC_FLAG; //Désactivation ADC
return ADC_RES;
}
void ConfigureADC()
{
P1ASF = 0xff; //Configuration Port P1 en mode AD
ADC_RES = 0; //Registre résultat effacé
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
WaitDelay(2); //Activation ADC avec délai
}
void WaitDelay(unsigned int duration)
{
unsigned int counter;
while (duration--)
{
counter = 5000;
while (counter--);
}
}
2.Temporisation logicielle
Utilisation toujours de l'outil de développement.
#include "delay.h"
#include <intrins.h>
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while ((--i));
}
void DelayMultipleMs(unsigned int msCount)
{
while(msCount--)
Delay1ms();
}
3.Affichage LCD1602
Code facilement adaptable.
#include "LCD1602.h"
void LCDCheckBusy()
{
unsigned char status;
unsigned char timeout;
LCD1602_DB |= 0xF0;
LCD1602_RS = 0;
LCD1602_RW = 1;
do
{
LCD1602_EN = 1;
status = LCD1602_DB&0xF0;
LCD1602_EN = 0;
LCD1602_EN = 1;
status |= (LCD1602_DB&0xF0)>>4;
LCD1602_EN = 0;
timeout++;
if(timeout>50)
break;
}
while(status & 0x80);
}
void LCDSendCommand(unsigned char command)
{
LCDCheckBusy();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = command;
DelayMultipleMs(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
LCD1602_DB = command<<4;
DelayMultipleMs(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LCDSendData(unsigned char data)
{
LCDCheckBusy();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = data;
DelayMultipleMs(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
LCD1602_DB = data<<4;
DelayMultipleMs(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LCDSetup()
{
LCDSendCommand(0x33);
DelayMultipleMs(5);
LCDSendCommand(0x32);
LCDSendCommand(LCD_MODE_PIN4);
LCDSendCommand(LCD_DIS_ON);
LCDSendCommand(LCD_CURSOR_RIGHT);
LCDSendCommand(LCD_SCREEN_CLR);
}
void LCDSetCursor(unsigned char column, unsigned char line)
{
if(0 == line)
{
LCDSendCommand(0x80 | column);
}
else
{
LCDSendCommand(0x80|(0x40 + column));
}
}
void LCDDisplayText(unsigned char col, unsigned char line, unsigned char *text)
{
LCDSetCursor(col, line);
while(*text != '\0')
{
LCDSendData(*text++);
}
}
unsigned char ConvertToString(int value, unsigned char *buffer)
{
unsigned char index=0;
unsigned char length=0;
unsigned char temp[20];
if(value < 0)
{
value = -value;
*buffer++ = '-';
length++;
}
do
{
temp[index++] = value%10 + '0';
value /= 10;
}while(value > 0);
length += index;
while(index-- > 0)
{
*buffer++ = temp[index];
}
*buffer = '\0';
return length;
}
4.Fonction principale
#include <stc15.h>
#include "LCD1602.h"
#include "delay.h"
#include "adc.h"
float sensorValue=1234;
unsigned char displayBuffer[20];
void main()
{
LCDSetup();
DelayMultipleMs(5);
ConfigureADC();
while(1)
{
LCDDisplayText(0,0,"Poids:");
sensorValue=ReadSensorValue(2);
sensorValue=(sensorValue-111)*32;
FloatToString(sensorValue, displayBuffer);
LCDDisplayText(7,0,displayBuffer);
LCDDisplayText(15,0,"g");
}
}
Résultats de mise au point
Prototype fonctionnel
Mise sous tension.
Sans charge.
Avec une masse de 100g.