硬件I2C调试时I2C_FLAG_ADDSEND卡死

This commit is contained in:
DESKTOP-2E6P1Q6\Administrator 2025-09-25 18:05:11 +08:00
parent 14174ffa94
commit a39e0e99fb
15 changed files with 271 additions and 117 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
EWARM/ /EWARM/*
!/EWARM/iar/

View File

@ -15,6 +15,10 @@
"core_cm4.h": "c", "core_cm4.h": "c",
"gd32f4xx_usart.h": "c", "gd32f4xx_usart.h": "c",
"stdlib.h": "c", "stdlib.h": "c",
"gd32f4xx_gpio.h": "c" "gd32f4xx_gpio.h": "c",
"gd32f4xx_i2c.h": "c",
"drv_i2c.h": "c",
"mb85rc64.h": "c",
"gd32f4xx_rcu.h": "c"
} }
} }

35
EWARM/iar/GD32F450xE.icf Normal file
View File

@ -0,0 +1,35 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08000000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x2000;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define symbol __region_RAM1_start__ = 0x10000000;
define symbol __region_RAM1_end__ = 0x1000FFFF;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
place in RAM1_region { section .sram };

View File

@ -0,0 +1,35 @@
/*###ICF### Section handled by ICF editor, don't touch! ****/
/*-Editor annotation file-*/
/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x08010000;
/*-Memory Regions-*/
define symbol __ICFEDIT_region_ROM_start__ = 0x08010000;
define symbol __ICFEDIT_region_ROM_end__ = 0x0807FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__ = 0x2002FFFF;
/*-Sizes-*/
define symbol __ICFEDIT_size_cstack__ = 0x2000;
define symbol __ICFEDIT_size_heap__ = 0x2000;
/**** End of ICF editor section. ###ICF###*/
define symbol __region_RAM1_start__ = 0x10000000;
define symbol __region_RAM1_end__ = 0x1000FFFF;
define memory mem with size = 4G;
define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
define region RAM1_region = mem:[from __region_RAM1_start__ to __region_RAM1_end__];
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
initialize by copy { readwrite };
do not initialize { section .noinit };
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region { readonly };
place in RAM_region { readwrite,
block CSTACK, block HEAP };
place in RAM1_region { section .sram };

View File

@ -244,9 +244,9 @@ void i2c_master_addressing(uint32_t i2c_periph, uint32_t addr, uint32_t trandire
{ {
/* master is a transmitter or a receiver */ /* master is a transmitter or a receiver */
if(I2C_TRANSMITTER == trandirection) { if(I2C_TRANSMITTER == trandirection) {
addr = addr & I2C_TRANSMITTER; addr = addr & I2C_TRANSMITTER;//1110
} else { } else {
addr = addr | I2C_RECEIVER; addr = addr | I2C_RECEIVER;//0001
} }
/* send slave address */ /* send slave address */
I2C_DATA(i2c_periph) = addr; I2C_DATA(i2c_periph) = addr;

View File

@ -38,8 +38,10 @@ OF SUCH DAMAGE.
#include "rtservice.h" #include "rtservice.h"
#include "drv_adc.h" #include "drv_adc.h"
#include "mb85rc64.h" #include "mb85rc64.h"
#include "tmp75.h" // #include "tmp75.h"
#include "drv_usart.h" #include "drv_usart.h"
#include "drv_i2c.h"
float voltage; float voltage;
float current; float current;
@ -78,31 +80,34 @@ int main(void)
// 其他应用程序初始化代码... // 其他应用程序初始化代码...
__enable_irq(); // __enable_irq();
gd32_usart_init();
// gd32_usart_init();
i2c_init();
adc_init(); adc_init();
temp75_gpio_init(); // temp75_gpio_init();
//测试mb铁电读写 //测试mb铁电读写
memset(&ttest, 0, sizeof(ttest)); memset(&ttest, 0, sizeof(ttest));
// mb85rc64_page_write();
mb85rc64_add_read(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest));
ttest.status = 0;
ttest.ttt++;
if (ttest.ggg >= 1000)
{
ttest.ggg -= 2;
ttest.ggg /= 3;
}
else
{
ttest.ggg += 2;
ttest.ggg *= 3;
}
mb85rc64_page_write(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest)); // mb85rc64_add_read(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest));
// ttest.status = 0;
// ttest.ttt++;
// if (ttest.ggg >= 1000)
// {
// ttest.ggg -= 2;
// ttest.ggg /= 3;
// }
// else
// {
// ttest.ggg += 2;
// ttest.ggg *= 3;
// }
// mb85rc64_page_write(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest));
// 进入主循环或启动其他任务 // 进入主循环或启动其他任务
while (1) while (1)
@ -121,11 +126,10 @@ int main(void)
#endif #endif
//测试mb铁电读写 //测试mb铁电读写
read_mb_id((uint8_t*)&tiedian_id);//读取铁电ID // read_mb_id((uint8_t*)&tiedian_id);//读取铁电ID
memset(&ttest, 0, sizeof(ttest)); memset(&ttest, 0, sizeof(ttest));
// mb85rc64_page_write(); // mb85rc64_add_read(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest));
mb85rc64_add_read(MB85TEST_ADD, (unsigned char *)&ttest, sizeof(ttest));
ttest.tmperature = ptz_temperature_collect_tmp75_task(); ttest.tmperature = ptz_temperature_collect_tmp75_task();
// usart_puts(ttest.ttt); // usart_puts(ttest.ttt);

BIN
doc/sbaa588a.pdf Normal file

Binary file not shown.

BIN
doc/tmp75.pdf Normal file

Binary file not shown.

View File

@ -302,7 +302,28 @@ float ptz_Current_collect_adc1_task()
/* 温度采集 */ /* 温度采集 */
float ptz_temperature_collect_tmp75_task() float ptz_temperature_collect_tmp75_task()
{ {
tmp75[tmp75_num] = tmp75_read_temp(); uint8_t tempHL[2];
uint16_t tempCode = 0;
float temp = 0;
i2c_read(tempHL, 2);
// tmp75[tmp75_num] = tmp75_read_temp();
tempCode = (tempHL[0] << 8) | tempHL[1];
tempCode = tempCode >> 6;
if (tempCode & 0x200) // 负温度
{
tempCode &= 0x1ff;
temp = ((float)tempCode - 512) / 4;
}
else
{
temp = (float)tempCode / 4;
}
tmp75[tmp75_num] = temp;
// tmp75[tmp75_num] = tmp75_read_temp();
tmp75_num ++; tmp75_num ++;
if(tmp75_num >= LB_T_TIMES) if(tmp75_num >= LB_T_TIMES)

View File

@ -1,7 +1,8 @@
#ifndef __DRV_ADC_H_ #ifndef __DRV_ADC_H_
#define __DRV_ADC_H_ #define __DRV_ADC_H_
#include "tmp75.h" // #include "tmp75.h"
#include "drv_i2c.h"
#include "stdlib.h" #include "stdlib.h"
#include "stdbool.h" #include "stdbool.h"
#include "string.h" #include "string.h"

View File

@ -16,16 +16,16 @@ All rights reserved.
#include "rtthread.h" #include "rtthread.h"
#include <core_cm4.h> #include <core_cm4.h>
/* // /*
@ brief // @ brief 延时函数
@ param // @ param
@ return // @ return
@ note 2025-09-15 // @ note 2025-09-15
*/ // */
static void delay_us(int us) // static void delay_us(int us)
{ // {
rt_thread_udelay(us); // rt_thread_udelay(us);
} // }
void i2c_init(void) void i2c_init(void)
{ {
@ -54,6 +54,8 @@ void i2c_config(void)
// 启用 I2C 外设的时钟 // 启用 I2C 外设的时钟
rcu_periph_clock_enable(RCU_I2C0); rcu_periph_clock_enable(RCU_I2C0);
i2c_deinit(I2C_PERIPH);
// 配置 I2C 的时钟参数: // 配置 I2C 的时钟参数:
// I2C_PERIPH这里使用的I2C1 // I2C_PERIPH这里使用的I2C1
// I2C_SPEED通信速率单位为 Hz常用为 100000 或 400000这里使用100000 // I2C_SPEED通信速率单位为 Hz常用为 100000 或 400000这里使用100000
@ -62,60 +64,104 @@ void i2c_config(void)
// 配置 I2C 工作模式和地址: // 配置 I2C 工作模式和地址:
// I2C_ADDFORMAT_7BITS使用 7 位地址模式 // I2C_ADDFORMAT_7BITS使用 7 位地址模式
// I2C_BUS_ADDRESSSD2068器件代码0110010 = 0x32 // I2C_BUS_ADDRESSSD2068器件代码0110010 = 0x32
i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C_BUS_ADDRESS); i2c_mode_addr_config(I2C_PERIPH, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, TMP75_ADDRESS);
// 使能 ACK 应答功能,确保在接收数据后自动发送 ACK
i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
// 启用 I2C 外设 // 启用 I2C 外设
i2c_enable(I2C_PERIPH); i2c_enable(I2C_PERIPH);
// 使能 ACK 应答功能,确保在接收数据后自动发送 ACK
i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
} }
/*
@ brief
@ param void i2c_write(uint8_t *buff, int len)
@ return
@ note 2025-09-15
*/
float tmp75_read_temp(void)
{ {
uint8_t tempH = 0; /* 等待总线空闲 */
uint8_t tempL = 0; while(i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY));
uint16_t tempCode = 0; /* 发送起始条件 */
float temp = 0; i2c_start_on_bus(I2C_PERIPH);
/* 等待起始条件已发送标志 */
while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND));
/* 发送从机地址(写模式) */
i2c_master_addressing(I2C_PERIPH, TMP75_ADDRESS, I2C_TRANSMITTER);
/* 等待地址已发送标志 */
while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND));
/* 清除地址发送标志 */
i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND);
// 起始信号 for(int i = 0; i < len; i++)
i2c_start(); {
// 写tmp75地址 /* 等待发送数据缓冲区为空 */
tmp75_write_byte(TMP75_ADDRESS); while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE));
// 接收tmp75的ack信息 /* 发送一个字节数据 */
tmp75_ack(); i2c_data_transmit(I2C_PERIPH, buff[i]);
// 发送需读取数据的地址 }
tmp75_write_byte(TEMP_REGISTER_ADDRESS); /* 等待数据传输完成 */
tmp75_ack(); while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_TBE));
/* 发送停止条件 */
i2c_start(); i2c_stop_on_bus(I2C_PERIPH);
// 写tmp75地址 /* 等待停止条件发送完成 */
tmp75_write_byte(TMP75_ADDRESS + 1); // 读地址数据 while(I2C_CTL0(I2C_PERIPH) & I2C_CTL0_STOP); // 检查STPDET位或类似标志
tmp75_ack(); }
tempH = tmp75_read_byte();
master_ack(); //接收1字节数据
tempL = tmp75_read_byte(); void i2c_read(uint8_t *buff, uint16_t len)
master_noack(); {
i2c_stop(); /* 等待I2C总线空闲 */
while(i2c_flag_get(I2C_PERIPH, I2C_FLAG_I2CBSY));
tempCode = (tempH << 8) | tempL; /* 向I2C总线发送启动信号 */
tempCode = tempCode >> 6; i2c_start_on_bus(I2C_PERIPH);
if (tempCode & 0x200) // 负温度 /* 等待直到设置SBSEND位 */
{ while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_SBSEND));//设置主机发送启动条件
tempCode &= 0x1ff;
temp = ((float)tempCode - 512) / 4; /* 将从机地址发送到I2C总线 */
} i2c_master_addressing(I2C_PERIPH, TMP75_ADDRESS, I2C_RECEIVER);//设置主机接收
else /* 等待地址位被设置 */
{ while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_ADDSEND));
temp = (float)tempCode / 4; /* 清除地址位 */
} i2c_flag_clear(I2C_PERIPH, I2C_FLAG_ADDSEND);
TMP75_SDA_LOW;
TMP75_SCL_LOW; /* 使能ACK多个字节接收时需要应答 */
return (temp); i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
/* 5. 接收数据 */
if(len > 1)
{
/* 使能ACK多个字节接收时需要应答 */
i2c_ack_config(I2C_PERIPH, I2C_ACK_ENABLE);
for(int i = 0; i < len; i++)
{
if(i == (len - 1))
{
/* 最后一个字节前禁用ACK */
i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE);
}
/* 等待RBNE标志接收缓冲区非空 */
while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_RBNE));
/* 读取数据 */
buff[i] = i2c_data_receive(I2C_PERIPH);
}
}
else
{
/* 单字节接收直接禁用ACK */
i2c_ack_config(I2C_PERIPH, I2C_ACK_DISABLE);
/* 等待RBNE标志 */
while(!i2c_flag_get(I2C_PERIPH, I2C_FLAG_RBNE));
/* 读取数据 */
buff[0] = i2c_data_receive(I2C_PERIPH);
}
/* 发送停止信号 */
i2c_stop_on_bus(I2C_PERIPH);
/* 等待停止信号完成 */
while(I2C_CTL0(I2C_PERIPH) & I2C_CTL0_STOP);
} }

View File

@ -16,13 +16,16 @@
#include "gd32f4xx_gpio.h" #include "gd32f4xx_gpio.h"
#include "gd32f4xx_i2c.h" #include "gd32f4xx_i2c.h"
#define I2C_PERIPH I2C0 #define I2C_PERIPH I2C0
#define I2C_SCL_PIN GPIO_PIN_6 #define I2C_SCL_PIN GPIO_PIN_6
#define I2C_SDA_PIN GPIO_PIN_7 #define I2C_SDA_PIN GPIO_PIN_7
#define I2C_SPEED 100000 #define I2C_SPEED 100000
#define TMP75_ADDRESS 0x48 //1001000
// #define TMP75_ADDRESS 0x09
#define TEMP_REGISTER_ADDRESS 0x00 //mcu作为从机时被寻址的地址
// #define I2C_SCL_HIGH gpio_bit_set(GPIOB, I2C_SCL_PIN) // #define I2C_SCL_HIGH gpio_bit_set(GPIOB, I2C_SCL_PIN)
// #define I2C_SCL_LOW gpio_bit_reset(GPIOB, I2C_SCL_PIN) // #define I2C_SCL_LOW gpio_bit_reset(GPIOB, I2C_SCL_PIN)
@ -34,8 +37,10 @@
void i2c_init(void); void i2c_init(void);
void i2c_gpio_config(void); void i2c_gpio_config(void);
void i2c_config(void); void i2c_config(void);
void i2c_write(uint8_t *buff, int len);
void i2c_read(uint8_t *buff, uint16_t len);
void temp75_gpio_init(); // void temp75_gpio_init();
float tmp75_read_temp(void); // float tmp75_read_temp(void);
#endif #endif

View File

@ -26,27 +26,27 @@ static void delay_us(int us)
rt_thread_udelay(us); rt_thread_udelay(us);
} }
/* // /*
@ brief // @ brief 芯片初始化
@ param // @ param
@ return // @ return
@ note 2022-05-26 // @ note 2022-05-26
*/ // */
void mb85rc64_gpio_init() // void mb85rc64_gpio_init()
{ // {
//配置引脚时钟 // //配置引脚时钟
rcu_periph_clock_enable(RCU_GPIOB); // rcu_periph_clock_enable(RCU_GPIOB);
//设置引脚为输出模式:PB6 // //设置引脚为输出模式:PB6
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6); // gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_6);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); // gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6);
//设置引脚PB7输出模式 // //设置引脚PB7输出模式
gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7); // gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_7);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7); // gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7);
MB85RC64_SCL_HIGH; // MB85RC64_SCL_HIGH;
MB85RC64_SDA_HIGH; // MB85RC64_SDA_HIGH;
} // }
/* /*
@ brief SDA引脚为输出模式 @ brief SDA引脚为输出模式

View File

@ -15,6 +15,9 @@
#include "gd32f4xx_gpio.h" #include "gd32f4xx_gpio.h"
#define MB85RC64_ADDRESS 0x50
#define MB85RC64_ADDRESS_WRITE 0xA0 #define MB85RC64_ADDRESS_WRITE 0xA0
#define MB85RC64_ADDRESS_READ 0xA1 #define MB85RC64_ADDRESS_READ 0xA1
//mb85rc64´æ´¢µØÖ· //mb85rc64´æ´¢µØÖ·
@ -29,10 +32,9 @@
#define MB85RC64_SDA_GET gpio_input_bit_get(GPIOB, GPIO_PIN_7) #define MB85RC64_SDA_GET gpio_input_bit_get(GPIOB, GPIO_PIN_7)
void mb85rc64_gpio_init(); // void mb85rc64_gpio_init();
char mb85rc64_page_write(unsigned short int addr, unsigned char* data, int data_len); char mb85rc64_page_write(unsigned short int addr, unsigned char* data, int data_len);
char mb85rc64_add_read(unsigned short int addr, unsigned char *data, int data_len); char mb85rc64_add_read(unsigned short int addr, unsigned char *data, int data_len);
void mb85rc64_function_test();
void read_mb_id(uint8_t* buff); void read_mb_id(uint8_t* buff);
#endif #endif

View File

@ -224,16 +224,16 @@ float tmp75_read_temp(void)
// 起始信号 // 起始信号
i2c_start(); i2c_start();
// 写tmp75地址 // 写tmp75地址
tmp75_write_byte(TMP75_ADDRESS); tmp75_write_byte(TMP75_ADDRESS);//写 数据 设置
// 接收tmp75的ack信息 // 接收tmp75的ack信息
tmp75_ack(); tmp75_ack();
// 发送需读取数据的地址 // 发送需读取数据的地址
tmp75_write_byte(TEMP_REGISTER_ADDRESS); tmp75_write_byte(TEMP_REGISTER_ADDRESS);// 写地址 0x00
tmp75_ack(); tmp75_ack();
i2c_start(); i2c_start();
// 写tmp75地址 // 写tmp75地址
tmp75_write_byte(TMP75_ADDRESS + 1); // 读地址数据 tmp75_write_byte(TMP75_ADDRESS + 1); // 读 数据 设置
tmp75_ack(); tmp75_ack();
tempH = tmp75_read_byte(); tempH = tmp75_read_byte();
master_ack(); master_ack();