stm32 硬件spi半双工三线的一些研究心得

2023-05-16

a7105可以使用四线spi,或者3线spi, 但是之前都是使用3线的软件模拟的三线spi的,所以不想改其它代码了,就想可以提高一个spi的读写速度,原来软件方式的读写速度,在48Mhz的03x下面,大约速度是1.6mbs,使用硬件spi之后,最终大约速度为12mbs. 

     为了令它可以稳定工作,这个还是花了不了时间了。主要的挑战是因为是使用3线spi,情况有些特殊,我们需要使用MOSI一条数据线实现主和从的双向模式通信。根据文档,我们使用进行以下设置

1. SPIx->CR1 的 BIDIMODE 设置为1,表示启用双向模式

2. 使用SPIX->CR1的BIDIOE 来控制方向,0表示当前为Master读数据,1表示当前为Master写数据

3. 更换这个方向时需要把SPIx禁用, SPIX->CR1的SPE,来控制。

这个总体思路是这样的,我实际编写完代码,发现是完全不工作的,网上也比较少这样的使用,有少数几个文章有说这个。

根据文档,在BIDIMODE 为1,BIDIOE为0, 时钟CLK在SPE马上开启输出,同时它只会在SPE为零时才会停,这个意味着,我们要依赖于Slave的处理速度,当时也依赖而自己准确开关这个CLK信号,否则这个读出来的数据就会错乱。

        这时需要一个比较慢的速度才可以稳定,最开始我并没有注意到这个,在    spiInit.SPI_BaudRatePrescaler 小于 SPI_BaudRatePrescaler_128时,要不读取全是时,要不出现一开始是对的,读着读着,数据就是错的,最后读出来全零的情况。只能不断的降低读写速度。最后才能稳定无误。但是128分频后,明显比软件模拟的方式还慢,这个就没有价值了。这个代码如下:

void spi_init()
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);


	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;


	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |  GPIO_Pin_15;
	

	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0); 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);

	SPI_I2S_DeInit(SPI1);
	spiInit.SPI_Direction = SPI_Direction_1Line_Tx;
	spiInit.SPI_Mode = SPI_Mode_Master;
	spiInit.SPI_DataSize  = SPI_DataSize_8b;
	spiInit.SPI_CPOL  = SPI_CPOL_Low;
	spiInit.SPI_CPHA = SPI_CPHA_1Edge;
	spiInit.SPI_NSS = SPI_NSS_Soft;
	spiInit.SPI_BaudRatePrescaler= SPI_BaudRatePrescaler_128;
	spiInit.SPI_FirstBit  = SPI_FirstBit_MSB;
	spiInit.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1, &spiInit);
	
	SPI_SSOutputCmd(SPI1,DISABLE);
	  
	//NSS
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	SPI_TIModeCmd(SPI1,DISABLE);
	SPI_NSSPulseModeCmd(SPI1,DISABLE);
	SPI_Cmd(SPI1,ENABLE);
}

void Rf_Spi_Write_Byte(uint8_t dat)
{
	if(!g_bisTx)
	{
		
		  SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI
    	  SPI1->CR1 |= SPI_Direction_Tx;
    	g_bisTx=1;
	}

	 *(uint8_t*)&SPI1->DR = dat;
    SPI1->CR1 |= SPI_CR1_SPE; //ENABLE SPI


   // while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) != RESET){}
    //SPI_SendData8(SPI1,dat);
   
	while(!(SPI1->SR & SPI_I2S_FLAG_TXE)){}
	while (SPI1->SR &  SPI_I2S_FLAG_BSY){}
   
	 SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
 


}

uint8_t Rf_Spi_Read_Byte(void)
{
#if USE_HARDWARE_SPI

	uint8_t dat =0;

	if(g_bisTx)
    {
	    SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI
	    SPI1->CR1 &= SPI_Direction_Rx;
	     /* Clear FRXTH bit */
		SPI1->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
		/* Set new FRXTH bit value */
		SPI1->CR2 |= SPI_RxFIFOThreshold_QF;  //SET IT 8 BIT per READ, THAT is QUETER OF 32BIT
	    
	}
	SPI1->CR1 |= SPI_CR1_SPE; //ENABLE SPI
 	g_bisTx=0;

     while (!(SPI1->SR &  SPI_I2S_FLAG_RXNE)  ) ; // wait data received
     SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI
	 dat = *(uint8_t*)&SPI1->DR;

	return dat;

}

        这个根据工作原理分析了一下,为什么在这样,主要是因为我们的读的时候,要是这个速度高,我们的mcu还没有去禁用SPI停时钟这个太慢了,上面代码已经在判断到RXNE时马上disable SPI了,但是明显,这个还是不够快。怎么办? 如何能提高速度? 这个折腾了很久,终于发现一个不合理的操作可以直接把速度成 DIV4,即12MB。这个就是先禁用SPI,  再判断RXNE...发现竟然是可以很稳定的工作。


	SPI1->CR1 |= SPI_CR1_SPE; //ENABLE SPI
g_bisTx=0;
     SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI

     while (!(SPI1->SR &  SPI_I2S_FLAG_RXNE)  ) ; // wait data received
	 dat = *(uint8_t*)&SPI1->DR;

这个确实也是神奇,特别写这个文章记录一下。

归纳的原理应该是SPI ENABLE就开始读了,这ENABLE和DISALBE的时间刚好就是12MB的速度,多一条指令都不行了。

同时也尝试了使用DMA去加速,但是同样因为这个时钟刹车停止问题,使用DMA时实际测试需要更慢才能稳定传输,也要去到SPI_BaudRatePrescaler_128。究其原因应该也是DMA停止时操作太多,无法简化,导致时钟无法及时停止,引起数据错误。

以下是三线SPI的DMA传输的代码,供参考。

void Rfchip_Spi_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure={0};

	
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);


	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;


	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 |  GPIO_Pin_15;
	

	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_0); 
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_0);

	SPI_I2S_DeInit(SPI1);
	spiInit.SPI_Direction = SPI_Direction_1Line_Tx;
	spiInit.SPI_Mode = SPI_Mode_Master;
	spiInit.SPI_DataSize  = SPI_DataSize_8b;
	spiInit.SPI_CPOL  = SPI_CPOL_Low;
	spiInit.SPI_CPHA = SPI_CPHA_1Edge;
	spiInit.SPI_NSS = SPI_NSS_Soft;
	spiInit.SPI_BaudRatePrescaler= SPI_BaudRatePrescaler_128;
	spiInit.SPI_FirstBit  = SPI_FirstBit_MSB;
	spiInit.SPI_CRCPolynomial = 7;
	SPI_Init(SPI1, &spiInit);
	
	SPI_SSOutputCmd(SPI1,DISABLE);
	  
	//NSS
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	SPI_TIModeCmd(SPI1,DISABLE);
	SPI_NSSPulseModeCmd(SPI1,DISABLE);


    DMA_DeInit(DMA1_Channel2);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
	DMA_InitStructure.DMA_MemoryBaseAddr = 0;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	DMA_InitStructure.DMA_BufferSize = 0;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel2, &DMA_InitStructure);


    DMA_DeInit(DMA1_Channel3);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = 0;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = 0;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel3, &DMA_InitStructure);




	SPI_Cmd(SPI1,ENABLE);



	//GIO
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	RFChip_Disable;
}



void Rf_Spi_Write_Bytes(uint8_t *pbuf, uint32_t len)
{

	if(!g_bisTx)
	{
		
		  SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI
    	  SPI1->CR1 |= SPI_Direction_Tx;
    	g_bisTx=1;
	}

    DMA_Cmd(DMA1_Channel3,DISABLE);

	DMA1_Channel3->CMAR = (uint32_t)pbuf;
    DMA1_Channel3->CNDTR = len;
    DMA_Cmd(DMA1_Channel3,ENABLE);
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,ENABLE);
    SPI1->CR1 |= SPI_CR1_SPE; //ENABLE SPI
    while(DMA_GetFlagStatus(DMA1_FLAG_TC3)==RESET);
    DMA_ClearFlag(DMA1_FLAG_TC3);
    SPI_I2S_DMACmd(SPI1,SPI_I2S_DMAReq_Tx,DISABLE);

    while (SPI1->SR &  SPI_I2S_FLAG_BSY){}
	
	SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);
	DMA_Cmd(DMA1_Channel3,DISABLE);
	
 


}

void Rf_Spi_Read_Bytes(uint8_t *pbuf, uint32_t len)
{

	uint16_t Dis_SPI_CR1_SPE=(uint16_t)~((uint16_t)SPI_CR1_SPE);
	uint16_t dMA_DISABLE =  (uint16_t)(~DMA_CCR_EN);
	if(g_bisTx)
    {
	    SPI1->CR1 &= (uint16_t)~((uint16_t)SPI_CR1_SPE);//DISABLE SPI
	    SPI1->CR1 &= SPI_Direction_Rx;
	     /* Clear FRXTH bit */
		SPI1->CR2 &= (uint16_t)~((uint16_t)SPI_CR2_FRXTH);
		/* Set new FRXTH bit value */
		SPI1->CR2 |= SPI_RxFIFOThreshold_QF;  //SET IT 8 BIT per READ, THAT is QUETER OF 32BIT
	    
	}
	g_bisTx=0;
    DMA1_Channel2->CCR &= dMA_DISABLE;  //DISABLE DMA CHANNEL2
	DMA1_Channel2->CMAR = (uint32_t)pbuf;
    DMA1_Channel2->CNDTR = len;
    SPI1->CR2 |= SPI_I2S_DMAReq_Rx; //DMA REQUEST
    SPI1->CR1 |= SPI_CR1_SPE; //ENABLE SPI
    DMA1_Channel2->CCR |= DMA_CCR_EN; //ENABLE DMA CHANNEL2

    while(!(DMA1->ISR & DMA1_FLAG_TC2));
     DMA1_Channel2->CCR &=dMA_DISABLE;  //DISABLE DMA CHANNEL2

    SPI1->CR1 &= Dis_SPI_CR1_SPE;//DISABLE SPI

    SPI1->CR2 &= (uint16_t)~SPI_I2S_DMAReq_Rx;

    DMA_ClearFlag(DMA1_FLAG_TC2);
    

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32 硬件spi半双工三线的一些研究心得 的相关文章

  • SiamFC代码配置复现

    写在前面 最近在研究SiamRPN xff0c 究其根本 xff0c CNN依托于AlexNet骨架 xff0c 所以花些功夫研究以下SiamFC代码 xff0c 将其阶段性复现 Tracking only 关于GPU显卡配置 cudn和c
  • PySOT

    写在前面 期待已久的PySOT终于放上了code xff0c 高兴ing xff0c 赶忙进行相应的配置加以复现 xff0c 不得不说 xff0c 作者真的很贴心 xff0c 把配置环境的指令封装成脚本 xff0c 直接按需配置即可 但是在
  • 【Linux】SocketCan c语言编程

    前言 为了能够对Socket CAN的深入理解 xff0c 我们需要了解Socket的机制 Socket的中文翻译为 插座 xff0c 在计算机世界里称为套接字 Socket最初是作为网络上不同主机之间进程的通信接口 xff0c 后来应用越
  • VMWare虚拟机网络配置及虚拟机远程rviz显示雷达数据

    虚拟机网络配置 1 工具 环境 本机 xff1a Windows 10 64位虚拟机 xff1a VMware Workstation xff0c Ubuntu 18 04 2 Windows配置 WLAN部分 网络和Internet配置
  • 2022数学建模国赛B题思路分析

    分享一下 xff0c 仅供参考借鉴 xff0c 切勿直接使用 xff01 致谢一下全糖奶茶屋 xff01 一 问题重述 1 1 问题背景 由于无人机集群在遂行编队飞行时 应尽可能的避免外界干扰 因此需要尽可能的保持电磁静默减少电磁波信号的发
  • 利用Visual Studio创建C语言dll

    利用VS2019创建dll方法 动态链接库的定义及意义如何在VS创建dll入口函数DLLMain如何创建导出函数动态调用导出函数 动态链接库的定义及意义 动态链接库 xff08 Dynamic Link Library 或者 Dynamic
  • Human-in-the-Loop Optimization of Exoskeleton Assistance Via Online Simulation of Metabolic Cost

    Human in the Loop Optimization of Exoskeleton Assistance Via Online Simulation of Metabolic Cost 文章来源https ieeexplore ie
  • Dynamical Movement Primitives (DMP) 总结

    Dynamical Movement Primitives DMP 总结 概述 DMP通过将动态系统建立为 弹簧阻尼系统 43 非线性控制项的方式 f f f xff0c 实现了对示教数据的建模 具体贡献如下 xff1a 提供了一种简单的非
  • Probabilistic Movement Primitives (ProMP) 总结

    概述 文章通过在DMP的基础上增加随机项 xff0c 并通过EM算法求解得到符合示教数据的参数 一 模型介绍 1 系统方程 假设示教数据为 61 q t
  • 一些有用的数学定理

    法托引理 xff08 Fatou Theorem xff09 设 f n f n f n 是非负可测函数 xff0c 那么
  • 爬取需要登录的网站

    爬虫在采集网站的过程中 xff0c 部分数据价值较高的网站 xff0c 会限制访客的访问行为 这种时候建议通过登录的方式 xff0c 获取目标网站的cookie xff0c 然后再使用cookie配合代理IP进行数据采集分析 1 使用表单登
  • Makefile和Cmake的联系与区别

    CMake是一种跨平台编译工具 xff0c 比make更为高级 xff0c 使用起来要方便得多 CMake主要是编写CMakeLists txt文件 xff0c 然后用cmake命令将CMakeLists txt文件转化为make所需要的m
  • STM32内部寄存器、储存器、C对寄存器的封装

    STM32内部寄存器 储存器 C对寄存器的封装 STM32的地址空间可以分为8个 xff0c 分别是Block0 Block7 xff0c 其中Block2是应用于外设的存储器 xff0c 也是主要学习的内容 存储器映射 存储器的地址由厂商
  • C++ STL中各种数据结构操作的时间复杂度比较

    C 43 43 STL中各种数据结构操作的时间复杂度比较 访问push back push front insert pop back pop front erace find listO n O 1 O 1 O 1 O 1 O 1 O 1
  • pom.xml 标签详解

    lt project xmlns 61 34 http maven apache org POM 4 0 0 34 xmlns xsi 61 34 http www w3 org 2001 XMLSchema instance 34 xsi
  • 解决“打开ArcGIS Server Manager”网页无反应为空白的情况

    问题 xff1a 装上arcgis serve 10后 xff0c 打开arcgis server manager页面返回空白 xff0c 用firefox显示 未找到元素 郁闷 xff0c 后来想尽各种办法 终于可以了 解决办法 xff1
  • 汇编语言教程-返回指令(RET)

    汇编语言教程 返回指令 RET 当子程序执行完时 xff0c 需要返回到调用它的程序之中 为实现此功能 xff0c 指令系统提供了一条专用的返回指令 其格式如下 xff1a RET RETN RETF Imm 子程序的返回在功能上是子程序调
  • 富斯/MC6接收机说明书

    正面 反面 1 PWM输出通道多达6个 xff0c 可以自由切换7种模式 xff0c 自由选择无刷 xff0c 有刷 xff0c 差速 xff0c 炫酷的RGB全彩灯带等 xff0c 自由玩耍 2 集成两个5A有刷电调 xff0c 通过模式
  • C++之struct构造函数(2010-10-19 15:04:47)

    C 43 43 之struct构造函数 2010 10 19 15 04 47 转载 标签 xff1a cpp struct 构造函数 校园 分类 xff1a C C PlusPlus 在网络协议 通信控制 嵌入式系统的C C 43 43
  • 汉字转拼音

    原创的兄弟 xff0c 看来是费了不少功夫 在此谢过了 代码如下 xff1a public class hanzi to pinyin1 private static readonly string Allhz 61 new string

随机推荐

  • 什么是功能性需求和非功能性需求

    需求定义 xff1a 需求 xff08 requirement xff09 就是系统 xff08 更广义的说法是项目 xff09 必须提供的能力和必须遵从的条件 需求分类 xff1a 1 在一般使用中 xff0c 需求按照功能性 xff08
  • 卷三、七言古诗

    卷三 七言古诗 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 登幽州台歌 作者 xff1a 陈子昂 前不见古人
  • 卷五、五言律诗

    卷五 五言律诗 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 经邹鲁祭孔子而叹之 作者 xff1a 唐玄宗 夫子
  • 卷六、七言律诗

    61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 黄鹤楼 作者 xff1a 崔颢 昔人已乘黄鹤去 xff0c 此地空
  • 计算两个经纬度间的距离(c++)

    double D jw double wd1 double jd1 double wd2 double jd2 double x y out double PI 61 3 14159265 double R 61 6 371229 1e6
  • C语言库函数及示例

    函数名 abort 功 能 异常终止一个进程 用 法 void abort void 程序例 include lt stdio h gt include lt stdlib h gt int main void printf 34 Call
  • Json风格指南

    英文版 xff1a http google styleguide googlecode com svn trunk jsoncstyleguide xml 翻译 xff1a Darcy Liu 简介 该风格指南是对在Google创建JSON
  • C中__FILE__ __LINE__的用法

    include lt stdio h gt void main void printf 34 File s Successfully reached line d n 34 FILE LINE Other statements here l
  • MC6C迈克/FLYSKY富斯/WFLY2天地飞二代接收机远程刷固件教程

    1 安装ch341的驱动程序 请找ch341卖家要或百度找 2 ch341的跳线跳到usb To ttl 如能本身只有TTL刷机的功能的板子 xff0c 像CH340一般只有usb to ttl的功能 xff0c 这一步可以不做 3 接收机
  • STM32入门系列-使用C语言封装寄存器

    前面介绍了存储器映射 寄存器和寄存器映射 xff0c 这些都是为了介绍使用 C语言封装寄存器做铺垫 这里我们通过一个实例来对 C 语言封装寄存器进行介绍 具体实例 xff1a 控制 GPIOC 端口的第 0 管脚输出一个低电平 首先我们需要
  • *** buffer overflow detected ***异常

    一次在linux上编译程序报错 xff1a buffer overflow detected TAppEncoderStaticSADBS terminated 排查原因发现是sprintf读取时数组长度不够 xff0c 将数组长度由50增
  • 利用火狐浏览器脚本功能_充分利用Firefox

    利用火狐浏览器脚本功能 Firefox 0 8的发布消息是凤凰网 Firebird Mozilla浏览器系列中的最新版本 xff0c 目前 xff0c Web开发社区对此感到非常关注 该发行版标志着Mozilla项目独立浏览器的第三个也是最
  • 串口接收无定长数据

    1 原理 xff1a 1 使能串口接收中断 定时器中断 xff1b 2 在串口第一次进入到中断后 xff0c 使能定时器计时 xff1b 3 在串口每次进入中断后 xff0c 清空定时器 xff1b 4 当定时器溢出时 xff0c 判定数据
  • OpenWRT 小记

    查看openwrt内核版本 xff1a cat proc version uname r 生成配置文件 xff1a config generate 查看DHCH 已经分配的IP cat var dhcp leases 分割cat tmp d
  • OpenWrt OpenMPTCProuter feed

    echo 34 src git OpenMPTCProuter https github com Ysurac openmptcprouter feeds git 34 gt gt feeds conf default echo 34 sr
  • openwrt路由器接华为E3372(E8372)网卡实现4G转有线和WIFI

    Hilink 在openwrt系统中安装kmod usb net rndis kmod usb net kmod usb2 usb modeswitch kmod usb net cdc ether 安装完成后 xff0c 把E3372 x
  • windows 10 内存居高不下,实际没开多少进程

    windows 10 内存居高不下 xff0c 实际没开多少进程 关闭快速启动 就好了
  • opkg list 报错

    opkg list Collected errors opkg conf load Could not lock var lock opkg lock Resource temporarily unavail echo 34 nameser
  • openwrt opkg install 强制替换安装

    查询 opkg list installed grep XXX opkg install XXX ipk force downgrade
  • stm32 硬件spi半双工三线的一些研究心得

    a7105可以使用四线spi 或者3线spi 但是之前都是使用3线的软件模拟的三线spi的 xff0c 所以不想改其它代码了 xff0c 就想可以提高一个spi的读写速度 xff0c 原来软件方式的读写速度 xff0c 在48Mhz的03x