Commit 310778af authored by 957dd's avatar 957dd

将软件iic改为了硬件i2c,让读取电压更稳定,加入了修改iic的配置文件

parent a88c5ccb
......@@ -30,22 +30,18 @@ int main(){
return -6;
}
if(softiic_init()!=0){
my_zlog_error("软件iic初始化失败");
return -7;
}
if(audio_config_init()!=0){
my_zlog_warn("音频配置初始化失败");
}
if(ina225_init()!=0){
my_zlog_warn("此版本电压没有使用INA226");
if(hardware_iic_init()!=0){
my_zlog_error("硬件iic初始化失败");
return -7;
}
if(device_shot_cooling_init()!=0){
my_zlog_warn("该设备没有冷却");
}
if(audio_config_init()!=0){
my_zlog_warn("音频配置初始化失败");
}
if (audio_init()==0){
my_zlog_info("音频命令执行初始化成功");
......@@ -62,6 +58,7 @@ int main(){
device_end_close(g_device_type);
self_control_thread_close();//销毁自控的线程
my_log_close();//关闭日志
hardware_iic_close();
my_zlog_info("程序关闭成功");
return 0;
......
......@@ -22,13 +22,11 @@ int audio_config_init();
/*音频初始化函数*/
int audio_init();
int softiic_init();
int hardware_iic_init();
/*mqtt的topic初始化*/
int device_mqtt_topic_init();
int ina225_init();
/*设备射击冷却初始化*/
int device_shot_cooling_init();
......@@ -54,4 +52,7 @@ void self_control_thread_close();//销毁自控的线程
/*关闭log日志记录*/
void my_log_close();
/*关闭硬件iic*/
int hardware_iic_close();
#endif
......@@ -83,8 +83,9 @@ void *thread_mqtt_beat(void *arg) {
delay_ms(100);
g_heartbeat_count++;
set_tank_angle_count();//角度发布计时,1开始计时,0清0
if(g_mqtt_grc == 0){
mqtt_beat_wirte();//心跳,3s一个
mqtt_beat_wirte();//心跳等发布函数,更具不同时间发布
if(get_device_self_control_configuration_initialization()==0){
my_zlog_warn("自控配置初始化成功");
......@@ -158,7 +159,7 @@ void *thread_time_calculation(void *arg) {
g_device_delay_back_count ++;//设备计时,坦克打击倒退逻辑
pthread_mutex_lock(&g_verify_mutex);
g_verify_count++;//验证计时,每15s一次
g_verify_count++;//jwt验证计时,每15s一次
pthread_mutex_unlock(&g_verify_mutex);
if(g_verify_count >= 20000) {//防止溢出
......
File deleted
......@@ -881,29 +881,29 @@ drivers/gpio/gpio_init.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/gpio_init.c.s
.PHONY : drivers/gpio/gpio_init.c.s
drivers/gpio/softiic.o: drivers/gpio/softiic.c.o
.PHONY : drivers/gpio/softiic.o
drivers/gpio/hardware_iic.o: drivers/gpio/hardware_iic.c.o
.PHONY : drivers/gpio/hardware_iic.o
# target to build an object file
drivers/gpio/softiic.c.o:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/softiic.c.o
.PHONY : drivers/gpio/softiic.c.o
drivers/gpio/hardware_iic.c.o:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/hardware_iic.c.o
.PHONY : drivers/gpio/hardware_iic.c.o
drivers/gpio/softiic.i: drivers/gpio/softiic.c.i
.PHONY : drivers/gpio/softiic.i
drivers/gpio/hardware_iic.i: drivers/gpio/hardware_iic.c.i
.PHONY : drivers/gpio/hardware_iic.i
# target to preprocess a source file
drivers/gpio/softiic.c.i:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/softiic.c.i
.PHONY : drivers/gpio/softiic.c.i
drivers/gpio/hardware_iic.c.i:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/hardware_iic.c.i
.PHONY : drivers/gpio/hardware_iic.c.i
drivers/gpio/softiic.s: drivers/gpio/softiic.c.s
.PHONY : drivers/gpio/softiic.s
drivers/gpio/hardware_iic.s: drivers/gpio/hardware_iic.c.s
.PHONY : drivers/gpio/hardware_iic.s
# target to generate assembly for a file
drivers/gpio/softiic.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/softiic.c.s
.PHONY : drivers/gpio/softiic.c.s
drivers/gpio/hardware_iic.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/gpio/hardware_iic.c.s
.PHONY : drivers/gpio/hardware_iic.c.s
drivers/network/ip_reader.o: drivers/network/ip_reader.c.o
.PHONY : drivers/network/ip_reader.o
......@@ -953,30 +953,6 @@ drivers/selfcontrol/self_devicecontrol.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/selfcontrol/self_devicecontrol.c.s
.PHONY : drivers/selfcontrol/self_devicecontrol.c.s
drivers/sensors/INA226.o: drivers/sensors/INA226.c.o
.PHONY : drivers/sensors/INA226.o
# target to build an object file
drivers/sensors/INA226.c.o:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/sensors/INA226.c.o
.PHONY : drivers/sensors/INA226.c.o
drivers/sensors/INA226.i: drivers/sensors/INA226.c.i
.PHONY : drivers/sensors/INA226.i
# target to preprocess a source file
drivers/sensors/INA226.c.i:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/sensors/INA226.c.i
.PHONY : drivers/sensors/INA226.c.i
drivers/sensors/INA226.s: drivers/sensors/INA226.c.s
.PHONY : drivers/sensors/INA226.s
# target to generate assembly for a file
drivers/sensors/INA226.c.s:
$(MAKE) $(MAKESILENT) -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/drivers/sensors/INA226.c.s
.PHONY : drivers/sensors/INA226.c.s
drivers/sensors/ads1115.o: drivers/sensors/ads1115.c.o
.PHONY : drivers/sensors/ads1115.o
......@@ -2006,18 +1982,15 @@ help:
@echo "... drivers/gpio/gpio_init.o"
@echo "... drivers/gpio/gpio_init.i"
@echo "... drivers/gpio/gpio_init.s"
@echo "... drivers/gpio/softiic.o"
@echo "... drivers/gpio/softiic.i"
@echo "... drivers/gpio/softiic.s"
@echo "... drivers/gpio/hardware_iic.o"
@echo "... drivers/gpio/hardware_iic.i"
@echo "... drivers/gpio/hardware_iic.s"
@echo "... drivers/network/ip_reader.o"
@echo "... drivers/network/ip_reader.i"
@echo "... drivers/network/ip_reader.s"
@echo "... drivers/selfcontrol/self_devicecontrol.o"
@echo "... drivers/selfcontrol/self_devicecontrol.i"
@echo "... drivers/selfcontrol/self_devicecontrol.s"
@echo "... drivers/sensors/INA226.o"
@echo "... drivers/sensors/INA226.i"
@echo "... drivers/sensors/INA226.s"
@echo "... drivers/sensors/ads1115.o"
@echo "... drivers/sensors/ads1115.i"
@echo "... drivers/sensors/ads1115.s"
......
No preview for this file type
CMAKE_PROGRESS_1 =
CMAKE_PROGRESS_2 = 81
CMAKE_PROGRESS_3 =
CMAKE_PROGRESS_2 =
CMAKE_PROGRESS_3 = 81
CMAKE_PROGRESS_4 =
CMAKE_PROGRESS_5 = 82
CMAKE_PROGRESS_6 =
......
......@@ -34,8 +34,8 @@ CMAKE_PROGRESS_33 =
CMAKE_PROGRESS_34 =
CMAKE_PROGRESS_35 = 12
CMAKE_PROGRESS_36 =
CMAKE_PROGRESS_37 =
CMAKE_PROGRESS_38 = 13
CMAKE_PROGRESS_37 = 13
CMAKE_PROGRESS_38 =
CMAKE_PROGRESS_39 =
CMAKE_PROGRESS_40 = 14
CMAKE_PROGRESS_41 =
......
......@@ -7,8 +7,8 @@ CMAKE_PROGRESS_6 =
CMAKE_PROGRESS_7 =
CMAKE_PROGRESS_8 = 18
CMAKE_PROGRESS_9 =
CMAKE_PROGRESS_10 =
CMAKE_PROGRESS_11 = 19
CMAKE_PROGRESS_10 = 19
CMAKE_PROGRESS_11 =
CMAKE_PROGRESS_12 =
CMAKE_PROGRESS_13 = 20
CMAKE_PROGRESS_14 =
......@@ -24,11 +24,11 @@ CMAKE_PROGRESS_23 =
CMAKE_PROGRESS_24 =
CMAKE_PROGRESS_25 = 24
CMAKE_PROGRESS_26 =
CMAKE_PROGRESS_27 =
CMAKE_PROGRESS_28 = 25
CMAKE_PROGRESS_27 = 25
CMAKE_PROGRESS_28 =
CMAKE_PROGRESS_29 =
CMAKE_PROGRESS_30 =
CMAKE_PROGRESS_31 = 26
CMAKE_PROGRESS_30 = 26
CMAKE_PROGRESS_31 =
CMAKE_PROGRESS_32 =
CMAKE_PROGRESS_33 = 27
CMAKE_PROGRESS_34 =
......
......@@ -3,8 +3,8 @@ CMAKE_PROGRESS_2 =
CMAKE_PROGRESS_3 =
CMAKE_PROGRESS_4 = 86
CMAKE_PROGRESS_5 =
CMAKE_PROGRESS_6 = 87
CMAKE_PROGRESS_7 =
CMAKE_PROGRESS_6 =
CMAKE_PROGRESS_7 = 87
CMAKE_PROGRESS_8 =
CMAKE_PROGRESS_9 = 88
CMAKE_PROGRESS_10 =
......
CMAKE_PROGRESS_1 =
CMAKE_PROGRESS_1 = 54
CMAKE_PROGRESS_2 =
CMAKE_PROGRESS_3 = 55
CMAKE_PROGRESS_4 =
CMAKE_PROGRESS_3 =
CMAKE_PROGRESS_4 = 55
CMAKE_PROGRESS_5 =
CMAKE_PROGRESS_6 = 56
CMAKE_PROGRESS_7 =
CMAKE_PROGRESS_6 =
CMAKE_PROGRESS_7 = 56
CMAKE_PROGRESS_8 =
CMAKE_PROGRESS_9 = 57
CMAKE_PROGRESS_10 =
......@@ -14,14 +14,14 @@ CMAKE_PROGRESS_13 =
CMAKE_PROGRESS_14 =
CMAKE_PROGRESS_15 = 59
CMAKE_PROGRESS_16 =
CMAKE_PROGRESS_17 = 60
CMAKE_PROGRESS_18 =
CMAKE_PROGRESS_17 =
CMAKE_PROGRESS_18 = 60
CMAKE_PROGRESS_19 =
CMAKE_PROGRESS_20 = 61
CMAKE_PROGRESS_21 =
CMAKE_PROGRESS_20 =
CMAKE_PROGRESS_21 = 61
CMAKE_PROGRESS_22 =
CMAKE_PROGRESS_23 = 62
CMAKE_PROGRESS_24 =
CMAKE_PROGRESS_23 =
CMAKE_PROGRESS_24 = 62
CMAKE_PROGRESS_25 =
CMAKE_PROGRESS_26 = 63
CMAKE_PROGRESS_27 =
......@@ -34,11 +34,11 @@ CMAKE_PROGRESS_33 =
CMAKE_PROGRESS_34 =
CMAKE_PROGRESS_35 = 66
CMAKE_PROGRESS_36 =
CMAKE_PROGRESS_37 = 67
CMAKE_PROGRESS_38 =
CMAKE_PROGRESS_37 =
CMAKE_PROGRESS_38 = 67
CMAKE_PROGRESS_39 =
CMAKE_PROGRESS_40 = 68
CMAKE_PROGRESS_41 =
CMAKE_PROGRESS_40 =
CMAKE_PROGRESS_41 = 68
CMAKE_PROGRESS_42 =
CMAKE_PROGRESS_43 = 69
CMAKE_PROGRESS_44 =
......@@ -54,8 +54,8 @@ CMAKE_PROGRESS_53 =
CMAKE_PROGRESS_54 =
CMAKE_PROGRESS_55 = 73
CMAKE_PROGRESS_56 =
CMAKE_PROGRESS_57 = 74
CMAKE_PROGRESS_58 =
CMAKE_PROGRESS_57 =
CMAKE_PROGRESS_58 = 74
CMAKE_PROGRESS_59 =
CMAKE_PROGRESS_60 = 75
CMAKE_PROGRESS_61 =
......@@ -71,6 +71,6 @@ CMAKE_PROGRESS_70 =
CMAKE_PROGRESS_71 =
CMAKE_PROGRESS_72 = 79
CMAKE_PROGRESS_73 =
CMAKE_PROGRESS_74 = 80
CMAKE_PROGRESS_75 =
CMAKE_PROGRESS_74 =
CMAKE_PROGRESS_75 = 80
......@@ -3,7 +3,7 @@
#include "device_init.h"
#include "gpio_init.h"
#include "gpio_control.h"
#include "softiic.h"
#include "hardware_iic.h"
#endif
\ No newline at end of file
......@@ -496,10 +496,10 @@ void tank0204_pwm_value(int pin,int value){
if(pin == 27){
device_shoting_check(27,30);
}else if(pin == 5) {
softPwmWrite(7, 30);
softPwmWrite(7, 25);
my_zlog_info("pwm:7,1");
}else if(pin == 7) {
softPwmWrite(5, 30);
softPwmWrite(5, 25);
my_zlog_info("pwm:5,1");
}else {
softPwmWrite(pin, 60);
......
#include "common.h"
#include "hardware_iic.h"
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#define I2C_DEVICE "/dev/i2c-2" // 示例:使用 I2C 总线 2
static int fd = 0;
static uint8_t current_iic_addr = 0; // 记录当前设置的 I2C 地址
int hardware_iic_config_init();
int hardware_iic_init() {
if(hardware_iic_config_init()!=0){
return 1;
}
// 打开 I2C 设备
fd = open(I2C_DEVICE, O_RDWR);
if (fd < 0) {
my_zlog_error("错误:无法打开 I2C 设备 %s\n", I2C_DEVICE);
return 1;
}
my_zlog_info("I2C 设备 %s 打开成功。", I2C_DEVICE);
return 0;
}
// 设置 I2C 从设备地址,如果当前地址不同则设置
int set_hardware_iic(uint8_t iic_addr) {
if (fd <= 0) {
my_zlog_error("I2C 设备未初始化或已关闭。");
return 1;
}
if (current_iic_addr != iic_addr) {
if (ioctl(fd, I2C_SLAVE, iic_addr) < 0) {
my_zlog_warn("错误:无法设置 I2C 地址 0x%02X", iic_addr);
// close(fd); // 不在这里关闭,可能需要重试
return 1;
}
current_iic_addr = iic_addr;
my_zlog_info("I2C 地址设置为 0x%02X。", iic_addr);
}
return 0;
}
// 硬件 I2C 写入函数
// device_addr: 从设备地址
// reg_addr: 寄存器地址
// data: 要写入的数据
// len: 数据长度 (不包括寄存器地址)
int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *data, int len) {
if (set_hardware_iic(device_addr) != 0) {
return 1;
}
// 构建发送缓冲区:第一个字节是寄存器地址,后面是数据
uint8_t write_buf[len + 1];
write_buf[0] = reg_addr;
for (int i = 0; i < len; i++) {
write_buf[i + 1] = data[i];
}
if (write(fd, write_buf, len + 1) != (len + 1)) {
my_zlog_warn("错误:向设备 0x%02X 寄存器 0x%02X 写入数据失败。", device_addr, reg_addr);
return 1;
}
// my_zlog_info("成功向设备 0x%02X 寄存器 0x%02X 写入 %d 字节数据。", device_addr, reg_addr, len);
return 0;
}
// 硬件 I2C 读取函数
// device_addr: 从设备地址
// reg_addr: 寄存器地址
// data: 存储读取数据的缓冲区
// len: 要读取的数据长度
int hardware_iic_read(uint8_t device_addr, uint8_t reg_addr, uint8_t *data, int len) {
if (set_hardware_iic(device_addr) != 0) {
return 1;
}
// 先写入要读取的寄存器地址
if (write(fd, &reg_addr, 1) != 1) {
my_zlog_warn("错误:向设备 0x%02X 设置读取寄存器 0x%02X 失败。", device_addr, reg_addr);
return 1;
}
// 然后从该寄存器读取数据
if (read(fd, data, len) != len) {
my_zlog_warn("错误:从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据失败。", device_addr, reg_addr, len);
return 1;
}
// my_zlog_info("成功从设备 0x%02X 寄存器 0x%02X 读取 %d 字节数据。", device_addr, reg_addr, len);
return 0;
}
int hardware_iic_close() {
if (fd > 0) {
close(fd);
fd = 0;
current_iic_addr = 0;
my_zlog_info("关闭 I2C 设备。");
}
return 0;
}
#define FILE_PATH "/boot/orangepiEnv.txt"
#define TMP_FILE_PATH "/tmp/orangepiEnv.tmp"
#define TARGET_OVERLAY "i2c2-m1"
// 检查字符串是否以指定内容结尾
bool iic_ends_with(const char *str, const char *suffix) {
if (!str || !suffix) return false;
size_t len_str = strlen(str);
size_t len_suffix = strlen(suffix);
if (len_suffix > len_str) return false;
return strncmp(str + len_str - len_suffix, suffix, len_suffix) == 0;
}
// 检查是否包含目标overlay(精确匹配)
bool contains_target_overlay(const char *overlays_value) {
if (!overlays_value || strlen(overlays_value) == 0) {
return false;
}
// 在字符串开头、逗号之间或结尾精确匹配目标overlay
char search_pattern1[50], search_pattern2[50], search_pattern3[50];
snprintf(search_pattern1, sizeof(search_pattern1), "%s,", TARGET_OVERLAY); // 目标在开头或中间
snprintf(search_pattern2, sizeof(search_pattern2), ",%s,", TARGET_OVERLAY); // 目标在中间
snprintf(search_pattern3, sizeof(search_pattern3), ",%s", TARGET_OVERLAY); // 目标在结尾
// 检查各种情况
if (strcmp(overlays_value, TARGET_OVERLAY) == 0 || // 完全相等
strncmp(overlays_value, search_pattern1, strlen(search_pattern1)) == 0 || // 在开头
strstr(overlays_value, search_pattern2) != NULL || // 在中间
iic_ends_with(overlays_value, TARGET_OVERLAY)) { // 在结尾
// 确保结尾匹配是精确的(前面是逗号或是字符串开头)
if (iic_ends_with(overlays_value, TARGET_OVERLAY)) {
size_t target_len = strlen(TARGET_OVERLAY);
size_t value_len = strlen(overlays_value);
if (value_len == target_len || // 完全相等的情况已经在上面检查过
(value_len > target_len && overlays_value[value_len - target_len - 1] == ',')) {
return true;
}
} else {
return true;
}
}
return false;
}
int hardware_iic_config() {
FILE *file, *tmp_file;
char line[256];
bool found_overlays = false;
bool need_modify = false;
char overlays_value[256] = "";
my_zlog_info("正在检查文件 %s...", FILE_PATH);
// 第一次扫描:检查是否需要修改
file = fopen(FILE_PATH, "r");
if (file == NULL) {
my_zlog_warn("无法打开文件");
return 1;
}
while (fgets(line, sizeof(line), file)) {
if (strncmp(line, "overlays=", 9) == 0) {
found_overlays = true;
// 提取overlays的值(去掉换行符)
char *value = line + 9;
value[strcspn(value, "\n\r")] = 0;
strncpy(overlays_value, value, sizeof(overlays_value) - 1);
if (!contains_target_overlay(value)) {
need_modify = true;
my_zlog_info("当前overlays值: %s", value);
my_zlog_info("需要添加: %s", TARGET_OVERLAY);
} else {
my_zlog_info("目标overlay已存在,无需修改");
}
break;
}
}
fclose(file);
// 如果没有找到overlays行,也需要修改
if (!found_overlays) {
need_modify = true;
my_zlog_info("未找到overlays行,需要添加");
}
// 如果不需要修改,直接退出
if (!need_modify) {
my_zlog_info("文件无需修改,程序退出。");
return 10;
}
my_zlog_info("开始修改文件...");
// 重新打开文件进行修改
file = fopen(FILE_PATH, "r");
if (file == NULL) {
my_zlog_error("无法打开文件");
return 1;
}
tmp_file = fopen(TMP_FILE_PATH, "w");
if (tmp_file == NULL) {
my_zlog_error("无法创建临时文件");
fclose(file);
return 1;
}
// 处理文件内容
bool overlays_processed = false;
while (fgets(line, sizeof(line), file)) {
if (strncmp(line, "overlays=", 9) == 0 && !overlays_processed) {
overlays_processed = true;
char *value = line + 9;
value[strcspn(value, "\n\r")] = 0;
if (strlen(value) == 0) {
// 空overlays
fprintf(tmp_file, "overlays=%s\n", TARGET_OVERLAY);
} else {
// 非空,添加到末尾
if (value[strlen(value) - 1] == ',') {
fprintf(tmp_file, "overlays=%s%s\n", value, TARGET_OVERLAY);
} else {
fprintf(tmp_file, "overlays=%s,%s\n", value, TARGET_OVERLAY);
}
}
} else {
fputs(line, tmp_file);
}
}
// 如果文件中没有overlays行,在文件末尾添加
if (!overlays_processed) {
fprintf(tmp_file, "overlays=%s\n", TARGET_OVERLAY);
}
fclose(file);
fclose(tmp_file);
// 备份原文件
char backup_cmd[256];
snprintf(backup_cmd, sizeof(backup_cmd), "cp %s %s.bak", FILE_PATH, FILE_PATH);
my_zlog_info("创建备份文件...");
if (system(backup_cmd) != 0) {
my_zlog_info("备份文件创建失败");
remove(TMP_FILE_PATH);
return 1;
}
// 替换原文件
char replace_cmd[256];
snprintf(replace_cmd, sizeof(replace_cmd), "mv %s %s", TMP_FILE_PATH, FILE_PATH);
my_zlog_info("更新文件...");
if (system(replace_cmd) != 0) {
my_zlog_info("文件更新失败");
return 1;
}
my_zlog_info("文件更新完成!原文件已备份为%s.bak", FILE_PATH);
return 0;
}
int hardware_iic_config_init(){
int res=hardware_iic_config();
if(res==10){
return 0;
}else if(res ==0){
delay_ms(200);
int ret=system("sudo reboot");//重启香橙派
if(ret==0) my_zlog_debug("重启成功");
return 1;
}
}
#ifndef HARDWARE_IIC_H__
#define HARDWARE_IIC_H__
int hardware_iic_init();
int set_hardware_iic(uint8_t iic_addr);
int hardware_iic_write(uint8_t device_addr, uint8_t reg_addr, const uint8_t *data, int len);
int hardware_iic_read(uint8_t device_addr, uint8_t reg_addr, uint8_t *data, int len);
int hardware_iic_close();
#endif
\ No newline at end of file
#include "common.h"
#include "softiic.h"
int sda_pin = 0; // GPIO0
int scl_pin = 1; // GPIO1
// 软件 I2C 延时
void i2c_delay() {
delayMicroseconds(5); // ~5μs 延迟,适配 100kHz I2C
}
// 初始化 I2C 引脚
int softiic_init() {
pinMode(sda_pin, OUTPUT);
pinMode(scl_pin, OUTPUT);
digitalWrite(sda_pin, HIGH);
digitalWrite(scl_pin, HIGH);
return 0;
}
// I2C 起始信号
void i2c_start() {
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, HIGH);
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(sda_pin, LOW);
i2c_delay();
digitalWrite(scl_pin, LOW);
i2c_delay();
}
// I2C 停止信号
void i2c_stop() {
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, LOW);
digitalWrite(scl_pin, LOW);
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(sda_pin, HIGH);
i2c_delay();
}
// I2C 发送一个字节,并检查 ACK(不返回,但内部可判断是否 ACK)
void i2c_write_byte(uint8_t data) {
pinMode(sda_pin, OUTPUT);
for (int i = 7; i >= 0; i--) {
digitalWrite(sda_pin, (data >> i) & 0x01);
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(scl_pin, LOW);
i2c_delay();
}
// 接收 ACK
pinMode(sda_pin, INPUT); // 释放 SDA
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
int ack = digitalRead(sda_pin); // 0 = ACK,1 = NACK(你可以打印或设置状态变量)
digitalWrite(scl_pin, LOW);
pinMode(sda_pin, OUTPUT); // 拉回输出模式
i2c_delay();
}
// I2C 读取一个字节并发送 ACK/NACK
uint8_t i2c_read_byte(bool ack) {
uint8_t data = 0;
pinMode(sda_pin, INPUT);
for (int i = 7; i >= 0; i--) {
digitalWrite(scl_pin, HIGH);
i2c_delay();
data |= (digitalRead(sda_pin) << i);
digitalWrite(scl_pin, LOW);
i2c_delay();
}
pinMode(sda_pin, OUTPUT);
digitalWrite(sda_pin, ack ? LOW : HIGH); // 发送 ACK or NACK
i2c_delay();
digitalWrite(scl_pin, HIGH);
i2c_delay();
digitalWrite(scl_pin, LOW);
i2c_delay();
pinMode(sda_pin, INPUT);
return data;
}
#ifndef SOFTIIC_H__
#define SOFTIIC_H__
extern int sda_pin; // GPIO0
extern int scl_pin; // GPIO1
int softiic_init();
// I2C 起始信号
void i2c_start();
void i2c_delay();
// I2C 停止信号
void i2c_stop();
// I2C 发送一个字节
void i2c_write_byte(uint8_t data);
// I2C 读取一个字节
uint8_t i2c_read_byte(bool ack);
#endif
\ No newline at end of file
#include "common.h"
#include "INA226.h"
#include "softiic.h"
float currentLSB;
// 配置 INA226
bool ina226_configure() {
uint16_t config = 0x4127; // 默认配置:16次平均,1.1ms 转换时间,连续模式
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CONFIG);
i2c_write_byte(config >> 8);
i2c_write_byte(config & 0xFF);
i2c_stop();
return true;
}
// 校准 INA226
bool ina226_calibrate(float rShuntValue, float iMaxExpected) {
currentLSB = iMaxExpected / 32767.0; // 电流 LSB
uint16_t calibrationValue = (uint16_t)(0.00512 / (currentLSB * rShuntValue));
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CALIBRATION);
i2c_write_byte(calibrationValue >> 8);
i2c_write_byte(calibrationValue & 0xFF);
i2c_stop();
return true;
}
// 读取总线电压
float ina226_readbusvoltage(){
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_BUSVOLTAGE);
i2c_start();
i2c_write_byte((INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(true);
uint8_t low = i2c_read_byte(false);
i2c_stop();
int16_t value = (high << 8) | low;
return value * 0.00125f; // 每 LSB = 1.25mV
}
// 读取电流
float ina226_readcurrent() {
i2c_start();
i2c_write_byte(INA226_ADDRESS << 1);
i2c_write_byte(INA226_REG_CURRENT);
i2c_start();
i2c_write_byte((INA226_ADDRESS << 1) | 1);
uint8_t high = i2c_read_byte(true);
uint8_t low = i2c_read_byte(false);
i2c_stop();
int16_t value = (high << 8) | low;
return -value * currentLSB;
}
int ina225_init(){
// 配置 INA226
if(!ina226_configure()) {
my_zlog_warn("INA226初始化失败");
return -1;
}
// 校准 INA226
float rshuntvalue = 0.01; // 分流电阻值(单位:欧姆)
float imaxexpected= 5; // 最大预期电流(单位:安培)
if(!ina226_calibrate(rshuntvalue, imaxexpected)){
my_zlog_warn("INA226校准失败");
return -2;
}
return 0;
}
#ifndef INA226_H
#define INA226_H
#define INA226_ADDRESS (0x40) // INA226 的 I2C 地址
#define INA226_REG_CONFIG (0x00)
#define INA226_REG_SHUNTVOLTAGE (0x01)
#define INA226_REG_BUSVOLTAGE (0x02)
#define INA226_REG_POWER (0x03)
#define INA226_REG_CURRENT (0x04)
#define INA226_REG_CALIBRATION (0x05)
/*初始化ina226,包括配置 INA226和校准 INA226*/
int ina225_init();
// 读取总线电压
float ina226_readbusvoltage();
// 读取电流
float ina226_readcurrent();
#endif // INA226_H
\ No newline at end of file
#include "ads1115.h"
#include "common.h"
#include "softiic.h"
#include "hardware_iic.h"
#define ADS1115_ADDR 0x48
#define ADS1115_ADDR 0x48 // ADS1115 的默认 I2C 地址
// I2C写寄存器
// reg: 寄存器地址
// val: 要写入的16位值
static void ads1115_write_register(uint8_t reg, uint16_t val) {
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 0);
i2c_write_byte(reg);
i2c_write_byte((val >> 8) & 0xFF);
i2c_write_byte(val & 0xFF);
i2c_stop();
uint8_t data[2];
data[0] = (val >> 8) & 0xFF; // MSB
data[1] = val & 0xFF; // LSB
if (hardware_iic_write(ADS1115_ADDR, reg, data, 2) != 0) {
// 这里可以添加更详细的错误处理
my_zlog_error("ADS1115: 写入寄存器 0x%02X 失败。", reg);
}
}
// 读取转换寄存器
static uint16_t ads1115_read_conversion() {
uint16_t result = 0;
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 0);
i2c_write_byte(0x00);
i2c_start();
i2c_write_byte((ADS1115_ADDR << 1) | 1);
uint8_t msb = i2c_read_byte(1);
uint8_t lsb = i2c_read_byte(0);
i2c_stop();
result = (msb << 8) | lsb;
return result;
uint8_t data[2];
if (hardware_iic_read(ADS1115_ADDR, 0x00, data, 2) != 0) {
// 这里可以添加更详细的错误处理
my_zlog_error("ADS1115: 读取转换寄存器失败。\n");
return 0; // 返回0表示读取失败,可能需要更合适的错误值
}
return (data[0] << 8) | data[1];
}
// 读取某个单端通道电压,channel = 0~3
float ads1115_read_channel(int channel) {
if (channel < 0 || channel > 3)
if (channel < 0 || channel > 3) {
my_zlog_warn("ADS1115: 无效的通道号 %d (应为 0-3)。\n", channel);
return -1.0f;
}
uint16_t config = 0x8000; // OS=1,启动转换
config |= ((4 + channel) << 12); // 单端MUX
config |= (0x00 << 9); // PGA ±6.144V
config |= (1 << 8); // 单次模式
config |= (0x04 << 5); // 128SPS
config |= 0x03; // 禁用比较器
uint16_t config = 0x8000; // OS=1,启动单次转换
config |= ((4 + channel) << 12); // 单端MUX (AIN0: 0100, AIN1: 0101, AIN2: 0110, AIN3: 0111)
config |= (0x00 << 9); // PGA ±6.144V (FSR = 6.144V)
config |= (1 << 8); // 单次模式 (MODE = 1)
config |= (0x04 << 5); // 128SPS (DR = 100)
config |= 0x03; // 禁用比较器 (COMP_MODE = 0, COMP_POL = 0, COMP_LAT = 0, COMP_QUE = 11)
// 写入配置寄存器 (0x01)
ads1115_write_register(0x01, config);
delay(10); // 等待转换
// 等待转换完成。根据 128SPS,转换时间约为 1000ms / 128 = 7.8125ms。
// 这里等待 10ms 是安全的。
delay_ms(10);
// 读取转换结果
int16_t val = (int16_t)ads1115_read_conversion();
// 将 16 位有符号值转换为电压
// FSR = 6.144V, 2^15 = 32768
float voltage = val * 6.144f / 32768.0f;
// my_zlog_info("ADS1115: 通道 %d 原始值: %d, 电压: %.3f V", channel, val, voltage);
return voltage;
}
}
\ No newline at end of file
......@@ -3,7 +3,6 @@
#include "ads1115.h"
#include "audioplay.h"
#include "INA226.h"
#include "infrared_gun.h"
#include "tank_angle.h"
#include "temperature.h"
......
......@@ -41,4 +41,25 @@ float low_pass_filter_360(float prev_angle, float new_angle, float alpha) {
// 应用滤波
float filtered = prev_angle + alpha * diff;
return fmod(filtered + 360.0f, 360.0f); // 确保输出在 [0, 360)
}
//上报角度计时,限制到这里
static int tank_angle_count=0;
static pthread_mutex_t tank_angle_mutex = PTHREAD_MUTEX_INITIALIZER;
void set_tank_angle_count(){
pthread_mutex_lock(&tank_angle_mutex);
tank_angle_count++;
pthread_mutex_unlock(&tank_angle_mutex);
}
//角度计时
void set_tank_angle_count_clear(){
pthread_mutex_lock(&tank_angle_mutex);
tank_angle_count=0;
pthread_mutex_unlock(&tank_angle_mutex);
}
int get_tank_angle_count(){
return tank_angle_count;
}
\ No newline at end of file
......@@ -13,6 +13,12 @@ int angle_limit();
float low_pass_filter_360(float prev_angle, float new_angle, float alpha);
void set_tank_angle_count();//计时
void set_tank_angle_count_clear();//计时清零
int get_tank_angle_count();//获取计时
// //角度滤波
// double en_filter_update(double new_angle);
......
......@@ -19,16 +19,15 @@ static unsigned char g_valt[4];//存放mqtt接收的tpye,mode等
//心跳发送格式*5/2
void heartbeat_send() {
float voltage = ina226_readbusvoltage();
float current = ina226_readcurrent();
my_zlog_debug("ina226_v:%.2f", voltage);
if(voltage<=0.5){
voltage=ads1115_read_channel(0)*5/2;
current=ads1115_read_channel(1)*5/2;
current=(current-voltage)*10;
my_zlog_debug("v:%.2f", voltage);
my_zlog_debug("i:%.2f", current);
}
static double voltage;
static double current;
voltage=ads1115_read_channel(0)*5/2;
current=ads1115_read_channel(1)*5/2;
current=(current-voltage)*10;
my_zlog_debug("v:%.2f", voltage);
my_zlog_debug("i:%.2f", current);
char voltage_str[20]; // 足够存储转换后的字符串的缓冲区
sprintf(voltage_str, "%.2f", voltage);
char current_str[20]; // 足够存储转换后的字符串的缓冲区
......@@ -79,7 +78,7 @@ void angle_mqtt_send() {
char TOPIC_send_angle[26];
static double prev_angle=0;
static double rounded_angle;
rounded_angle =low_pass_filter_360(prev_angle,tank_angle(),0.6);
rounded_angle =low_pass_filter_360(prev_angle,tank_angle(),0.8);
sprintf(TOPIC_send_angle,"dev_rtinfo/%s",mqtt_topic_pure_number());
cJSON_AddStringToObject(root, "type","tank_angle");
cJSON_AddNumberToObject(root, "angle",rounded_angle);
......@@ -90,7 +89,7 @@ void angle_mqtt_send() {
prev_angle=tank_angle();
angle_i=0;
}
if(rounded_angle == 0){
if(fabs(rounded_angle) < 1e-8){
cJSON_Delete(root);
return;
}
......@@ -109,8 +108,8 @@ void mqtt_beat_wirte(){
g_heartbeat_count=0;
}
switch (g_device_type) {
if(get_tank_angle_count()>2){
switch (g_device_type) {
case DEVICE_TANK0202:
case DEVICE_TANK0203:
case DEVICE_TANK0204:
......@@ -119,7 +118,8 @@ void mqtt_beat_wirte(){
default:
break;
}
set_tank_angle_count_clear();
}
}
//message_type为3,控制pwm
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment