stm32f103读取电子罗盘数据
前几天接到了一个任务,用stm32f103的串口读取电子罗盘(北微姿态传感器)的数据,其实也就三个,PITCH,ROLL,HEADING三个方向上的角度,顺带复习了一下串口知识。
个人觉得熟悉一下串口协议还是很重要的,刚开始学习的时候跟着原子的视频学习还是学习的很认真的,奈何但是是为了比赛速成,所以看完视频就直接用原子的例程了,久而久之不太清楚串口通信的具体实现过程了,就知道怎么使用原子的串口例程。
下面我们先来回顾一下串口的通信例程(已经会的大佬请略过)
其实串口说到底就是一个通信工具,也就是说就是两个模块之间传输数据用的工具,那么传输数据,最重要的两个方面就是发送数据和接收数据这两个方面了,所以,我们今天也就着重从这两个方面来讲讲串口通信。
在开始之前,我觉得有个串口通信的框图我们有必要先了解一下,不要求完全看懂,但至少需要了解一些。
其实最重要的就是两(仅对于发送而言,接收同理的也是两个)
一、USARTx->SR(状态寄存器)
就如图上所说的,控制寄存器主要就是一些使能位以及一些中断标志位,咱们可以看看参考手册,用手册说话
显然,这个寄存器中很多都是一些中断标志位。
二、USARTX->DR(数据寄存器)
可以看出,数据寄存器只有八位有效位,所以咱们串口的数据是一字节一字节(8位)传输的。
关于数据寄存器,还有一个要注意的地方大家一定要注意。大家看数据手册。
也就是说,串口发送与接收的寄存器其实是两个寄存器,一个是TDR寄存器,一个是RDR寄存器(其实我感觉就是一个寄存器,只不过不同时候用处不一样而已,大家可以在MDk中找到USART_TypeDef这个结构体去看看定义,所以这个知识点我觉得有可能是我没有理解手册的意思),但是很爽的是我们在单片机里头的操作一概都是USARTx->DR=0x某某;
下面咱们来看看具体的收发过程
发送
显然,按照参考手册上说的,只需要向USARTx->DR中写数据数据就会自动发送,发送完了,SR寄存器的相应的标志就会置位。我们也可以设置相应的中断。这是单字节发送,在这个基础上,我们也可以非常轻松地实现多字节发送。下面是多字节发送程序。
/************************************************************ 函数功能:连续发送数据 函数参数 u8 *data 发送数据数组首元素地址times 发送数据字节数 ·µ»ØÖµ £º void ************************************************************/ void constant_send(u8 *data,u8 times) {int i;for(i=0;i<times;i++){ while((USART2->SR&0X80)==0);USART2->DR=*(data++);} }
接收
咱们继续看数据手册,,,这东西确实是个好东西,有耐心一定可以学到很多东西的
从上面可以看出来,我们接收数据也是直接读取DR寄存器就行,我们读取串口接收到的数据一般使用串口接收中断(USART_IT_RXNE),取数据的时候,中断标志位就自动清除了,所以在中断处理函数中我们不用调用清除中断标志位的函数。
接收中断还有个中断我觉得很有必要了解一下,在接受不定长数组中很有作用——USART_IT_IDLE(帧中断),帧中断是检测传输过程中的数据断流,当一组数据传输完成之后,才会进入中断。这样,我们就能很方便接收不定长数据了。下面附上代码
我的协议的代码。
void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //使能usart2的时钟//USART1//2_TX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_2; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1/2_RX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_3;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1/2 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
//使能初始化以及中断设置usart1USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断 USART_Cmd(USART1, ENABLE); //使能串口1 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
//使能初始化以及中断设置usart2USART_Init(USART2, &USART_InitStructure); //初始化串口2USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_ITConfig(USART2,USART_IT_IDLE,ENABLE); //使能串口帧中断 帧中断寄存器的清除,,先读SR寄存器,在读DR寄存器USART_Cmd(USART2, ENABLE); //使能串口2
}void USART1_IRQHandler(void) //串口1中断服务程序{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾){printf("ha\n"); Res =USART_ReceiveData(USART1); //读取接收到的数据if((USART1_RX_STA&0x8000)==0)//接收未完成{if(USART1_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始else USART1_RX_STA|=0x8000; //接收完成了 }else //还没收到0X0D{ if(Res==0x0d)USART1_RX_STA|=0x4000;else{USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ;USART1_RX_STA++;if(USART1_RX_STA>(USART_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收 } }} } }
/***************************************************************************************************************
函数功能:串口2接收中断函数
入口参数:void
返回值:void
***************************************************************************************************************/
void USART2_IRQHandler(void) //串口1中断服务程序{u8 clear=clear;if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //等待接收中断{USART2_RX_BUF[recount++]=USART_ReceiveData(USART2);}if(USART_GetITStatus(USART2,USART_IT_IDLE)!=RESET){clear=USART2->SR;clear=USART2->DR;ReceiveState=1;}
}
#endif
/************************************************************
函数功能:连续发送数据
函数参数:*data u8类型指针,代表要发送的数据数组第一个数的地址times 循环次数
返回值 : void
************************************************************/
void constant_send(u8 *data,u8 times)
{int i;for(i=0;i<times;i++){ while((USART2->SR&0X80)==0);USART2->DR=*(data++);}
}
///以下为获取传感器数据相关函数/
/**************************************************************
函数功能:获取PITCH角度值
入口参数:void
返回值: void
描述:发送 77 04 00 01 05(16进制),传感器返籶pitch叵喙厥荩菸辉诘谒奈辶纸冢咛寮蔽⑼ㄐ判?
**************************************************************/
void get_pitch(void)
{u16 data=data; //这样子的作用可以排除没有使用的警告command_string[0]=0x77;command_string[1]=0x04;command_string[2]=0x00;command_string[3]=0x01;command_string[4]=0x05;constant_send(command_string,5); //循环发送,直到发送完毕 while(1){if(ReceiveState==1){data=(USART2_RX_BUF[4]&0x0f)*10000; //百位,这儿其实都是乘了100倍换成整数提高代码的效率,同时可以防止一次一次转化成浮点数带来的精度损失的问题data=data+(USART2_RX_BUF[5]&0xf0>>4)*1000+(USART2_RX_BUF[5]&0x0f)*100; data=data+(USART2_RX_BUF[6]&0xf0>>4)*10+(USART2_RX_BUF[6]&0x0f);direction_angles[0]=(data*1.0)/100;if((USART2_RX_BUF[4]&0xf0)==0x10)direction_angles[0]=-direction_angles[0];ReceiveState=0;recount=0; break; }}
}
关于串口收发,手册上还提供了一个更好的方法,用DMA通道(前提是支持DMA)直接进行数据传输。用DMA好处是为CPU减负,在要在开始和结束的阶段CPU参与一下就行,中间的数据传输阶段完全不用CPU参与,此时CPU可以去做其他事情。
关于串口DMA收发,我就写一下收发的要点
发送
1、初始化DMA通道(大家可以去参考原子的教程),使能串口DMA通道(这个容易忘记)
2、打开对应DMA的传输完成中断
3、在DMA的传输模式中,我们选择的是单次模式而不是循环模式,那么,我们如何重新开始发送数据呢,大家看手册。
手册上面说的很明白,我们先失能DMA对应的通道(只有先失能才能更改相应设置),然后重新写入需要传输的字节数,然后打开通道,对于接收而言也是同样的。
接收
1、初始化DMA通道(大家可以去参考原子的教程),使能串口DMA通道(这个容易忘记)
2、对于接收不定长数据,我们不能使用DMA通道的传输完成中断,因为数组的不定长,有可能会使DMA不能产生传输完成中断,这个时候,我们可以使用定时器超时中断,不过建议使用串口接收帧中断。
3、如何重新初始化接收和初始化发送是一样的
下面附上代码
void usart2_Init(u32 bound)
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO0A时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); //使能串口2时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.2GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.2//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART2, &USART_InitStructure); //初始化串口1USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//开启串口接受帧中断USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);USART_Cmd(USART2, ENABLE); //使能串口1
}
/**************************************************
函数功能:串口2的DMA初始化
函数参数:void
函数返回值:void
**************************************************/
void usart2_dma(void)
{DMA_InitTypeDef usart2dma;NVIC_InitTypeDef DMA_NVIC; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA1的时钟//中断配置 DMA_NVIC.NVIC_IRQChannel=DMA1_Channel7_IRQn; //DMA1发送完成中断DMA_NVIC.NVIC_IRQChannelPreemptionPriority=1; //抢占优先级为最高优先级DMA_NVIC.NVIC_IRQChannelSubPriority=0;DMA_NVIC.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&DMA_NVIC); //根据指定的参数初始化VIC寄存器
//设置USART-DMA的接收 DMA_DeInit(DMA1_Channel6); //USART2的接收DMA设置成缺省位 usart2dma.DMA_PeripheralBaseAddr=(u32)(USART2->DR); //外设基地址 //在指针面前加一个(u32),数据类型的强制转化,把指针类型的数据转化成u32usart2dma.DMA_MemoryBaseAddr=(u32)USART2_RX_BUF; //内存基地址usart2dma.DMA_DIR=DMA_DIR_PeripheralSRC; //外设到内存usart2dma.DMA_BufferSize=20; //一次传输10字节usart2dma.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址不变,一直为USART2;usart2dma.DMA_MemoryInc=DMA_MemoryInc_Enable; //内存地址增加usart2dma.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; //外设字节传输usart2dma.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte; //内存字节传输usart2dma.DMA_Mode=DMA_Mode_Normal; //不采用循环采集的模式,采集一次便可,需要的花继续采集防止出现错误usart2dma.DMA_Priority=DMA_Priority_High;usart2dma.DMA_M2M=DMA_M2M_Disable; DMA_ClearFlag(DMA1_FLAG_GL6); //清除所有的标志位DMA_Init(DMA1_Channel6,&usart2dma); //串口2的接收对应着DMA1的channel6DMA_Cmd(DMA1_Channel6, ENABLE); //使能USART1 TX DMA1 所指示的通道
//设置usart_dma的发送DMA_DeInit(DMA1_Channel7); usart2dma.DMA_PeripheralBaseAddr=(u32)&(USART2->DR); //外设基地址 usart2dma.DMA_MemoryBaseAddr=(u32)USART2_TX_BUF; //内存基地址usart2dma.DMA_DIR=DMA_DIR_PeripheralDST; //内存外设usart2dma.DMA_BufferSize=0; //一次传输0字节,需要的时候更改就行usart2dma.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址不变,一直为USART2;usart2dma.DMA_MemoryInc=DMA_MemoryInc_Enable; //内存地址增加usart2dma.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte; //外设字节传输usart2dma.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte; //内存字节传输usart2dma.DMA_Mode=DMA_Mode_Normal; //不采用循环采集的模式,采集一次便可,需要的花继续采集防止出现错误usart2dma.DMA_Priority=DMA_Priority_VeryHigh;usart2dma.DMA_M2M=DMA_M2M_Disable;DMA_ClearFlag(DMA1_FLAG_GL7); //清除所有的标志位DMA_Init(DMA1_Channel7,&usart2dma); //串口2的接收对应着DMA1的channel6DMA_ITConfig(DMA1_Channel7,DMA_IT_TC,ENABLE); //DMA传输完成中断}
/***************************************
函数功能:接受重新使能
函数参数:DMA_Channel_TypeDef* DMAy_Channelx //对应的DMA通道bytes_amount //字节数
函数返回值 void
描述:在DMA的正常模式下,DMA传输完一次之后需要重新开始传输的时候
需要先关闭该通道然后向DMA_CNDTRx寄存器写值之后再打开寄存器的值
***************************************/
void Receive_cmd(DMA_Channel_TypeDef* DMAy_Channelx,u16 bytes_amount)
{DMA_Cmd(DMAy_Channelx, DISABLE); //失能USART1 TX DMA1 所指示的通道 DMA_SetCurrDataCounter(DMAy_Channelx,bytes_amount);//DMA通道的DMA缓存的大小DMA_Cmd(DMAy_Channelx, ENABLE); //使能USART1 TX DMA1 所指示的通道
}/**************下面是中断服务函数*********************/
/***************************************
函数作用:串口2中断函数
函数参数:void
函数返回值:void
***************************************/
void USART2_IRQHandler(void)
{u32 temp=temp;u8 i;if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET){temp=USART2->SR; //先读状态寄存器,然后在读数据寄存器temp=USART2->DR;DMA_Cmd(DMA1_Channel6, DISABLE); //暂时关闭USART2DMA的接受通道,防止干扰receive_flag=1;}
}
/***************************************
函数功能:DMA接受中断服务函数
函数参数:void
函数返回值:void
***************************************/
void DMA1_Channel7_IRQHandler(void)
{if(DMA_GetITStatus(DMA1_IT_GL7)!=RESET){Receive_cmd(DMA1_Channel6,20); //开启接收DMA_ClearITPendingBit(DMA1_IT_GL7); //清除所有中断标志位DMA_Cmd(DMA1_Channel7, DISABLE); //暂时关闭USART2DMA的接受通道,防止干扰send_flag=1; //接收完成软标志}
}
/**************************************************************
函数功能:获取heading角度值
入口参数:void
返回值: void
描述:发送 77 04 00 03 07(16进制),传感器返回heading相关数据,数据位在第四五六字节,具体见北微通信协议
**************************************************************/
void get_heading(void)
{u16 data=data; //这样子的作用可以排除没有使用的警告USART2_TX_BUF[0]=0x77;USART2_TX_BUF[1]=0x04;USART2_TX_BUF[2]=0x00;USART2_TX_BUF[3]=0x03;USART2_TX_BUF[4]=0x07;Receive_cmd(DMA1_Channel7,5); delay_ms(1000);while(send_flag); //等待可以已发送while(1) {if(send_flag){send_flag=0;break;}}while(1) {if(receive_flag==1) //等待接受完成{receive_flag=0; break;}} data=(USART2_RX_BUF[4]&0x0f)*10000; //百位,这儿其实都是乘了100倍换成整数提高代码的效率,同时可以防止一次一次转化成浮点数带来的精度损失的问题data=data+(USART2_RX_BUF[5]&0xf0>>4)*1000+(USART2_RX_BUF[5]&0x0f)*100; data=data+(USART2_RX_BUF[6]&0xf0>>4)*10+(USART2_RX_BUF[6]&0x0f);direction_angles[0]=(data*1.0)/100;if((USART2_RX_BUF[4]&0xf0)==0x10)direction_angles[0]=-direction_angles[0];
}
第一次写博客,肯定有很多理解不对或者错误的地方,还请各位大佬指正,也希望能给需要的人带来一点帮助,知识需要分享才能发挥更大的价值
stm32f103读取电子罗盘数据相关推荐
- 绘制STM32最小系统电路原理图、STM32F103读取SD卡的数据
绘制STM32最小系统电路原理图.STM32F103读取SD卡的数据 文章目录 绘制STM32最小系统电路原理图.STM32F103读取SD卡的数据 1 AltiumDesigner 软件配置 2 A ...
- pycharm读取JY-901S数据
前言 在家真的好不方便,等了2天的usb转ttl终于到了,也终于可以学习了 一.JY-901S介绍 ● 该产品是基于MEMS技术的高性能三维运动姿态测量系统.它包含三轴陀螺仪.三轴加速度计,三轴电子罗 ...
- 机器人底层通讯(3): linux系统下获取电子罗盘数据(上)
1.已有设备和接口 电子罗盘–1个 RS485转RS232接口–1个 RS232转USB接口-- 1个 2.在window10系统下借助串口调试器可以正常接收数据,说明电子罗盘正常: 3.查看是否已正 ...
- TensorFlow csv读取文件数据(代码实现)
TensorFlow csv读取文件数据(代码实现) 大多数人了解 Pandas 及其在处理大数据文件方面的实用性.TensorFlow 提供了读取这种文件的方法. 前面章节中,介绍了如何在 Tens ...
- SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...
转:http://blog.csdn.net/miragesky2049/article/details/7204882 SharePoint2010沙盒解决方案基础开发--关于TreeView树形控 ...
- Kinect V1读取图像数据(For Windows)
Kinect V1读取图像数据(For Windows) 这篇博客 Kinect V1介绍 数据读取的基本流程 运行代码和注释 结尾 这篇博客 刚好有一台现成的Kinect V1相机,所以就拿过来学 ...
- C++ 简单读写文本文件、统计文件的行数、读取文件数据到数组
转自:http://hi.baidu.com/ctralt/blog/item/cde79fec87f841302697911c.html fstream提供了三个类,用来实现c++对文件的操作.(文 ...
- 图像数据读取及数据扩增方法
Datawhale干货 作者:王程伟,Datawhale成员 本文为干货知识+竞赛实践系列分享,旨在理论与实践结合,从学习到项目实践.(零基础入门系列:数据挖掘/cv/nlp/金融风控/推荐系统等,持 ...
- 操作系统学习:Linux0.12初始化详细流程-进程1调度与读取硬盘数据
本文参考书籍 1.操作系统真相还原 2.Linux内核完全剖析:基于0.12内核 3.x86汇编语言 从实模式到保护模式 4.Linux内核设计的艺术 ps:基于x86硬件的pc系统 Linux0.1 ...
最新文章
- java 日期和字符串互转,根据当天整天时间 得到当天最后一秒的日期时间
- CentOS/Linux 卸载MATLAB
- B. Lynyrd Skynyrd(倍增 + 区间最小值)
- 关于select中fd_set变量的一些通俗宏解释
- Github 简明教程 - 添加远程库
- !何为脏读、不可重复读、幻读
- Python: try finally 与 上下文管理器简介
- 【华为云技术分享】云小课 | SAP S/4HANA高可用之实战演练
- python装饰器语法糖_最全python装饰器的各种写法
- RetinaNet算法详解及其在垃圾检测中的应用
- java+整合handwrite_E-signature-master
- 常用公差配合表图_车间里常用的测量器具,别说没见过!
- 华为悦盒EC6108V9 、EC6108V9C_1080UI_非高安版_鸿蒙动画_免拆卡刷固件
- 为什么打工人996会猝死,而老板007不会?
- 安岷老师 精益生产管理专家
- 关于Linux备份文件和应用的几个命令:tar和cp
- oracle热备检查,oracle 手动热备
- php狼找兔子问题算法,算法 狼找兔子问题
- acer加固态硬盘,hdd放到光驱位,BIOS没有设置固态硬盘启动选项
- Qt向MySQL中插入图片
热门文章
- python并行计算_《python并行计算(完结篇):并行方法总结》
- RBF网络插值、MNIST识别简例
- 直播协议HTTP-FLV详解
- speechSynthesis.speak()在chrome不执行问题
- 最先进的微型计算机,获得《微型计算机》称赞,GPD P2 MAX堪称对便携本的终极追求...
- 小米运动和每日瑜伽对比缺陷
- x11苹果_Apple中国 - Mac OS X - X11
- 运兴ETF:成为50ETF期权赢家必须克服的共性弱点
- 霍夫曼树与霍夫曼编码
- 头歌C++ 第8章 虚函数与多态性