51单片机 esp-01发送DS18B20数据、AS5600数据、HX711数据的C语言程序
时间: 2023-07-14 13:13:39 浏览: 131
以下是一个可以发送DS18B20、AS5600和HX711数据的51单片机程序,使用esp-01作为WiFi模块进行数据传输。
```
#include <reg51.h>
#include <math.h>
#include <intrins.h>
#include <stdio.h>
#include <string.h>
#define FOSC 11059200L //定义晶振频率
#define BAUD 9600 //定义波特率
#define ERROR 0 //定义常量0
#define OK 1 //定义常量1
#define DS18B20_PIN P2_3 //定义DS18B20引脚
#define AS5600_PIN P2_4 //定义AS5600引脚
#define HX711_PIN P2_5 //定义HX711引脚
unsigned char idata Send_Buffer[60]; //定义发送缓存区
unsigned char idata Receive_Buffer[60]; //定义接收缓存区
unsigned int count; //定义计数器
bit flag; //用于指示是否有数据需要发送
void Init_UART(void) //初始化UART
{
TMOD |= 0x20; //设定定时器1为8位自动重载模式
TH1 = TL1 = -(FOSC / 12 / 32 / BAUD); //设定波特率
TR1 = 1; //启动定时器1
SM0 = 0; //设定串口工作模式
SM1 = 1;
REN = 1; //允许串口接收数据
EA = 1; //开启总中断
ES = 1; //开启串口中断
}
void Init_DS18B20(void) //初始化DS18B20
{
DS18B20_PIN = 1; //DS18B20初始化
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
bit Start_DS18B20(void) //启动DS18B20
{
bit ack;
DS18B20_PIN = 1; //总线复位
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DS18B20_PIN = 0; //开始信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DS18B20_PIN = 1; //释放总线,等待DS18B20响应
_nop_();
_nop_();
_nop_();
_nop_();
ack = DS18B20_PIN; //读取DS18B20响应信号
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
return ack;
}
void Write_DS18B20(unsigned char dat) //写入数据
{
unsigned char i;
for (i = 0; i < 8; i++) {
DS18B20_PIN = 0; //写入数据开始
_nop_();
_nop_();
DS18B20_PIN = dat & 0x01; //写入数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DS18B20_PIN = 1; //释放总线
dat >>= 1; //准备写入下一位数据
}
}
unsigned char Read_DS18B20(void) //读取数据
{
unsigned char i, dat = 0;
for (i = 0; i < 8; i++) {
dat >>= 1; //准备读取下一位数据
DS18B20_PIN = 0; //读取数据开始
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
DS18B20_PIN = 1; //释放总线,等待DS18B20响应
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
if (DS18B20_PIN) //读取数据
dat |= 0x80;
}
return dat;
}
void Read_Temperature_DS18B20(void) //读取DS18B20温度数据
{
unsigned char temp[2];
unsigned int t;
if (Start_DS18B20()) { //启动DS18B20
Write_DS18B20(0xCC); //跳过ROM
Write_DS18B20(0x44); //启动温度转换
while (!DS18B20_PIN); //等待转换结束
Start_DS18B20(); //启动DS18B20
Write_DS18B20(0xCC); //跳过ROM
Write_DS18B20(0xBE); //读取温度数据
temp[0] = Read_DS18B20(); //读取LSB
temp[1] = Read_DS18B20(); //读取MSB
t = ((unsigned int)temp[1] << 8) | temp[0]; //计算温度值
t = t * 0.0625 * 10 + 0.5;
sprintf(Send_Buffer, "Temperature: %d.%dC\r\n", t / 10, t % 10); //将温度值转化为字符串
flag = 1; //设置发送数据标志位
}
}
void Init_AS5600(void) //初始化AS5600
{
AS5600_PIN = 1; //AS5600初始化
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
unsigned char Read_AS5600(void) //读取AS5600角度数据
{
unsigned char i, dat = 0;
for (i = 0; i < 8; i++) {
dat <<= 1; //准备读取下一位数据
AS5600_PIN = 0; //读取数据开始
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
dat |= AS5600_PIN; //读取数据
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
AS5600_PIN = 1; //释放总线,等待AS5600响应
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
return dat;
}
void Read_Angle_AS5600(void) //读取AS5600角度数据
{
unsigned char angle;
Init_AS5600(); //初始化AS5600
AS5600_PIN = 0; //发送起始地址
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
AS5600_PIN = 1; //释放总线,等待AS5600响应
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
angle = Read_AS5600(); //读取角度数据
sprintf(Send_Buffer, "Angle: %d\r\n", angle); //将角度值转化为字符串
flag = 1; //设置发送数据标志位
}
void Init_HX711(void) //初始化HX711
{
HX711_PIN = 1; //HX711初始化
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
unsigned long Read_HX711(void) //读取HX711重量数据
{
unsigned char i;
unsigned long dat = 0;
Init_HX711(); //初始化HX711
for (i = 0; i < 24; i++) { //读取24位数据
HX711_PIN = 0; //读取数据开始
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
dat <<= 1; //准备读取下一位数据
if (HX711_PIN) dat++;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
HX711_PIN = 1; //释放总线,等待HX711响应
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
HX711_PIN = 0; //读取校验位
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
dat ^= 0x800000;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
HX711_PIN = 1; //释放总线,等待HX711响应
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
return dat;
}
void Read_Weight_HX711(void) //读取HX711重量数据
{
unsigned long weight;
weight = Read_HX711(); //读取重量数据
sprintf(Send_Buffer, "Weight: %ldg\r\n", weight); //将重量值转化为字符串
flag = 1; //设置发送数据标志位
}
void Send_Data(void) //发送数据
{
unsigned char i;
for (i = 0; i < strlen(Send_Buffer); i++) {
SBUF = Send_Buffer[i]; //发送数据
while (!TI); //等待数据发送完成
TI = 0; //清除发送完成标志位
}
memset(Send_Buffer, 0, sizeof(Send_Buffer)); //清空发送缓存区
flag = 0; //清除发送数据标志位
}
void main(void)
{
Init_UART(); //初始化UART
while (1) {
Read_Temperature_DS18B20(); //读取DS18B20温度数据
if (flag) Send_Data(); //发送数据
Read_Angle_AS5600(); //读取AS5600角度数据
if (flag) Send_Data(); //发送数据
Read_Weight_HX711(); //读取HX711重量数据
if (flag) Send_Data(); //发送数据
}
}
void UART_ISR(void) interrupt 4 //UART中断服务程序
{
if (RI) { //接收数据
RI = 0; //清除接收完成标志位
Receive_Buffer[count++] = SBUF; //将接收数据存入接收缓存区
if (count >= sizeof(Receive_Buffer)) count = 0; //如果接收缓存区已满,重置计数器
}
if (TI) TI = 0; //清除发送完成标志位
}
```
需要注意的是,该程序中的DS18B20、AS5600和HX711的引脚定义是P2_3、P2_4和P2_5,可以根据实际硬件连接情况进行修改。此外,程序中使用了一个标志位flag来指示是否有数据需要发送,可以避免数据重复发送的问题。
阅读全文