feat: add STM32 four-channel weighing firmware

This commit is contained in:
FinleyHsu
2026-07-28 11:01:55 +08:00
commit 1282b9b77e
205 changed files with 80376 additions and 0 deletions
@@ -0,0 +1,353 @@
/*************************** (C) COPYRIGHT 2018 Ping ****************************
* 文件名 timer.c
* 描 述 :定时器驱动代码
* 版 本 V1.0
* 作 者 XuZhongPing
* 日 期 2017/02/07
*********************************************************************************/
#include "timer.h"
#include "usart1.h"
#include "device.h"
#include "data_typedef.h"
uint32_t time_value = 0;//uip 计时器,每10ms增加1.
/*
***********************************************************************
* 函 数 名: clock_time
* 功能说明: 取得当前计时值
* 形 参: 无
* 返 回 值: 当前计时值
***********************************************************************
*/
clock_time_t clock_time(void)
{
return time_value; /* 10ms 单位 */
}
/*
***********************************************************************
* 函 数 名: timer_set
* 功能说明: 设置一个定时间隔
* 形 参:
* t:定时变量
* interval:定时间隔值
* 返 回 值: 无
***********************************************************************
*/
void timer_set(timer *t, clock_time_t interval)
{
t->interval = interval;
t->start = clock_time();
}
/*
***********************************************************************
* 函 数 名: timer_reset
* 功能说明: 对定时变量进行复位
* 形 参:
* t:定时变量
* 返 回 值: 无
***********************************************************************
*/
void timer_reset(timer *t)
{
t->start += t->interval;
}
/*
***********************************************************************
* 函 数 名: timer_reset_interval
* 功能说明: 重新设置定时时间
* 形 参:
* t:定时变量
* 返 回 值: 无
***********************************************************************
*/
void timer_reset_interval(timer *t, clock_time_t interval)
{
t->interval = interval;
}
/*
***********************************************************************
* 函 数 名: timer_restart
* 功能说明: 从当前时间点重新启动定时器
* 形 参:
* t:定时变量
* 返 回 值: 无
***********************************************************************
*/
void timer_restart(timer *t)
{
t->start = clock_time();
}
/*
***********************************************************************
* 函 数 名: timer_expired
* 功能说明: 判断一个定时器是否达到定时时间
* 形 参:
* t:定时变量
* 返 回 值: 非零则已经到了定时时间,零则定时还未到
***********************************************************************
*/
int timer_expired(timer *t)
{
return (clock_time_t)(clock_time() - t->start) >= (clock_time_t)t->interval;
}
/*
***********************************************************************
* 函 数 名: timer_remaining
* 功能说明: 判断一个定时器还剩下多少时间达到定时时间
* 形 参:
* t:定时变量
* 返 回 值: 返回定时器剩余时间
***********************************************************************
*/
uint32_t timer_remaining(timer *t)
{
uint32_t res = 0;
if(clock_time() < (t->start + (clock_time_t)t->interval))
{
res = (t->start + (clock_time_t)t->interval) - clock_time();
return res;
}else{
return 0;
}
}
//定时器定时器2用于开始一个软件定时供外部程序使用
//单位为100ms(0.1S)
/*
***********************************************************************
* 函 数 名: TIM2_Int_Init
* 功能说明: 定时器2初始化配置
* 形 参:arr:自动重装值
* psc:时钟预分频数
* 返 回 值: 无
***********************************************************************
*/
void TIM2_Int_Init(uint16_t arr,uint16_t psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率(即0.1ms周期)
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig( TIM2, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //使能定时器2更新触发中断
TIM_Cmd(TIM2, ENABLE); //使能TIMx外设
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
/*
***********************************************************************
* 函 数 名: TIM2_IRQHandler
* 功能说明: 定时器2中断服务子程序
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void TIM2_IRQHandler(void) //TIM2中断
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
time_value++; //计时器增加1
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//定时器3部分(用于按键扫描)每10ms中断一次
/*
***********************************************************************
* 函 数 名: TIM3_Int_Init
* 功能说明: 定时器3初始化配置
* 形 参:arr:自动重装值
* psc:时钟预分频数
* 返 回 值: 无
***********************************************************************
*/
void TIM3_Int_Init(uint16_t arr,uint16_t psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler = psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率(即0.1ms周期)
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig( TIM3, TIM_IT_Update|TIM_IT_Trigger, ENABLE); //使能定时器2更新触发中断
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
/*
***********************************************************************
* 函 数 名: TIM3_IRQHandler
* 功能说明: 定时器2中断服务子程序
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void TIM3_IRQHandler(void) //TIM3中断
{
uint8_t keyTemp = 0;
static uint8_t timerCut = 0;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
if(deviceInitFlag == 1)
{
// OptoKeyScanning();
// BottleScanning(); //调用瓶子扫描检测函数
if(keyType == 0)
{
keyTemp = KeyScanning();
}else if(keyType == 1){
keyTemp = TouchKeyScanning();
}
if(keyTemp != 0)
{
keyValue = keyTemp; //输出键值由外部读取后清除
}
}
}
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//定时器4部分(用于超声波测距)
/*
***********************************************************************
* 函 数 名: TIM4_Int_Init
* 功能说明: 定时器4初始化配置
* 形 参:arr:自动重装值
* psc:时钟预分频数
* 返 回 值: 无
***********************************************************************
*/
void TIM4_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //时钟使能
//定时器TIM4初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM4, TIM_IT_Update | TIM_IT_Trigger, ENABLE); //使能指定的TIM4中断,允许更新中断
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM4, DISABLE);
// TIM_Cmd(TIM4, ENABLE);
}
/*
***********************************************************************
* 函 数 名: TIM4_IRQHandler
* 功能说明: 定时器4中断服务子程序
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void TIM4_IRQHandler(void) //TIM4中断
{
if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //检查TIM4更新中断发生与否
{
TIM_ClearITPendingBit(TIM4, TIM_IT_Update); //清除TIMx更新中断标志
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//定时器4部分(用于二维码读头数据接收完成标记用)
/*
***********************************************************************
* 函 数 名: TIM5_Int_Init
* 功能说明: 定时器5初始化配置
* 形 参:arr:自动重装值
* psc:时钟预分频数
* 返 回 值: 无
***********************************************************************
*/
void TIM5_Int_Init(uint16_t arr, uint16_t psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
//定时器TIM5初始化
TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE ); //使能指定的TIM4中断,允许更新中断
//中断优先级NVIC设置
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //TIM5中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; //先占优先级3级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级2级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
TIM_Cmd(TIM5, DISABLE); //失能TIMx外设
}
/*
***********************************************************************
* 函 数 名: TIM5_IRQHandler
* 功能说明: 定时器4中断服务子程序
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void TIM5_IRQHandler(void)
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET) //检查TIM5更新中断发生与否
{
USART1_RX_STA |= 1<<15; //标记接收完成
TIM_ClearITPendingBit(TIM5, TIM_IT_Update); //清除TIMx更新中断标志
TIM_Cmd(TIM5, DISABLE); //关闭TIMx
}
}
/******************** (C) COPYRIGHT 2018 Ping *****END OF FILE*******************/