1.首先是超声波模块部分
超声波模块的hc-sr04.h文件
#ifndef __HC__SR04_H
#define __HC__SR04_H
#include "sys.h"
#define Trig PFout(1) // HC-SR04
void TIM9_CH1_Cap_Init(u32 arr,u16 psc);
void Trig_Init(void);
#endif
超声波模块的hc-sr04.c文件
#include "hc-sr04.h"
#include "usart.h"
//初始化PE9为输入口.并设置定时器中断9.且使能
//Echo IO 和定时器9初始化
void TIM9_CH1_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_ICInitTypeDef TIM9_ICInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM9,ENABLE); //TIM9时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //使能PORTE时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIOE5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOE,&GPIO_InitStructure); //初始化PE5
GPIO_PinAFConfig(GPIOE,GPIO_PinSource5,GPIO_AF_TIM9); //PE5复用位定时器9
TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM9,&TIM_TimeBaseStructure);
//初始化TIM9输入捕获参数
TIM9_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM9_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕获
TIM9_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM9_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置输入分频,不分频
TIM9_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM9, &TIM9_ICInitStructure);
TIM_ITConfig(TIM9,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断
TIM_Cmd(TIM9,ENABLE ); //使能定时器9
NVIC_InitStructure.NVIC_IRQChannel = TIM1_BRK_TIM9_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、
}
//捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.
//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)
u8 TIM9CH1_CAPTURE_STA=0; //输入捕获状态
u32 TIM9CH1_CAPTURE_VAL; //输入捕获值(TIM9是32位)
//定时器9中断服务程序
void TIM1_BRK_TIM9_IRQHandler(void)
{
if((TIM9CH1_CAPTURE_STA&0X80)==0)//还未成功捕获
{
if(TIM_GetITStatus(TIM9, TIM_IT_Update) == SET)//溢出
{
if(TIM9CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
{
if((TIM9CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
{
TIM9CH1_CAPTURE_STA|=0X80; //标记成功捕获了一次
TIM9CH1_CAPTURE_VAL=0XFFFFFFFF;
}else TIM9CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM9, TIM_IT_CC1) != RESET)//捕获1发生捕获事件
{
if(TIM9CH1_CAPTURE_STA&0X40) //捕获到一个下降沿
{
TIM9CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽
TIM9CH1_CAPTURE_VAL=TIM_GetCapture1(TIM9);//获取当前的捕获值.
TIM_OC1PolarityConfig(TIM9,TIM_ICPolarity_Rising); //OC1P=0 设置为上升沿捕获
}else //还未开始,第一次捕获上升沿
{
TIM9CH1_CAPTURE_STA=0; //清空
TIM9CH1_CAPTURE_VAL=0;
TIM9CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿
TIM_Cmd(TIM5,DISABLE ); //关闭定时器9
TIM_SetCounter(TIM9,0);
TIM_OC1PolarityConfig(TIM9,TIM_ICPolarity_Falling); //OC1P=1 设置为下降沿捕获
TIM_Cmd(TIM9,ENABLE ); //使能定时器9
}
}
}
TIM_ClearITPendingBit(TIM9, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位
}
//初始化PF1为输出口.并使能时钟
//Trig IO初始化
void Trig_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
//GPIOF1初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化
GPIO_ResetBits(GPIOF,GPIO_Pin_1);//初始化GPIOF1为低电平
}
配置文件缺少什么就补什么,上篇STM32F407红外避障控制舵机有写。
2.到称重传感器模块
压力传感器的HX711.h文件
#ifndef __HX711_H
#define __HX711_H
#include "sys.h"
#define HX711_SCK PBout(0)// PB0
#define HX711_DOUT PBin(1)// PB1
extern void Init_HX711pin(void);
extern u32 HX711_Read(void);
extern void Get_Maopi(void);
extern void Get_Weight(void);
extern u32 HX711_Buffer;
extern u32 Weight_Maopi;
extern s32 Weight_Shiwu;
extern u8 Flag_Error;
#endif
压力传感器的HX711.c文件
#include "HX711.h"
#include "delay.h"
u32 HX711_Buffer=0;
u32 Weight_Maopi=0;
s32 Weight_Shiwu=0;
u8 Flag_Error = 0;
//校准参数
//因为不同的传感器特性曲线不是很一致,因此,每一个传感器需要矫正这里这个参数才能使测量值很准确。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
//该值可以为小数
#define GapValue 285
void digitalWrite(GPIO_TypeDef * GPIO,int pin,int value)
{
if(value==1)//set 1
{
GPIO_SetBits(GPIO,pin);
}
if(value==0)//reset 0
{
GPIO_ResetBits(GPIO,pin);
}
}
int digitalRead(GPIO_TypeDef * GPIO,int pin)
{
return GPIO_ReadInputDataBit(GPIO,pin);
}
void Init_HX711pin(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure1;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//SCK
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
//DOUT
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_1 ;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IN;
//GPIO_InitStructure1.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure1.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure1);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//初始化设置为0
}
//读取HX711
u32 HX711_Read(void) //增益128
{
unsigned long count;
unsigned char i=0;
// HX711_DOUT=1;
while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1));
delay_us(1);
HX711_SCK=0;
count=0;
delay_us(1);
// while(HX711_DOUT);
while(!GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1));
for(i=0;i<24;i++)
{
delay_us(100);
HX711_SCK=1;
count=count<<1;
delay_us(1);
HX711_SCK=0;
if(HX711_DOUT)
count++;
delay_us(1);
}
HX711_SCK=1;
count=count^0x800000;//第25个脉冲下降沿来时,转换数据
delay_us(1);
HX711_SCK=0;
delay_us(1);
return (count);
}
//获取毛皮重量
void Get_Maopi(void)
{
Weight_Maopi = HX711_Read();
}
//称重
void Get_Weight(void)
{
HX711_Buffer = HX711_Read();
if(HX711_Buffer > Weight_Maopi)
{
Weight_Shiwu = HX711_Buffer;
Weight_Shiwu = Weight_Shiwu - Weight_Maopi; //获取实物的AD采样数值。
Weight_Shiwu = (s32)((float)Weight_Shiwu/GapValue); //计算实物的实际重量
//因为不同的传感器特性曲线不一样,因此,每一个传感器需要矫正这里的GapValue这个除数。
//当发现测试出来的重量偏大时,增加该数值。
//如果测试出来的重量偏小时,减小改数值。
}
}
到TFT LCD显示模块的lcd.h和lcd.c代码过长,百度下载引入即可用
3.到主程序部分
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "hc-sr04.h"
#include "lcd.h"
#include "HX711.h"
extern u8 TIM9CH1_CAPTURE_STA; //输入捕获状态
extern u32 TIM9CH1_CAPTURE_VAL; //输入捕获值
int main(void)
{
float temp=0;
u8 complete = 1; //一次采集完成标志
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200);//初始化串口波特率为115200
LCD_Init(); //初始化LCD FSMC接口
Trig_Init();
TIM9_CH1_Cap_Init(0XFFFFFFFF,84-1); //以1Mhz的频率计数 timer9是32位的。
Init_HX711pin();
delay_ms(2000);
Get_Maopi(); //称毛皮重量
delay_ms(100);
POINT_COLOR=RED; //画笔颜色:红色
while(1)
{
if(complete == 1)
{
Trig = 1;
delay_us(15);
Trig = 0;
complete = 0;
}
while(complete == 0)
{
if(TIM9CH1_CAPTURE_STA&0X80) //成功捕获到了一次高电平
{
temp=TIM9CH1_CAPTURE_STA&0X3F;
temp*=0XFFFFFFFF; //溢出时间总和
temp+=TIM9CH1_CAPTURE_VAL; //得到总的高电平时间
temp = temp * 17/1000; //得到距离
printf("HIGH:%f cm\r\n",temp); //打印距离
delay_ms(1000);
LCD_ShowNum(50,10,temp,3,16); //TFT LCD打印距离
TIM9CH1_CAPTURE_STA=0; //开启下一次捕获
complete = 1;
}
}
Get_Weight();
Get_Maopi();
printf("净重量 = %d g\r\n",Weight_Shiwu); //打印
printf("毛坯 = %d g\r\n",Weight_Maopi); //打印
printf("重量 = %d g\r\n",HX711_Buffer); //打印
delay_ms(1000);
LCD_ShowNum(50,50,Weight_Shiwu,8,16); //TFT LCD打印输出
LCD_ShowNum(50,100,Weight_Maopi,8,16);
LCD_ShowNum(50,150,HX711_Buffer,8,16);
}
}