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,79 @@
/*
*********************************************************************************************************
*
* 模块名称 : WM8978音频芯片驱动模块
* 文件名称 : bsp_WM8978.h
* 版 本 : V1.0
* 说 明 : 头文件
* 修改记录 :
* 版本号 日期 作者 说明
* v0.1 2009-12-27 armfly 创建该文件,ST固件库版本为V3.1.2
* v1.0 2011-09-04 armfly ST固件库升级到V3.5.0版本。
*
* Copyright (C), 2010-2011, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#ifndef _BSP_WM8978_H
#define _BSP_WM8978_H
#include <inttypes.h>
#define WM8978_SLAVE_ADDRESS 0x34 /* WM8978 I2C从机地址 */
/* WM8978 音频输入通道控制选项, 可以选择多路,比如 MIC_LEFT_ON | LINE_ON */
typedef enum
{
IN_PATH_OFF = 0x00, /* 无输入 */
MIC_LEFT_ON = 0x01, /* LIN,LIP脚,MIC左声道(接板载咪头) */
MIC_RIGHT_ON = 0x02, /* RIN,RIP脚,MIC右声道(接GPRS模块音频输出) */
LINE_ON = 0x04, /* L2,R2 立体声输入 */
AUX_ON = 0x08, /* AUXL,AUXR 立体声输入 */
DAC_ON = 0x10, /* I2S数据DAC (CPU产生音频信号) */
ADC_ON = 0x20 /* 输入的音频馈入WM8978内部ADC I2S录音) */
}IN_PATH_E;
/* WM8978 音频输出通道控制选项, 可以选择多路 */
typedef enum
{
OUT_PATH_OFF = 0x00, /* 无输出 */
EAR_LEFT_ON = 0x01, /* LOUT1 耳机左声道 */
EAR_RIGHT_ON = 0x02, /* ROUT1 耳机右声道 */
SPK_ON = 0x04, /* LOUT2和ROUT2反相输出单声道,接扬声器 */
OUT3_4_ON = 0x08, /* OUT3 和 OUT4 输出单声道音频, 接GSM模块的音频输入 */
}OUT_PATH_E;
/* 定义最大音量 */
#define VOLUME_MAX 63 /* 最大音量 */
#define VOLUME_STEP 1 /* 音量调节步长 */
/* 定义最大MIC增益 */
#define GAIN_MAX 63 /* 最大增益 */
#define GAIN_STEP 1 /* 增益步长 */
/* 供外部引用的函数声明 */
uint8_t wm8978_Init(void);
void wm8978_CfgAudioIF(uint16_t _usStandard, uint8_t _ucWordLen);
void wm8978_OutMute(uint8_t _ucMute);
void wm8978_PowerDown(void);
void wm8978_CfgAudioPath(uint16_t _InPath, uint16_t _OutPath);
void wm8978_SetMicGain(uint8_t _ucGain);
void wm8978_SetLineGain(uint8_t _ucGain);
void wm8978_SetSpkVolume(uint8_t _ucVolume);
void wm8978_SetEarVolume(uint8_t _ucVolume);
uint8_t wm8978_ReadEarVolume(void);
uint8_t wm8978_ReadSpkVolume(void);
void wm8978_NotchFilter(uint16_t _NFA0, uint16_t _NFA1);
void I2S_CODEC_Init(void);
void I2S_StartPlay(uint16_t _usStandard, uint16_t _usWordLen, uint16_t _usAudioFreq);
void I2S_StartRecord(uint16_t _usStandard, uint16_t _usWordLen, uint16_t _usAudioFreq);
void I2S_Stop(void);
void wm8978_RegCash_Output(void);
#endif
@@ -0,0 +1,232 @@
/*************************** (C) COPYRIGHT 2018 PING ****************************
* 文件名 bsp_i2c_gpio.h
* 描 述 :IO口模拟I2C程序
* 版 本 V1.0
* 日 期 2018-01-11
* 作 者 XuZhongPing
* 更新记录
*********************************************************************************/
#include "stm32f10x.h"
#include "bsp_i2c_gpio.h"
#include "delay.h"
/* 定义I2C总线连接的GPIO端口, 用户只需要修改下面4行代码即可任意改变SCL和SDA的引脚 */
#define GPIO_PORT_I2C GPIOD /* GPIO端口 */
#define RCC_I2C_PORT RCC_APB2Periph_GPIOD /* GPIO端口时钟 */
#define I2C_SCL_PIN GPIO_Pin_10 /* 连接到SCL时钟线的GPIO */
#define I2C_SDA_PIN GPIO_Pin_9 /* 连接到SDA数据线的GPIO */
static void i2c_CfgGpio(void);
/*
*********************************************************************************************************
* 函 数 名: i2c_Start
* 功能说明: CPU发起I2C总线启动信号
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
IIC_SCL=1;
delay_us(4);
IIC_SDA=0; //START:when CLK is high,DATA change form high to low
delay_us(4);
IIC_SCL=0; //钳住I2C总线,准备发送或接收数据
}
/*
*********************************************************************************************************
* 函 数 名: i2c_Start
* 功能说明: CPU发起I2C总线停止信号
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
/*
*********************************************************************************************************
* 函 数 名: i2c_SendByte
* 功能说明: CPU向I2C总线设备发送8bit数据
* 形 参:_ucByte : 等待发送的字节
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(uint8_t _ucByte)
{
uint8_t t;
SDA_OUT();
IIC_SCL = 0; //拉低时钟开始数据传输
for(t=0; t<8; t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((_ucByte&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
_ucByte<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
/*
*********************************************************************************************************
* 函 数 名: i2c_ReadByte
* 功能说明: CPU从I2C总线设备读取8bit数据
* 形 参:无
* 返 回 值: 读到的数据
*********************************************************************************************************
*/
uint8_t i2c_ReadByte(void)
{
// unsigned char i,receive=0;
// SDA_IN();//SDA设置为输入
// for(i=0;i<8;i++ )
// {
// IIC_SCL=0;
// delay_us(2);
// IIC_SCL=1;
// receive<<=1;
// if(READ_SDA)receive++;
// delay_us(1);
// }
// if (!ack)
// IIC_NAck();//发送nACK
// else
// IIC_Ack(); //发送ACK
// return receive;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_WaitAck
* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
* 形 参:无
* 返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
uint8_t i2c_WaitAck(void)
{
uint8_t ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
i2c_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_Ack
* 功能说明: CPU产生一个ACK信号
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_NAck
* 功能说明: CPU产生1个NACK信号
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
/*
*********************************************************************************************************
* 函 数 名: i2c_CfgGpio
* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现
* 形 参:无
* 返 回 值: 无
*********************************************************************************************************
*/
static void i2c_CfgGpio(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_I2C_PORT, ENABLE); /* 打开GPIO时钟 */
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /* 开漏输出 GPIO_Mode_Out_PP GPIO_Mode_Out_OD*/
GPIO_Init(GPIO_PORT_I2C, &GPIO_InitStructure);
GPIO_SetBits(GPIO_PORT_I2C, I2C_SCL_PIN | I2C_SDA_PIN);
/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */
i2c_Stop();
}
/*
*********************************************************************************************************
* 函 数 名: i2c_CheckDevice
* 功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在
* 形 参:_Address:设备的I2C总线地址
* 返 回 值: 返回值 0 表示正确, 返回1表示未探测到
*********************************************************************************************************
*/
uint8_t i2c_CheckDevice(uint8_t _Address)
{
uint8_t ucAck;
i2c_CfgGpio(); /* 配置GPIO */
i2c_Start(); /* 发送启动信号 */
/* 发送设备地址+读写控制bit0 = w 1 = r) bit7 先传 */
i2c_SendByte(_Address | I2C_WR);
ucAck = i2c_WaitAck(); /* 检测设备的ACK应答 */
i2c_Stop(); /* 发送停止信号 */
return ucAck;
}
@@ -0,0 +1,44 @@
/*
*********************************************************************************************************
*
* 模块名称 : I2C总线驱动模块
* 文件名称 : bsp_i2c_gpio.h
* 版 本 : V1.0
* 说 明 : 头文件。
* 修改记录 :
* 版本号 日期 作者 说明
* v1.0 2011-08-21 armfly ST固件库升级到V3.5.0版本。
*
* Copyright (C), 2010-2011, 安富莱电子 www.armfly.com
*
*********************************************************************************************************
*/
#ifndef _BSP_I2C_GPIO_H
#define _BSP_I2C_GPIO_H
#include <inttypes.h>
#include "stm32f10x.h"
#define I2C_WR 0 /* 写控制bit */
#define I2C_RD 1 /* 读控制bit */
//IO方向设置
#define SDA_IN() {GPIOD->CRH&=0XFFFFFF0F;GPIOD->CRH|=8<<4;}
#define SDA_OUT() {GPIOD->CRH&=0XFFFFFF0F;GPIOD->CRH|=3<<4;}
//IO操作函数
#define IIC_SCL PDout(10) //SCL
#define IIC_SDA PDout(9) //SDA
#define READ_SDA PDin(9) //输入SDA
void i2c_Start(void);
void i2c_Stop(void);
void i2c_SendByte(uint8_t _ucByte);
uint8_t i2c_ReadByte(void);
uint8_t i2c_WaitAck(void);
void i2c_Ack(void);
void i2c_NAck(void);
uint8_t i2c_CheckDevice(uint8_t _Address);
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,198 @@
/*************************** (C) COPYRIGHT 2018 PING ****************************
* 文件名 sound.h
* 描 述 :语音播报控制程序
* 版 本 V1.0
* 日 期 2016-01-11
* 作 者 XuZhongPing
* 更新记录
*********************************************************************************/
#include "sound.h"
#include "delay.h"
#include "timer.h"
#include "usart1.h"
#include "stdio.h"
#include "string.h"
#define SPEAKER_PORT_PeriphClock RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO
#define SPEAKER_PORT GPIOB
#define SPEAKER_CTRL_PIN GPIO_Pin_3
uint8_t audioOutputMark = 0; //标志是否输出语音
uint8_t audioNum = 0; //语音编号
uint8_t audioOutputStatus = 0; //音频输出状态
/*
***********************************************************************
* 函 数 名: SpeakerInit
* 功能说明: 扬声器控制接口初始化
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void SpeakerInit(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SPEAKER_PORT_PeriphClock, ENABLE); //使能时钟
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //关闭JTAG的PB3,PB4复用功能
GPIO_InitStructure.GPIO_Pin = SPEAKER_CTRL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPEAKER_PORT, &GPIO_InitStructure);
GPIO_ResetBits(SPEAKER_PORT, SPEAKER_CTRL_PIN);
}
/*
***********************************************************************
* 函 数 名: AudioInit
* 功能说明: 音频相关初始化
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
void Audio_Init(void)
{
SpeakerInit();
Audio_SetVolume(20);
}
/*
***********************************************************************
* 函 数 名: Audio_OutputEnable
* 功能说明: 音频输出使能
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
static void Audio_OutputEnable(void)
{
GPIO_SetBits(SPEAKER_PORT, SPEAKER_CTRL_PIN);
audioOutputStatus = 1;
}
/*
***********************************************************************
* 函 数 名: Audio_OutputDisable
* 功能说明: 音频输出失能
* 形 参:无
* 返 回 值: 无
***********************************************************************
*/
static void Audio_OutputDisable(void)
{
GPIO_ResetBits(SPEAKER_PORT, SPEAKER_CTRL_PIN);
audioOutputStatus = 0;
}
/*
***********************************************************************
* 函 数 名: Audio_SetVolume
* 功能说明: 设置音频音量
* 形 参:val -> 音量值
* 返 回 值: 无
***********************************************************************
*/
void Audio_SetVolume(uint8_t volume)
{
char str[32];
if (volume<=30 && volume>=1)
{
sprintf(str, "AF:%d", volume);
USART1_SendFrameData((uint8_t*)str, strlen(str));
}
}
/*
***********************************************************************
* 函 数 名: Audio_Play
* 功能说明: 播放指定音频
* 形 参:num -> 语音编号
* 返 回 值: 无
***********************************************************************
*/
void Audio_PlayOutput(uint8_t num)
{
char str[32];
sprintf(str, "A7:%05d", num);
Audio_OutputEnable(); //使能语音输出
USART1_SendFrameData((uint8_t*)str, strlen(str));
}
/*
***********************************************************************
* 函 数 名: Audio_Play
* 功能说明: 播放指定音频
* 形 参:num -> 语音编号
* 返 回 值: 无
***********************************************************************
*/
void Audio_Play(uint8_t num)
{
audioOutputMark = 1;
audioNum = num;
}
/*
***********************************************************************
* 函 数 名: Audio_Play
* 功能说明: 播放指定音频
* 形 参:num -> 语音编号
* 返 回 值: 无
***********************************************************************
*/
void Audio_PlayTask(void)
{
static uint8_t RunningStatus = 0x00;
static timer waitingTimer;
static uint8_t timer_ok = 0;
if(timer_ok == 0)
{
timer_ok = 1;
timer_set(&waitingTimer, CLOCK_SECOND*5);
}
switch(RunningStatus)
{
case 0x00:
if(audioOutputMark == 1)
{
audioOutputMark = 0;
Audio_PlayOutput(audioNum);
timer_restart(&waitingTimer);
RunningStatus = 0x01;
break;
}
break;
case 0x01:
if(audioOutputMark == 1)
{
RunningStatus = 0x00;
break;
}
if(timer_expired(&waitingTimer))
{
printf("\r\n停止播放!\r\n");
Audio_OutputDisable(); //关闭语音输出
RunningStatus = 0x00;
break;
}
break;
case 0x02:
break;
default:
RunningStatus = 0x00;
break;
}
}
/******************** (C) COPYRIGHT 2014 GLHF *****END OF FILE*******************/
@@ -0,0 +1,28 @@
/*************************** (C) COPYRIGHT 2014 GLHF ****************************
* 文件名 sound.h
* 描 述 :语音播报控制头文件
* 版 本 V1.0
* 日 期 2016-01-11
* 作 者 XuZhongPing
* 更新记录
*********************************************************************************/
#ifndef __SOUND_H
#define __SOUND_H
#include "stm32f10x.h"
#include "stdio.h"
extern uint8_t audioOutputMark; //标志是否输出语音
extern uint8_t audioNum; //语音编号
extern uint8_t audioOutputStatus; //音频输出状态
void AudioInit(void);
void VoiceBroadcast (uint8_t number);
void Audio_Init(void);
void Audio_SetVolume(uint8_t volume);
void Audio_Play(uint8_t num);
void Audio_PlayTask(void);
#endif
/******************** (C) COPYRIGHT 2014 GLHF *****END OF FILE*******************/
@@ -0,0 +1,15 @@
#ifndef __SOUNDFILELIST_H
#define __SOUNDFILELIST_H
#include "stm32f10x.h"
const uint32_t SOUND_FILE_LIST[5][2] = {
/*起启地址 长度*/
{0x00002C, 0x0088BC}, //00语音信息
{0x0088E8, 0x00F898}, //01语音信息
{0x018180, 0x0151F8}, //02语音信息
{0x02D378, 0x01701A}, //03语音信息
{0x044392, 0x032E5C} //04语音信息
};
#endif