ADI Blackfin DSP处理器-BF533的开发详解17:IIS+AUDIO音频codec的应用(含源代码)

本文主要是介绍ADI Blackfin DSP处理器-BF533的开发详解17:IIS+AUDIO音频codec的应用(含源代码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

硬件准备

ADSP-EDU-BF533:BF533开发板
AD-HP530ICE:ADI DSP仿真器

软件准备

Visual DSP++软件

硬件链接

在这里插入图片描述

很早期做的设计,用的是TI的一颗音频codec,如果要放到今天,我肯定是用ADI的SigmaDSP了,ADI所有的SigmaDSP我都用过,非常熟。

硬件设计原理图

在这里插入图片描述

硬件实现原理

音频是采用 TI 公司的 TLV320AIC23B 音频 Codec 芯片,TLV320AIC23B 支持 1 路 MICIN,1 路 LINEIN, 1 路OUT,1 路 HPOUT。硬件设计中将 1 路 LINEIN 和 1 路 HPOUT 通过接口引出,板载 1 个 MIC,连接芯片的 MICIN
接口。

BF533 处理器的 SPORT 接口支持 IIS 协和和 TDM 协议,可直接与 TLV320AIC23B 的接口连接。通过 BF53x处理器的 PF0 和 PF1 接口分别模拟 IIC 的 SCL 和 SDA 总线,用来初始化 TLV320AIC23B 芯片。

TLV320AIC23B 支持多种音频采样格式,硬件设计中为其提供的时钟为 12MHz,可参考 TLV320AIC23B 数据手册将其配置为 USB 模式采样。

在这里插入图片描述

硬件连接示意图

在这里插入图片描述

初始化配置

TLV320AIC23B 的器件地址可通过接口上的 CS 引脚进行选择,如下表:在这里插入图片描述

硬件中,将 CS 管脚接地,所以其使用的器件地址是:写器件:0x34 读器件:0x35

TLV320AIC23B 需要通过 IIC 接口配置初始化,所以需要通过配置板卡上的 CPLD 寄存器,将 PF0 和 PF1 配置为 IIC 总线模式,该配置映射在 CPLD 的 DEVICE_OE 寄存器,其配置功能为:

DEVICE_OE 寄存器(读/写):
DEVICE_OE 寄存器地址:0x20320000
DEVICE_OE 寄存器设置硬件设备上一些控制管脚的电平状态。
DEVICE_OE 寄存器位功能:

在这里插入图片描述

PF0_SET:PF0 模拟 IIC 总线 SCL 接口或 PF0 中断功能使能

1:关闭 I2C_SCL 输入信号, 使能 PF0 中断信号
0:使能 I2C_SCL 输入信号,关闭 PF0 中断信号

使用 IIC 配置 TLV320AIC23B 时,需将 PF0_SET 位设置为 0,关闭中断,待 IIC 配置完成后,再将中断 PF0_SET位设置为 1,将 PF0 中断功能打开。

代码实现功能

  1. bf53x_audio_talkthrough代码:

代码实现了一个音频输入播放的功能,将一个声源通过 LINEIN 接口(蓝色)输入,将一音响或耳机连接在HPOUT 接口(绿色),运行代码后,音响或耳机中能听到输入声源的声音。输入声源的音量不要太大,否则会产生
削波现象,导致听到的输出声音有爆破音。

  1. bf53x_audio_mic

代码实现了 MIC 输入播放的功能,将一音响或耳机连接在 HPOUT 接口(绿色),运行代码后,用手机或其他播放器对准板上 MIC 接口播放音乐,在音响或耳机中能听到输入声源的声音。

代码实现原理

  1. bf53x_audio_talkthrough

代码通过 IIC 初始化完 TLV320AIC23B 后,TLV320AIC23B 开始通过 LINEIN 接口采集模拟音频数据,并将采集到的数据通过 ADSP-BF53x 的 SPORT 口传送给 ADSP-BF53x,ADSP-BF53x 将数据做内存交换后,再通过 SPORT口传送给 TLV320AIC23B,TLV320AIC23B 将数据转为模拟信号后通过 HPOUT 接口输出。

  1. bf53x_audio_mic

代码通过 IIC 初始化完 TLV320AIC23B 后,TLV320AIC23B 开始通过板上 MIC 采集模拟音频数据,并将采集到的数据通过 ADSP-BF53x 的 SPORT 口传送给 ADSP-BF53x,ADSP-BF53x 将数据做内存交换后,再通过 SPORT口传送给 TLV320AIC23B,TLV320AIC23B 将数据转为模拟信号后通过 HPOUT 接口输出。

调试步骤

  1. bf53x_audio_talkthrough

1)将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好。
2)将正在播放的声源通过标准音频连接线接入开发板的 Lin IN 接口(蓝色接口)接入,音箱或耳机连接 HPOUT接口(绿色接口)。
3)先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
4)运行 VisualDSP++ 5.0 软件,选择合适的 BF533 的 session 将仿真器与软件连接。
5)加载 VisualDSP++ 5.0 工程文件 BF53x_AUDIO_TALKTHROUGH.dpj,编译并全速运行。

  1. bf53x_audio_mic

1)将仿真器(ICE)与 ADSP-EDU-BF53x 开发板和计算机连接好。
2)将正在播放的声源通过标准音频连接线接入开发板的 Lin IN 接口(蓝色接口)接入,音箱或耳机连接 HPOUT接口(绿色接口)。
3)先给 ADSP-EDU-BF53x 开发板上电,再为仿真器(ICE)上电。
4)运行 VisualDSP++ 5.0 软件,选择合适的 BF533 的 session 将仿真器与软件连接。
5)加载 VisualDSP++ 5.0 工程文件 BF53x_AUDIO_MIC.dpj,编译并全速运行。

调试结果

bf53x_audio_talkthrough

在音响或耳机中可以听到输入声源的声音。

bf53x_audio_mic

用手机或其他播放器播放音乐,对准板上 MIC,可从耳机中听到 MIC 采集到的音乐。

程序源码

  1. bf53x_audio_talkthrough

aic23b_init.c

#include <cdefBF533.h>
#include “i2c.h”
#include “aic23b.h”

#define AIC23B_ADDRESS 0x34
static i2c_device mcu_i2c;

void init_aic23b(void);
int aic23b_write(unsigned char addr, unsigned char dat);
int aic23b_read(unsigned char addr, unsigned char * buf);

unsigned short AudioConfig[] = {
PWDC, 0x000FF,
LLVC, 0x1d,
RLVC, 0x1d,
LHVC, 0x70,
RHVC, 0x70,
AAPC, DAC,
DAPC, 0,
PWDC, 0,
DAIF, MS|FOR|LRP,
SARC, 0,
DIAC, ACT|RES };

/****************************************************************************

  • 名称 :aic23b_write
  • 功能 : 写aic23b寄存器函数
  • 入口参数 :addr:寄存器偏移地址
    dat:寄存器配置值
  • 出口参数 :返回0
    ****************************************************************************/
    int aic23b_write(unsigned char addr, unsigned char dat)
    {
    int ret = -1;
    i2c_start(&mcu_i2c);
    if(i2c_write(&mcu_i2c, AIC23B_ADDRESS, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    if(i2c_write(&mcu_i2c, addr, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    i2c_write(&mcu_i2c, dat, 1);
    i2c_stop(&mcu_i2c);
    return 0;
    }

/****************************************************************************

  • 名称 :aic23b_read
  • 功能 : 读aic23b寄存器函数
  • 入口参数 :addr:寄存器偏移地址
    buf:寄存器读取数据缓存
  • 出口参数 :返回0
    ****************************************************************************/
    int aic23b_read(unsigned char addr, unsigned char * buf)
    {
    unsigned char *p = buf;
    int ret = -1;
    i2c_start(&mcu_i2c);
    //send slave address
    if(i2c_write(&mcu_i2c, AIC23B_ADDRESS, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    //send sub-address of slave
    if(i2c_write(&mcu_i2c, addr, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    i2c_stop(&mcu_i2c);
    i2c_start(&mcu_i2c);
    // send slave address (+1 read mode)
    if(i2c_write(&mcu_i2c, AIC23B_ADDRESS+1, 1)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    if(i2c_wait_slave(&mcu_i2c, 1000)){
    i2c_stop(&mcu_i2c);
    return ret;
    }
    i2c_read(&mcu_i2c, p++, 1); // send ack
    i2c_stop(&mcu_i2c);
    return 0;
    }

/****************************************************************************

  • 名称 :Init_aic23b
  • 功能 : 音频模块的内部初始化
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/

void init_aic23b(void)
{
unsigned char i;

mcu_i2c.sclk = PF0;         //时钟PF脚
mcu_i2c.sdata = PF1;        //数据PF脚
mcu_i2c.low_ns = 7000;      //低电平延时 ns
mcu_i2c.high_ns = 6000;     //高电平延时 ns	   i2c_init(&mcu_i2c);	aic23b_write(PWDC,0x000FF);   aic23b_write(LLVC,0x1d);    
aic23b_write(RLVC,0x1d);    
aic23b_write(LHVC,0xff);   
aic23b_write(RHVC,0xff);   aic23b_write(AAPC,DAC);aic23b_write(DAPC,0);    
aic23b_write(PWDC,0);aic23b_write(DAIF,MS|FOR|LRP);   aic23b_write(SARC,0);        aic23b_write(DIAC,ACT|RES);

}

cpu.c

#include <cdefBF533.h>
/**********************************************************************************

  • 名称 :Set_PLL
  • 功能 :初始化内核时钟和系统时钟
  • 入口参数 :pmsel pssel 设置参数
  • 出口参数 :无
    ***********/
    void Set_PLL(int pmsel,int pssel)
    {
    int new_PLL_CTL;
    pPLL_DIV = pssel;
    asm(“ssync;”);
    new_PLL_CTL = (pmsel & 0x3f) << 9;
    pSIC_IWR |= 0xffffffff;
    if (new_PLL_CTL != pPLL_CTL)
    {
    pPLL_CTL = new_PLL_CTL;
    asm(“ssync;”);
    asm(“idle;”);
    }
    }
    /
  • 名称 :Init_EBIU
  • 功能 :初始化并允许异步BANK存储器工作
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/

void Init_EBIU(void)
{
*pEBIU_AMBCTL0 = 0x7bb07bb0;
*pEBIU_AMBCTL1 = 0xffc07bb0;
*pEBIU_AMGCTL = 0x000f;
}

/****************************************************************************

  • 名称 :Init_SDRAM
  • 功能 :初始化SDRAM
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void Init_SDRAM(void)
    {
    *pEBIU_SDRRC = 0x00000817;
    *pEBIU_SDBCTL = 0x00000013;
    *pEBIU_SDGCTL = 0x0091998d;
    ssync();
    }

/****************************************************************************

  • 名称 : delay
  • 功能 : 延时函数
  • 入口参数 :无
  • 返回值 :无
    ****************************************************************************/
    void delay(unsigned int tem)
    {
    int i;
    for(i=0;i<tem;i++)
    asm(“nop;”);
    }

I2C.c

#include <cdefBF533.h>
#include “i2c.h”

#define CORE_CLK_IN 24 * 1000 * 1000

#define SET_PF(pf)
do{
*pFIO_FLAG_S = (pf);
ssync();
}while(0)

#define CLR_PF(pf)
do{
*pFIO_FLAG_C = (pf);
ssync();
}while(0)

#define SET_PF_OUTPUT(pf)
do{
*pFIO_INEN &= ~(pf);
*pFIO_DIR |= (pf);
ssync();
}while(0)

#define SET_PF_INPUT(pf)
do{
*pFIO_DIR &= ~(pf);
*pFIO_INEN |= (pf);
ssync();
}while(0)

int get_core_clk(void)
{
int tempPLLCTL;
int _DF;
int VCO;
int MSEL1;

tempPLLCTL = *pPLL_CTL;MSEL1 = ((tempPLLCTL & 0x7E00) >> 9);
_DF   =  tempPLLCTL & 0x0001;VCO  = MSEL1 * __CORE_CLK_IN__;
if(_DF == 1)VCO /= 2;return  VCO;

}
void delay_ns(unsigned int core_clock, unsigned long long count)
{
count *= core_clock;
count /= 1000000000;
while(count–);

}

int _get_sdata(i2c_device * dev)
{
return ((*pFIO_FLAG_D & dev->sdata) ? 1 : 0);
}

void i2c_init(i2c_device * dev)
{
dev->core_clock = get_core_clk();
dev->delay_ns = delay_ns;
*pFIO_DIR |= dev->sclk | dev->sdata;
ssync();
}

void i2c_deinit(i2c_device * dev)
{
dev->sclk = 0;
dev->sdata = 0;

*pFIO_DIR &=  ~(dev->sclk | dev->sdata);
ssync();

}

void i2c_start(i2c_device * dev)
{
SET_PF_OUTPUT(dev->sdata);
SET_PF_OUTPUT(dev->sclk);

SET_PF(dev->sdata);
SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->low_ns);CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

}

void i2c_stop(i2c_device * dev)
{
CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

SET_PF_OUTPUT(dev->sdata);
CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->low_ns);SET_PF_INPUT(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns);

}

int i2c_read_ack(i2c_device * dev)
{
int ret = 0;

SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/3);SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns/3);ret = _get_sdata(dev);delay_ns(dev->core_clock, dev->high_ns/3);
CLR_PF(dev->sclk);delay_ns(dev->core_clock, dev->low_ns);SET_PF_OUTPUT(dev->sdata);
return ret;

}

int i2c_wait_slave(i2c_device * dev, unsigned int time_out)
{
int ret;
int count = time_out * 2 / dev->high_ns;

SET_PF_INPUT(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns/2);do{ret = *pFIO_FLAG_D & dev->sclk;if(ret)break;delay_ns(dev->core_clock, dev->high_ns/2);
}while(count--);SET_PF_OUTPUT(dev->sclk);
return !ret;

}

void i2c_write_ack(i2c_device * dev)
{
SET_PF_OUTPUT(dev->sdata);
CLR_PF(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/2);
SET_PF(dev->sclk);
delay_ns(dev->core_clock, dev->high_ns);

CLR_PF(dev->sclk);
delay_ns(dev->core_clock, dev->low_ns);

}

int i2c_write(i2c_device * dev, unsigned char value, int need_ack)
{
int ret = -1;
unsigned char index;

SET_PF_OUTPUT(dev->sdata);//send 8 bits to slave
for(index = 0; index < 8; index++){//send one bit to the i2c busif((value<<index) & 0x80){SET_PF(dev->sdata);} else {CLR_PF(dev->sdata);}delay_ns(dev->core_clock, dev->low_ns/2);SET_PF(dev->sclk);delay_ns(dev->core_clock, dev->high_ns);CLR_PF(dev->sclk);delay_ns(dev->core_clock, dev->low_ns/2);
}if(need_ack){ret = i2c_read_ack(dev);
}
return ret;

}

int i2c_read(i2c_device * dev, unsigned char * value, int send_ack)
{
unsigned char index;
*value = 0x00;

SET_PF_INPUT(dev->sdata);
delay_ns(dev->core_clock, dev->high_ns/2);//get 8 bits from the device
for(index = 0; index < 8; index++){SET_PF(dev->sclk);delay_ns(dev->core_clock, dev->high_ns/2);*value <<= 1;*value |= _get_sdata(dev);delay_ns(dev->core_clock, dev->high_ns/2);CLR_PF(dev->sclk);delay_ns(dev->core_clock, dev->low_ns);
}// send ack to slave
if(send_ack){i2c_write_ack(dev);
}
return *value;

}

main.c

void main()
{
Set_PLL(16,4);
Init_EBIU();
Init_SDRAM();
IIC_Enable();

init_aic23b();
Init_Interrupts();
Init_Sport0();
Init_DMA();
Enable_DMA_Sport0();while(1); 

}

talkthrough.c

#include <cdefBF533.h>
#include <sys\exception.h>

#define TIMOD_DMA_TX 0x0003 // SPI transfer mode
#define SLEN_32 0x001f // SPORT0 word length
#define FLOW_1 0x1000 // DMA flow mode

#define INTERNAL_ADC_L0 0
#define INTERNAL_ADC_R0 2
#define INTERNAL_DAC_L0 0
#define INTERNAL_DAC_R0 2
#define INTERNAL_ADC_L1 1
#define INTERNAL_ADC_R1 3
#define INTERNAL_DAC_L1 1
#define INTERNAL_DAC_R1 3

EX_INTERRUPT_HANDLER(Sport0_RX_ISR);

int iChannel0LeftIn, iChannel1LeftIn;
int iChannel0RightIn, iChannel1RightIn;
int iChannel0LeftOut, iChannel1LeftOut;
int iChannel0RightOut, iChannel1RightOut;

volatile int iTxBuffer1[4];
volatile int iRxBuffer1[4];
/****************************************************************************

  • 名称 :Init_Timers
  • 功能 :初始化TIMER0 为PWM模式。
  • 入口参数 :无
  • 出口参数 :无
    ****************************************************************************/
    void Init_Timers(void)
    {
    *pTIMER0_CONFIG = 0x0019;
    *pTIMER0_PERIOD = 0x00800000;
    *pTIMER0_WIDTH = 0x00400000;
    *pTIMER_ENABLE = 0x0001;
    }

void Init_Sport0(void)
{
*pSPORT0_RCR1 = RFSR | RCKFE;
*pSPORT0_RCR2 = RSFSE |SLEN_32;

*pSPORT0_TCR1 = TFSR| LATFS | TCKFE;
*pSPORT0_TCR2 = TSFSE | SLEN_32;	

}

void Init_DMA(void)
{
*pDMA1_PERIPHERAL_MAP = 0x1000;
*pDMA1_CONFIG = WNR | WDSIZE_32 | DI_EN | FLOW_1;
*pDMA1_START_ADDR = (void *)iRxBuffer1;
*pDMA1_X_COUNT = 4;
*pDMA1_X_MODIFY = 4;

*pDMA2_PERIPHERAL_MAP = 0x2000;
*pDMA2_CONFIG = WDSIZE_32 | FLOW_1;
*pDMA2_START_ADDR = (void *)iTxBuffer1;
*pDMA2_X_COUNT = 4;
*pDMA2_X_MODIFY = 4;

}

void Enable_DMA_Sport0(void)
{
*pDMA2_CONFIG = (*pDMA2_CONFIG | DMAEN);
*pDMA1_CONFIG = (*pDMA1_CONFIG | DMAEN);

*pSPORT0_TCR1 	= (*pSPORT0_TCR1 | TSPEN);
*pSPORT0_RCR1 	= (*pSPORT0_RCR1 | RSPEN);

}

void Init_Interrupts(void)
{
*pSIC_IAR0 = 0xffffffff;
*pSIC_IAR1 = 0xffffff2f;
*pSIC_IAR2 = 0xffffffff;

register_handler(ik_ivg9, Sport0_RX_ISR);*pSIC_IMASK = 0x00000200;

}

void Process_Data(void)
{
iChannel0LeftOut = iChannel0LeftIn;
iChannel0RightOut = iChannel0RightIn;
iChannel1LeftOut = iChannel1LeftIn;
iChannel1RightOut = iChannel1RightIn;
}

EX_INTERRUPT_HANDLER(Sport0_RX_ISR)
{
*pDMA1_IRQ_STATUS = 0x0001;

iChannel0LeftIn = iRxBuffer1[INTERNAL_ADC_L0];
iChannel0RightIn = iRxBuffer1[INTERNAL_ADC_R0];
iChannel1LeftIn = iRxBuffer1[INTERNAL_ADC_L1];
iChannel1RightIn = iRxBuffer1[INTERNAL_ADC_R1];Process_Data();	iTxBuffer1[INTERNAL_DAC_L0] = iChannel0LeftOut;
iTxBuffer1[INTERNAL_DAC_R0] = iChannel0RightOut;
iTxBuffer1[INTERNAL_DAC_L1] = iChannel1LeftOut;
iTxBuffer1[INTERNAL_DAC_R1] = iChannel1RightOut;

}

这篇关于ADI Blackfin DSP处理器-BF533的开发详解17:IIS+AUDIO音频codec的应用(含源代码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/226022

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#