MPU6050型号
商家描述:此六轴模块采用先进的数字滤波技术,能有效降低测量噪声,提高测量精度。模块内部集成了运动引擎DMP,获取四元数得到当前姿态。姿态测量精度0.01度,稳定性极高,性能甚至优于某些专业的倾角仪!此六轴模块采用高精度的陀螺加速度计 MPU6050,通过处理器读取 MPU6050 的测量数据然后通过串口输出,免去了用户自己去开发MPU6050 复杂的 I2C 协议,同时精心的 PCB 布局和工艺保证了 MPU6050 收到外接的干扰最小,测量的精度最高。
模块发送至上位机每帧数据分为 3 个数据包,分别为加速度包,角速度包和角度包,3个数据包顺序输出。波特率 115200 时每隔 10ms 输出 1 帧数据,波特率 9600 时每隔 50ms 输出一帧数据。
通信协议:电平:TTL 电平,波特率:115200/9600,停止位 1,校验位 0。
源码分析
整体流程是:初始化,然后反复通过串口接收数据,取走数据。(因为不改写模块的配置,所以不考虑向模块发送数据部分)
初始化:配置系统时钟、初始化IO口、中断优先级初始化、初始化串口、初始化延时函数
配置系统时钟
//配置系统时钟
void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus; //定义外部高速晶体启动状态枚举变量
RCC_DeInit(); //复位RCC外部设备寄存器到默认值
RCC_HSEConfig(RCC_HSE_ON); //打开外部高速晶振
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待外部高速时钟准备好
if(HSEStartUpStatus == SUCCESS) //外部高速时钟已经准别好
{
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //开启FLASH预读缓冲功能,加速FLASH的读取。所有程序中必须的用法.位置:RCC初始化子函数里面,时钟起振之后
FLASH_SetLatency(FLASH_Latency_2); //flash操作的延时
RCC_HCLKConfig(RCC_SYSCLK_Div1); //配置AHB(HCLK)时钟等于==SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); //配置APB2(PCLK2)钟==AHB时钟
RCC_PCLK1Config(RCC_HCLK_Div2); //配置APB1(PCLK1)钟==AHB1/2时钟
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //配置PLL时钟 == 外部高速晶体时钟 * 9 = 72MHz
RCC_PLLCmd(ENABLE); //使能PLL时钟
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) //等待PLL时钟就绪
{
}
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //配置系统时钟 = PLL时钟
while(RCC_GetSYSCLKSource() != 0x08) //检查PLL时钟是否作为系统时钟
{
}
}
}
初始化IO口
//IO口配置
//用法:用哪个打开那个
void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure; //定义名为GPIO_InitStructure的结构体类型变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开GPIOB的时钟,并使能。
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开GPIOC的时钟,并使能。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //打开GPIOD的时钟,并使能。
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //打开GPIOA的时钟,并使能。
//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE); //打开GPIOB和GPIOD的时钟,并使能。
//配置PD10口:
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_9; //选定哪个IO口 现选定PD9口和PD10口
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; //设定IO口的模式为上拉输入�
// //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //如果IO口的模式是输入,GPIO_Speed可以不赋值
// GPIO_Init(GPIOD, &GPIO_InitStructure); /* PC6 */ //初始化GPIOD
//配置PA口:
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //选定哪个IO口 现选定PA0口和PA1口
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设定IO口的模式为推挽输出�
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //设定IO口的输出速度为2MHz
// GPIO_Init(GPIOA, &GPIO_InitStructure); /* PC6 */ //初始化GPIOD
//配置PD口:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; //选定哪个IO口 现选定PD0123口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设定IO口的模式为推挽输出�
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设定IO口的输出速度为50MHz
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOD
//配置PD口:
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //选定哪个IO口 现选定PD2口
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设定IO口的模式为推挽输出�
// GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //设定IO口的输出速度为2MHz
// GPIO_Init(GPIOD, &GPIO_InitStructure); /* PC6 */ //初始化GPIOD
//配置3个LED灯:PB12、PB13、PB14:
GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14); //关闭3个LED灯:PB12、PB13、PB14,输出高电平
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14; //选定PB12、PB13、PB14
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设定IO口的模式为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //设定IO口的输出速度为2MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB
}
中断优先级初始化
//中断IO口配置
//用法:用哪个打开那个
void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure; //定义一个结构体变量
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //打开APB2总线复用时钟
//外部中断线10配置:
EXTI_ClearITPendingBit(EXTI_Line10); //清除中断挂起位 外部中断线10
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择是中断触发还是事件触发,现在选择的是中断触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //触发方式:现在选择的是下降沿触发
EXTI_InitStructure.EXTI_Line = EXTI_Line10; //选择哪个IO口作为中断输入,现在选择的是PD10口
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource10); //选择GPIO管脚作为外部中断线路
//外部中断线9配置:
EXTI_ClearITPendingBit(EXTI_Line9); //清除中断挂起位 外部中断线9
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //选择是中断触发还是事件触发,现在选择的是中断触发
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //触发方式:现在选择的是下降沿触发
EXTI_InitStructure.EXTI_Line = EXTI_Line9; //选择哪个IO口作为中断输入,现在选择的是PD9口
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //使能中断
EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
GPIO_EXTILineConfig(GPIO_PortSourceGPIOD, GPIO_PinSource9); //选择GPIO管脚作为外部中断线路
}
中断优先级管理
//中断优先级配置
//用法:用哪个打开那个
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure; //定义用于配置中断的结构体变量
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 抢占式优先级别设置为2位;响应优先级占2位
//外部中断线10优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //指定中断源
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//外部中断线9优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //指定中断源
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级 暂时没有
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //指定响应优先级别2
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//串口1中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //通道设置为串口1中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//串口1用DMA接收中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn; //通道设置为串口DMA通道4中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//串口2中断优先级设置(RS485)
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //指定中断源
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //指定响应优先级别1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//串口3中断优先级设置(RS485)
// NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //指定中断源
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
// //串口1用DMA接收优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn; //DMA1通道5中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
// //串口4中断优先级设置(RS485)
// NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn; //指定中断源
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
// //串口5中断优先级设置(RS485)
// NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; //指定中断源
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //指定响应优先级别1
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断
// NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//通用定时器2中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//通用定时器3中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//通用定时器4中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//通用定时器5中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn; //TIM5中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//通用定时器6中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn; //TIM6中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
//通用定时器7中断优先级设置
// NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn; //TIM7中断
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级1级
// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
// NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
// NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
}
串口初始化
//串口1初始化
void USART1_Config(void) //初始化 配置USART1
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量
//第1步:打开GPIO和USART部件的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //打开GPIOA时钟和GPIOA复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //打开串口复用时钟
USART_DeInit(USART1); //复位串口1
//第2步:将USART1 Tx(发送脚)的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //串口1发送脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //输出速度50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
//第3步:将USART Rx(接收脚)的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //串口1接收脚
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
//第4步:配置USART1参数
USART_InitStructure.USART_BaudRate = 115200; //波特率设置:115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置: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(USART1, &USART_InitStructure); //初始化USART1
//打开发送中断和接收中断(如果需要中断)
//USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 使能指定的USART1发送中断 ;
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能指定的USART1接收中断 ;
//第5步:使能 USART1, 配置完毕
USART_Cmd(USART1, ENABLE); //使能 USART1
//如下语句解决第1个字节无法正确发送出去的问题
USART_ClearFlag(USART1, USART_FLAG_TC); //清串口1发送标志
}
//串口2初始化
void USART2_Config(void) //初始化 配置USART2
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量
//使能 USART2 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //打开串口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //打开PA端口时钟
//将USART2 Tx(发送脚)的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //选定哪个IO口 现选定PA2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设定IO口的输出速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
//将USART2 Rx(接收脚)的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //选定哪个IO口 现选定PA3
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化GPIOA
//配置USART2参数
USART_InitStructure.USART_BaudRate = 115200; //波特率设置:115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置: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); //初始化USART2
//打开发送中断和接收中断(如果需要中断)
//USART_ITConfig(USART2, USART_IT_TXE, ENABLE); // 使能指定的USART2发送中断
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // 使能指定的USART2接收中断
//使能 USART2, 配置完毕
USART_Cmd(USART2, ENABLE); // USART2使能
//如下语句解决第1个字节无法正确发送出去的问题
USART_ClearFlag(USART2, USART_FLAG_TC); //清串口2发送标志
}
//串口3初始化
void USART3_Config(void) //初始化 配置USART3
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量
//使能 USART3 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //打开串口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //打开PB端口时钟
//将USART3 Tx(发送脚)的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //选定哪个IO口 现选定PB10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设定IO口的输出速度为50MHz
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOB
//将USART3 Rx(接收脚)的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //选定哪个IO口 现选定PB11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化GPIOA
//配置USART3参数
USART_InitStructure.USART_BaudRate = 2400; //波特率设置:2400
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置: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(USART3, &USART_InitStructure); //初始化USART3
//打开发送中断和接收中断(如果需要中断)
//USART_ITConfig(USART3, USART_IT_TXE, ENABLE); // 使能指定的USART3发送中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); // 使能指定的USART3接收中断
//使能 USART3, 配置完毕
USART_Cmd(USART3, ENABLE); // USART3使能
//如下语句解决第1个字节无法正确发送出去的问题
USART_ClearFlag(USART3, USART_FLAG_TC); //清串口3发送标志
}
//串口4初始化
void UART4_Config(void) //初始化 配置USART4
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量
//使能 UART4 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE); //打开串口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开PC端口时钟
//将USART4 Tx(发送脚)的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //选定哪个IO口 现选定PC10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设定IO口的输出速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC
//将UART4 Rx(接收脚)的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; //选定哪个IO口 现选定PC11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC
//配置UART4参数
USART_InitStructure.USART_BaudRate = 2400; //波特率设置:2400
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置: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(UART4, &USART_InitStructure); //初始化UART4
//打开发送中断和接收中断(如果需要中断)
//USART_ITConfig(UART4, USART_IT_TXE, ENABLE); // 使能指定的UART4发送中断
USART_ITConfig(UART4, USART_IT_RXNE, ENABLE); // 使能指定的UART4接收中断
//使能 UART4, 配置完毕
USART_Cmd(UART4, ENABLE); // UART4使能
//如下语句解决第1个字节无法正确发送出去的问题
USART_ClearFlag(UART4, USART_FLAG_TC); //清串口4发送标志
}
//串口5初始化
void UART5_Config(void) //初始化 配置UART5
{
GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量
//使能 UART5 时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); //打开串口复用时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //打开PC端口时钟
//将UART5 Tx(发送脚)的GPIO配置为推挽复用模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; //选定哪个IO口 现选定PC12
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设定IO口的输出速度为50MHz
GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化GPIOC
//将UART5 Rx(接收脚)的GPIO配置为浮空输入模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //选定哪个IO口 现选定PD2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_Init(GPIOD, &GPIO_InitStructure); //初始化GPIOC
//配置UART5参数
USART_InitStructure.USART_BaudRate = 2400; //波特率设置:2400
USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位数设置:8位
USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位设置: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(UART5, &USART_InitStructure); //初始化UART5
//打开发送中断和接收中断(如果需要中断)
//USART_ITConfig(UART5, USART_IT_TXE, ENABLE); // 使能指定的UART4发送中断
USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); // 使能指定的UART4接收中断
//使能 UART5, 配置完毕
USART_Cmd(UART5, ENABLE); // UART5使能
//如下语句解决第1个字节无法正确发送出去的问题 */
USART_ClearFlag(UART5, USART_FLAG_TC); //清串口5发送标志
}
反复接收串口2数据
void USART2_IRQHandler(void){
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //接收中断有效,若接收数据寄存器满
{
Temp[counter] = USART_ReceiveData(USART2); //接收数据
//网购给的程序
//if(counter == 0 && Re_buf[0] != 0x55) return; //第 0 号数据不是帧头,跳过
if(counter == 0 && Temp[0] != 0x55) return; //第 0 号数据不是帧头,跳过
counter++;
if(counter==11) //接收到 11 个数据
{
memcpy(Re_buf,Temp,11);
counter=0; //重新赋值,准备下一帧数据的接收
sign=1;//缓冲区Re_buf是否有数据标志
}
}
}
反复查询缓冲区是否存在数据,存在并取走
while (1)
{
if(sign)
{
memcpy(Temp,Re_buf,11);
sign=0;
if(Re_buf[0]==0x55) //检查帧头
{
switch(Re_buf[1])
{
case 0x51: //标识这个包是加速度包
a[0] = ((short)(Temp[3]<<8 | Temp[2]))/32768.0*16; //X轴加速度
a[1] = ((short)(Temp[5]<<8 | Temp[4]))/32768.0*16; //Y轴加速度
a[2] = ((short)(Temp[7]<<8 | Temp[6]))/32768.0*16; //Z轴加速度
T = ((short)(Temp[9]<<8 | Temp[8]))/340.0+36.25; //温度
break;
case 0x52: //标识这个包是角速度包
w[0] = ((short)(Temp[3]<<8| Temp[2]))/32768.0*2000; //X轴角速度
w[1] = ((short)(Temp[5]<<8| Temp[4]))/32768.0*2000; //Y轴角速度
w[2] = ((short)(Temp[7]<<8| Temp[6]))/32768.0*2000; //Z轴角速度
T = ((short)(Temp[9]<<8| Temp[8]))/340.0+36.25; //温度
break;
case 0x53: //标识这个包是角度包
angle[0] = ((short)(Temp[3]<<8| Temp[2]))/32768.0*180; //X轴滚转角(x 轴)
angle[1] = ((short)(Temp[5]<<8| Temp[4]))/32768.0*180; //Y轴俯仰角(y 轴)
angle[2] = ((short)(Temp[7]<<8| Temp[6]))/32768.0*180; //Z轴偏航角(z 轴)
T = ((short)(Temp[9]<<8| Temp[8]))/340.0+36.25; //温度
//printf("X轴角度:%.2f Y轴角度:%.2f Z轴角度:%.2f
",angle[0],angle[1],angle[2]);
break;
default: break;
}
printf("X角度:%.2f Y角度:%.2f Z角度:%.2f X速度:%.2f Y速度:%.2f Z速度:%.2f
",angle[0],angle[1],angle[2],w[0],w[1],w[2]);
}
}
delay_ms(50);
}
}