基于平行梁测力重量传感器的数字电子称设计
组成:
1.主控芯片STC15F2K16S2
STC15F2K16S2是一款基于增强型8051内核的单片机,主频最高可达35MHz(相比STC89C51,不需要额外添加外部晶振),内置16KB Flash程序存储器和512B SRAM数据存储器,同时内置了高精度的8路10位ADC模块。

2.电源电路
VIN设置为15V,很一般的稳压电路。
15V也用来给平行梁测力重量传感器供电。

3.平行梁测力重量传感器
很常见的平行梁测力重量传感器。

应变式力传感器的受力工作原理。

一般红色线为输入正(E+)、黑色线为输入负(E-)、绿色线或蓝色线为输出正(S+)、白色线为输出负(S-),这次使用传感器供电电压 5-15V,输出电压0-20mV。
4.放大电路
很常用的放大电路。
把传感器输出的微弱的模拟信号进行一定倍数的放大,设计限幅电路。

AD620是一款经典的低功耗、高精度仪表放大器,专为差分小信号放大设计,外接电阻R1(10kΩ电位器)用于设置增益增益,G=1+49.4kΩ/R1,49.4kΩ 是AD620芯片内部经过激光修调的精密电阻网络的等效阻值,是AD620增益公式的核心常数。
OP07是一款超低失调、低漂移的精密运算放大器,电路结构为同相比例放大,增益为G=1+R2/R3。
R4、C1构成RC低通滤波器,滤除高频噪声,使输出信号更平滑。
1N5234B是稳压二极管,反向并联在输出与地之间,起到限幅保护作用。
5.LCD1602显示屏
很普通的LCD1602显示屏

整体硬件设计

PCB设计

软件设计
1.ADC转换
打开这个熟悉的好帮手软件。

点击“范例程序”。

选择想要的ADC例程。

选择对应函数。

float GetADCResult(unsigned char ch)
{
// unsigned int ad_result;
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START;
_nop_(); //等待4个NOP
_nop_();
_nop_();
_nop_();
while (!(ADC_CONTR & ADC_FLAG));//等待ADC转换完成
ADC_CONTR &= ~ADC_FLAG; //Close ADC
return ADC_RES;
}

void InitADC()
{
P1ASF = 0xff; //设置P1口为AD口
ADC_RES = 0; //清除结果寄存器
ADC_CONTR = ADC_POWER | ADC_SPEEDLL;
Delay(2); //ADC上电并延时
}

void Delay(unsigned int n)
{
unsigned int x;
while (n--)
{
x = 5000;
while (x--);
}
}
2.软件延时
这边还是好帮手软件。

#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 DelayXms(unsigned int xms)
{
while(xms--)
Delay1ms();
}
3.LCD1602显示
很容易找到的代码。
#include "LCD1602.h"
void LCDReadBF()
{
unsigned char state;
unsigned char i;
LCD1602_DB |= 0xF0;//高四位IO置1 低四位保持不变
LCD1602_RS = 0;
LCD1602_RW = 1;
do
{
LCD1602_EN = 1;
state = LCD1602_DB&0xF0;//读高四位
LCD1602_EN = 0;
LCD1602_EN = 1;
state |= (LCD1602_DB&0xF0)>>4;//读低四位
LCD1602_EN = 0;
i++;
if(i>50)
break;
}
while(state & 0x80);
}
void LCDWriteCmd(unsigned char cmd)
{
LCDReadBF();//等待忙检测,不忙时操作
LCD1602_RS = 0;//命令
LCD1602_RW = 0;//写
LCD1602_DB = cmd;//高四位
DelayXms(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
LCD1602_DB = cmd<<4;//低四位
DelayXms(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LCDWriteData(unsigned char dat)
{
LCDReadBF();//等待忙检测,不忙时操作
LCD1602_RS = 1;//数据
LCD1602_RW = 0;//写
LCD1602_DB = dat;//高四位
DelayXms(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
LCD1602_DB = dat<<4;//第四位
DelayXms(1);
LCD1602_EN = 1;
LCD1602_EN = 0;
}
void LCDInit()
{
LCDWriteCmd(0x33);
DelayXms(5);
LCDWriteCmd(0x32);
LCDWriteCmd(LCD_MODE_PIN4);//显示模式设置 2行 5*8点阵
LCDWriteCmd(LCD_DIS_ON);//显示开 光标关
LCDWriteCmd(LCD_CURSOR_RIGHT);//光标右移
LCDWriteCmd(LCD_SCREEN_CLR);//清屏
}
void LCDSetPosition(unsigned char x,unsigned char y)
{
if(0 == y)
{
LCDWriteCmd(0x80 | x);
}
else
{
LCDWriteCmd(0x80|(0x40 + x));
}
}
void LCDShowStr(unsigned char x,unsigned char y,unsigned char *str)
{
LCDSetPosition(x,y);
while(*str != '\0')
{
LCDWriteData(*str++);
}
}
unsigned char IntegerToStr(int dat,unsigned char *str)
{
unsigned char i=0;
unsigned char len=0;
unsigned char buf[20];
if(dat < 0)
{
dat = -dat;//如果是负数,取绝对值
*str++ = '-';
len++;
}
do
{
buf[i++] = dat%10 + '0';//dat%10 + 0x30; buf[0] = '8' buf[1] = '7'buf[2] = '6'
dat /= 10;
}while(dat > 0);
len += i;
while(i-- > 0)
{
*str++ = buf[i];
}
*str = '\0';
return len;
}
4.主函数
#include <stc15.h>
#include "LCD1602.h"
#include "delay.h"
#include "adc.h"
float ad_result=1234;
unsigned char str[20];
void main()
{
LCDInit();
DelayXms(5);
InitADC();
while(1)
{
LCDShowStr(0,0,"Weight:");
ad_result=GetADC(2);
ad_result=(ad_result-111)*32;
FloatToStr(ad_result, str);
LCDShowStr(7,0,str);
LCDShowStr(15,0,"g");
}
}
调试结果

实物结果
通电。
未放置重物。

放置100g重物。

结束!!!
浙公网安备 33010602011771号