/*********************************************************************************************************
* 模块名称 : BSP HX711数据采集
* 版 本 : V1.00
* 说 明 : HX711每约12.5mS SDAT引脚输出80uS的高电平触发读取HX710的数据,模块稳定需要延时0.4秒。
* 创 建 人 : TV--20200410
* 修改记录 :
*
*********************************************************************************************************/
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
///////////////////////////////////////////////////////////////////////////////////////////////////////////
//校准参数
//因为不同的传感器特性曲线不一样,因此每一个传感器需要矫正这里的K_value=AD差值/重量克数差值。
//#define K_value 0
//估算校准参数,需要据实填写称重传感器 灵敏度和量程
#ifndef K_value
#define LoadCell_Sensitivity 1 // 灵敏度 单位 mV/V
#define LoadCell_FS 10000 // 满量程 单位 克
// K = 1mV*128*2^24/满量程克 = 2147484/满量程克 估算 K
#define K_value (2147483.0f*LoadCell_Sensitivity/LoadCell_FS)
#endif
// 触发力大小, 单位:克
#define ThresholdTriggerForce 20
//HX711 连接的GPIO端口 ,更换电路板更改
#define GPIO_PORT_SCK1 GPIOB
#define GPIO_PIN_SCK1 GPIO_Pin_1
#define GPIO_PORT_SDA1 GPIOB
#define GPIO_PIN_SDA1 GPIO_Pin_0
//HX711 连接的GPIO 时钟
#define RCC_APB2_SCK1 RCC_APB2Periph_GPIOB
#define RCC_APB2_SDA1 RCC_APB2Periph_GPIOB
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#if 0 // 条件编译: 1 选择GPIO的库函数实现IO读写
#define SCK1_H GPIO_SetBits( GPIO_PORT_SCK1, GPIO_PIN_SCK1 )
#define SCK1_L GPIO_ResetBits( GPIO_PORT_SCK1, GPIO_PIN_SCK1 )
#define SDA1_READ GPIO_ReadInputDataBit( GPIO_PORT_SDA1, GPIO_PIN_SDA1 )
#else // 这个分支选择直接寄存器操作实现IO读写
// 注意:如下写法,在IAR最高级别优化时,会被编译器错误优化
#define SCK1_H GPIO_PORT_SCK1->BSRR = GPIO_PIN_SCK1 // SCK = 1
#define SCK1_L GPIO_PORT_SCK1->BRR = GPIO_PIN_SCK1 // SCK = 0
#define SDA1_READ (GPIO_PORT_SDA1->IDR & GPIO_PIN_SDA1) // 读SDA口线状态
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////
static s32 s32InitWeight;
///////////////////////////////////////////////////////////////////////////////////////////////////////////
/*********************************************************************************************************
* 功能说明: HX711 IO初始化
*********************************************************************************************************/
static void Init_HX711pin(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2_SCK1, ENABLE); //使能Px端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2_SDA1, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // GPIO_Mode_Out_PP; //GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_SCK1;
GPIO_Init( GPIO_PORT_SCK1, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_PIN_SDA1;
GPIO_Init( GPIO_PORT_SDA1, &GPIO_InitStructure );
}
/*********************************************************************************************************
功能说明: HX711 是否存在检测。上电HX710唤醒后400ms后可以有效检测,利用HX711AD转换结束会在 SDA1_READ 生成脉冲电平
返回 : 1:正常 0:HX711故障
*********************************************************************************************************/
static u32 HX711_Check( void )
{
u32 i;
// 等待 SDA1_READ 为低电平
for(i=0; i<1600000; i++)
{
if(SDA1_READ==0)
break;
}
if(i==1600000)
return 0;
// 等待 SDA1_READ 为高电平
for(i=0; i<1600000; i++)
{
if(SDA1_READ!=0)
break;
}
if(i==1600000)
return 0;
// 再次等待 SDA1_READ 为低电平
for(i=0; i<1600000; i++)
{
if(SDA1_READ==0)
break;
}
if(i==1600000)
return 0;
// // AD 采样一次至少 6ms SDA1_READ 为低电平
// if(i<60000) // 约6ms
// return 0;
return 1;
}
/*********************************************************************************************************
功能说明: 读取HX711 AD数据,增益128
返回 : 无符号 AD值,如返回0表示 HX711或传感器故障
*********************************************************************************************************/
static u32 HX711_Read(void)
{
u32 data;
u32 i;
// 等待 SDA1_READ 为低电平
for(i=0; i<1600000; i++)
{
if(SDA1_READ==0)
break;
}
if(i==1600000)
return 0;
// 读取 AD数据
SCK1_H;
data=0;
for(i=0; i<24; i++)
{
__NOP();
SCK1_L;
__NOP();
data=data<<1;
if(SDA1_READ)
data++;
SCK1_H;
}
data=data^0x800000; // 24位有符号数转换为无符号数
__NOP();
SCK1_L;
return(data);
}
#if 0
// 注意 更改IO需要更改相应 stm32f10x_it.c 文件中中断函数入口
#define EXTI_HX710_Priority 6
#define GPIO_PortSource_Channel1 GPIO_PortSourceGPIOB
#define GPIO_PinSource_Channel1 GPIO_PinSource4
#define EXTI_Line_Channel1 EXTI_Line4
#define EXTI_Channel1_IRQn EXTI4_IRQn
#define EXTI_HX710C1_ISRFUN void EXTI4_IRQHandler(void) // 中断的函数名
/*********************************************************************************************************
* 功能说明: 初始化 XH711 外部中断线
**********************************************************************************************************/
static void HX710_EXTI_Config( void )
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/*********************外部中断0配置*************************/
GPIO_EXTILineConfig( GPIO_PortSource_Channel1, GPIO_PinSource_Channel1 ); // 把PB.1设置为外部中断
EXTI_DeInit(); // 将EXIT寄存器重设置为缺省值
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 设置EXTI线路为重点请求
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 设置输入线路为下降沿为中断请求 EXTI_Trigger_Rising; //设置输入线路为上升沿为中断请求
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 中断使能
EXTI_InitStructure.EXTI_Line = EXTI_Line_Channel1 ; // 设置外部中断线
EXTI_Init( &EXTI_InitStructure );
// NVIC_SetVectorTable(NVIC_VectTab_FLASH, 2); //设置向量表的地址为FLASH,偏移量为0
NVIC_InitStructure.NVIC_IRQChannel = EXTI_Channel1_IRQn; // EXTI0_IRQn;//设置外部中断1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = EXTI_HX710_Priority; // 主优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; // 从优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 中断使能
NVIC_Init( &NVIC_InitStructure );
}
/*********************************************************************************************************
* 功能说明: HX710数据触发中断函数
**********************************************************************************************************/
volatile u32 HX710_buf_Data;
volatile u32 g_sysErrFlag;
EXTI_HX710C1_ISRFUN // HX710通道1中断服务程序
{
static volatile u32 Count;
static volatile u32 i;
if ( EXTI_GetITStatus( EXTI_Line_Channel1 ) != RESET ) // 检测指定的EXTI0线路触发请求与否 发生中断时返回SET 无中断时返回RESET
{
Count = 0;
SCK1_H;
for ( i = 0; i < 24; i++ ) /* 读24个bit AD值 */
{
SCK1_L;
- 1
- 2
- 3
前往页