/*
JQ8400,JQ8900系列例程。
STC89C52RC,晶振11.0592Mhz,串口波特率9600
连接方式
P1.0-------->8900的VPP或8400的one line
语音模块供电5.0V
压力传感器接线
HX711_DOUT=P2^3;
HX711_SCK=P2^4;
蓝牙:
tx:P3.0
RX:P3.1
*/
#include "main.h"
#include "HX711.h"
#include "LCD1602.h"
#include "reg52.h"
#include <stdio.h>
sbit SDA=P1^0;
//sbit Trig = P2^1;
//sbit Echo = P2^0;
unsigned long HX711_Buffer = 0;
unsigned long Weight_Maopi = 0;
long Weight_Shiwu = 0;
unsigned char flag = 0;
bit Flag_ERROR = 0;
sbit speak= P1^7;
unsigned char zh[3];
//语音播报
void SendData ( unsigned char addr );
void ONE_LINE_VOL(unsigned char vol);
void ONE_LINE_PLAY();
void ONE_LINE_PAUSE();
void ONE_LINE_STOP();
void ONE_LINE_PLAY_SONG(unsigned char song);
void ONE_LINE_NEXT();
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
#define GapValue 180
void delay_us(unsigned int x)
{
while(x--);
}
/*串口初始化配置*/
void UartConfiguration()
{
TMOD=0x20; //设置计数器1的工作方式2
TH1=0xfd; //设置计数器1的初值,决定波特率
TL1=0xfd; //设置计数器1的初值,决定波特率
PCON=0x00; // 波特率倍增0x00不加倍 0x80加倍
SCON=0x50; //设置工作方式1 开启接受允许
EA=1; //开启总中断
ES=1; //开启串口接受中断
TR1=1; //计数器1开始运行
}/*发送数据*/
void sendDate(unsigned char date)
{
SBUF=date; //接收到的数据放入发送缓存器发送
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}
void SendString(unsigned char *p)
{
while(*p)
{
sendDate(*p);
p++;
}
}
char putchar(char c)
{
//输出重定向到串口
sendDate(c);
return c; //返回给函数的调用者printf
}
//****************************************************
//主函数
//****************************************************
unsigned int i=0;
void main(void)
{
P1=0xf0;
/*这里为什么要给P1.0 1.1 1.2 1.3置0,因为这个开发板的液晶驱动和数码管驱动共用了,
NPN三极管是高电平导通的,因为单片机的IO口默认开机都是1,为了给数码管断开,
所以需要给数码管驱动手动置0. */
UartConfiguration();
Init_LCD1602();
LCD1602_write_com(0x80);
LCD1602_write_word("Welcome to use!");
//上电延时2秒,等待外设初始化
SendString("准备就绪");
ONE_LINE_VOL(30); //语音播报音量
Delay_ms(20); //一条指令发送完毕之后,需要间隔20ms在发送下一条指令
Get_Maopi(); //称毛皮重量
ONE_LINE_PLAY_SONG(3);// 播报开始白
Delay_ms(500);
while(1)
{
EA = 0;
Get_Weight(); //称重
EA = 1;
Delay_ms(100);
Scan_Key();
//显示当前重量
if( Flag_ERROR == 1)
{
LCD1602_write_com(0x80+0x40);
LCD1602_write_word("ERROR ");
speak=0;
}
else
{
speak=1;
LCD1602_write_com(0x80+0x40);
LCD1602_write_data(Weight_Shiwu/1000 + 0X30);
LCD1602_write_data(Weight_Shiwu%1000/100 + 0X30);
LCD1602_write_data(Weight_Shiwu%100/10 + 0X30);
LCD1602_write_data(Weight_Shiwu%10 + 0X30);
LCD1602_write_word(" g");
}
Delay_ms(1000);
if(Weight_Shiwu>100 & Weight_Shiwu>0 & i==0)
{
ONE_LINE_PLAY_SONG(1); //播报“合格”
Delay_ms(500);
i++;
}
else if(Weight_Shiwu<100 & Weight_Shiwu>0 & i==0)
{
ONE_LINE_PLAY_SONG(2); //播报“不合格”
Delay_ms(500);
i++;
}
//蓝牙上传数据
// ONE_LINE_PLAY_SONG(5); //播报“上传数据”
SendString("重量为:");
printf("%ld",Weight_Shiwu);
printf(" g\n");
if(Weight_Shiwu==0)
{
i=0;
}
// ONE_LINE_NEXT();
}
}
//扫描按键
void Scan_Key()
{
if(KEY1 == 0)
{
Delay_ms(5);
if(KEY1 == 0)
{
while(KEY1 == 0);
Get_Maopi(); //去皮
}
}
}
//****************************************************
//称重
//****************************************************
void Get_Weight()
{
Weight_Shiwu = HX711_Read();
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取净重
if(Weight_Shiwu > 0)
{
Weight_Shiwu = (unsigned int)((float)Weight_Shiwu/GapValue); //计算实物的实际重量
if(Weight_Shiwu > 5000) //超重报警
{
Flag_ERROR = 1;
}
else
{
Flag_ERROR = 0;
}
}
else
{
Weight_Shiwu = 0;
// Flag_ERROR = 1; //负重报警
}
}
//****************************************************
//获取毛皮重量
//****************************************************
void Get_Maopi()
{
Weight_Maopi = HX711_Read();
}
//单线串口:播放
void ONE_LINE_PLAY()
{
SendData(0x011);
}
//单线串口:暂停
void ONE_LINE_PAUSE()
{
SendData(0x012);
}
//单线串口:停止
void ONE_LINE_STOP()
{
SendData(0x013);
}
//单线串口:下一首
void ONE_LINE_NEXT()
{
SendData(0x015);
}
//设置音量:vol(0-30)
void ONE_LINE_VOL(unsigned char vol)
{
if(vol>30)vol=30;
SendData(vol/10);
SendData(vol%10);
SendData(0x0C);
}
//指定曲目播放 song: (1-255)
void ONE_LINE_PLAY_SONG(unsigned char song)
{
unsigned char i;
unsigned char tmp[3];
tmp[0]=song/100;song%=100;
tmp[1]=song/10;
tmp[2]=song%10;
SendData(0x0a);
for(i=0;i<3;i++)
{
if(tmp[i]!=0)
{
SendData(tmp[i]);
}
}
SendData(0x0b);
}
void SendData( unsigned char addr )//发送函数。
{
unsigned char i;
EA = 0;/*发送时关掉中断,防止中断影响时序 */
SDA = 1;/*开始拉高 */
delay_us ( 1000 );
SDA = 0;/*开始引导码*/
delay_us ( 2000 );/*此处延时最少要大于 2ms,此参数延时为 310ms */
for ( i = 0; i < 8; i++ ) /*总共 8 位数据 */
{
SDA = 1;
if ( addr & 0x01 ) /*3:1 表示数据位 1,每个位用两个脉冲表示 */
{
delay_us ( 1200 );
SDA = 0;
delay_us ( 400 );
}
else /*1:3 表示数据位 0 ,每个位用两个脉冲表示 */
{
delay_us ( 400 );
SDA = 0;
delay_us ( 1200 );
}
addr >>= 1;
}
SDA = 1;
EA = 1;//恢复中断
}
//****************************************************
//MS延时函数(12M晶振下测试)
//****************************************************
void Delay_ms(unsigned int n)
{
unsigned int i,j;
for(i=0;i<n;i++)
for(j=0;j<123;j++);
}
/*中断函数*/
void Uart() interrupt 4
{
unsigned char date;
date=SBUF; //取出接受到的数据
RI=0; //清除接受中断标志位
//收到的数据是date
}