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\r\n",angle[0],angle[1],angle[2]);
break;
default: break;
}
printf("X角度:%.2f Y角度:%.2f Z角度:%.2f X速度:%.2f Y速度:%.2f Z速度:%.2f\r\n",angle[0],angle[1],angle[2],w[0],w[1],w[2]);
}
}
delay_ms(50);
}
}
