当前位置:   article > 正文

mspm0G3507使用正点原子ATK-IMU901十轴陀螺仪模块的教程(附keil源码)_g3507使用keil开发uart

g3507使用keil开发uart

开始:硬件连接 

源代码链接:链接:https://pan.baidu.com/--s/1m69UXBf2TM__1FVuUxfPgA?pwd=nhcu 
提取码:nhcu 

自己去掉中间的“--”,防和谐
 

电赛来临,相比大家已经做好了很多的准备,我本来使用的是普通的6050陀螺仪,但是发现这个的静态偏差挺大的,所以想着用一个好一点的陀螺仪就买了正点原子的这个陀螺仪。

我使用的是mspm0g3507,但是正点原子并没有给出相应的代码所以就需要自己去移植,自己琢磨了一下,难度不是很高,但是要去翻手册,想必很多萌新都不太愿意去看(也有可能是因为找不到哈哈)就出了这个教程。(L1306理论上也是可以使用的,串口稍微有点区别)

其中我自己遇到了一个问题,因为一次性接受的数据很多,而且有时候发送过来并没有接收就会导致串口FIFO接收满了导致OVERRUN_ERROR(串口接收溢出错误),stm32有很多相关的教程,但是g3507几乎没有,在我翻了driverlib的库和一些stm32的解决办法后将他解决了,就在修改UART.C文件标题里面。话不多说,开始教程吧!

首先我们准备正点原子的陀螺仪模块,如下图

然后将模块的tx 和rx 与我们开发板的串口相连接(tx连接我们主板的rx,rx连接我们主板的tx)

我使用的是串口3(pa13(rx)和pa14(tx),每个人设置的不一样可能有差别)如下图所示

引脚配置:串口3 

sysconfig引脚配置如图所示

波特率可以自行修改,interrupt configuration必须是overrun error(接收溢出错误)和receive(接收)两个中断!!!

代码移植:

正点原子代码

开始之前先将串口3的中断进行使能,不然没法用

我们首先要得到一份正点原子官方的代码文件:如下图所示(百度直接搜索正点原子资料下载或者问客服要就行)

路径:

然后我们将精英stm32f103压缩包解压得到一个文件夹,点进去之后进入Drivers这个文件夹下面的BSP,我们会看到以下几个文件夹

拷贝文件:

我们将ATK_MS901M整个文件夹拷贝到你自己的工程下面去!!里面是有四个文件的!!!

添加.c和.h文件

在keil中去添加.c和.h文件(这个不会的话去看野火的stm32教程,开始就讲了,这里就不多说了)

添加好的文件(我是编译过的,前面有个小加号,最开始编译要报很多的错误,先不要编译)

修改UART.h文件

仔细看一下两个.c文件,atk_ms901.c文件里面都是一些功能函数,和陀螺仪读取数据相关的,我们不用去管它(包括atk_ms901.h也不用去管),我们把重点放在(后续为了方便将atk_ms901_uart.c和atk_ms901_uart.h统一叫做uart.c和uart.h)uart.c和uart.h的文件上面

首先我们打开uart.h文件,将引脚定义的代码全部都注释掉,这是基于hal库写的,我们有sysconfig,使能什么的都已经帮我们做好了(缓冲区大小你们没必要写我这么大,原来不变就行)

修改UART.C文件

uart.c文件里面我们主要是要修改以下几个函数

  1. void atk_ms901m_uart_send(uint8_t *dat, uint8_t len)
  2. {
  3. HAL_UART_Transmit(&g_uart_handle, dat, len, HAL_MAX_DELAY);
  4. }
  5. /**
  6. * @brief ATK-MS901M UART初始化
  7. * @param baudrate: UART通讯波特率
  8. * @retval 无
  9. */
  10. void atk_ms901m_uart_init(uint32_t baudrate)
  11. {
  12. g_uart_handle.Instance = ATK_MS901M_UART_INTERFACE; /* ATK-MS901M UART */
  13. g_uart_handle.Init.BaudRate = baudrate; /* 波特率 */
  14. g_uart_handle.Init.WordLength = UART_WORDLENGTH_8B; /* 数据位 */
  15. g_uart_handle.Init.StopBits = UART_STOPBITS_1; /* 停止位 */
  16. g_uart_handle.Init.Parity = UART_PARITY_NONE; /* 校验位 */
  17. g_uart_handle.Init.Mode = UART_MODE_TX_RX; /* 收发模式 */
  18. g_uart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; /* 无硬件流控 */
  19. g_uart_handle.Init.OverSampling = UART_OVERSAMPLING_16; /* 过采样 */
  20. HAL_UART_Init(&g_uart_handle); /* 使能ATK-MS901M UART
  21. * HAL_UART_Init()会调用函数HAL_UART_MspInit()
  22. * 该函数定义在文件usart.c中
  23. */
  24. g_uart_rx_fifo.size = ATK_MS901M_UART_RX_FIFO_BUF_SIZE; /* UART接收FIFO缓冲大小 */
  25. g_uart_rx_fifo.reader = 0; /* UART接收FIFO读指针 */
  26. g_uart_rx_fifo.writer = 0; /* UART接收FIFO写指针 */
  27. }
  28. /**
  29. * @brief ATK-MS901M UART中断回调函数
  30. * @param 无
  31. * @retval 无
  32. */
  33. void ATK_MS901M_UART_IRQHandler(void)
  34. {
  35. uint8_t tmp;
  36. if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_ORE) != RESET) /* UART接收过载错误中断 */
  37. {
  38. __HAL_UART_CLEAR_OREFLAG(&g_uart_handle); /* 清除接收过载错误中断标志 */
  39. (void)g_uart_handle.Instance->SR; /* 先读SR寄存器,再读DR寄存器 */
  40. (void)g_uart_handle.Instance->DR;
  41. }
  42. if (__HAL_UART_GET_FLAG(&g_uart_handle, UART_FLAG_RXNE) != RESET) /* UART接收中断 */
  43. {
  44. HAL_UART_Receive(&g_uart_handle, &tmp, 1, HAL_MAX_DELAY); /* UART接收数据 */
  45. atk_ms901m_uart_rx_fifo_write(&tmp, 1); /* 接收到的数据,写入UART接收FIFO */
  46. }
  47. }

修改后的函数:

  1. void atk_ms901m_uart_send(char *dat, uint8_t len)
  2. {
  3. //HAL_UART_Transmit(&g_uart_handle, dat, len, HAL_MAX_DELAY);
  4. //当前字符串地址不在结尾 并且 字符串首地址不为空
  5. while(*dat!=0&&dat!=0)
  6. {
  7. //发送字符串首地址中的字符,并且在发送完成之后首地址自增
  8. uart3_send_char(*dat++);
  9. }
  10. }
  11. /**
  12. * @brief ATK-MS901M UART初始化
  13. * @param baudrate: UART通讯波特率
  14. * @retval 无
  15. */
  16. void atk_ms901m_uart_init(uint32_t baudrate)
  17. {
  18. g_uart_rx_fifo.size = ATK_MS901M_UART_RX_FIFO_BUF_SIZE; /* UART接收FIFO缓冲大小 */
  19. g_uart_rx_fifo.reader = 0; /* UART接收FIFO读指针 */
  20. g_uart_rx_fifo.writer = 0; /* UART接收FIFO写指针 */
  21. }
  22. /**
  23. * @brief ATK-MS901M UART中断回调函数
  24. * @param 无
  25. * @retval 无
  26. */
  27. void UART_3_INST_IRQHandler(void)
  28. {
  29. uint8_t tmp;
  30. switch( DL_UART_getPendingInterrupt(UART_3_INST) )
  31. {
  32. case DL_UART_IIDX_OVERRUN_ERROR:
  33. DL_UART_getRawInterruptStatus(UART_3_INST,DL_UART_IIDX_OVERRUN_ERROR);
  34. DL_UART_Main_receiveData(UART_3_INST);
  35. break;
  36. case DL_UART_IIDX_RX://如果是接收中断
  37. // 接收发送过来的数据保存
  38. tmp = DL_UART_Main_receiveData(UART_3_INST);
  39. atk_ms901m_uart_rx_fifo_write(&tmp, 1);
  40. break;
  41. default://其他的串口中断
  42. break;
  43. }
  44. DL_UART_clearInterruptStatus(UART_3_INST,DL_UART_IIDX_OVERRUN_ERROR);
  45. }

其中uart3_send_char(*dat++);函数的实现如下

  1. void uart3_send_char(char ch)
  2. {
  3. //当串口3忙的时候等待,不忙的时候再发送传进来的字符
  4. while( DL_UART_isBusy(UART_3_INST) == true );
  5. DL_UART_Main_transmitData(UART_3_INST, ch);
  6. }

在修改完中断回调函数之后请将uart.h文件里面的中断回调函数的名称改掉!!!!

调试:DEMO.C

我们返回刚才的精英stm32f103文件夹,进入Projects->MDK-ARM->atk_f103.uvprojx,打开工程文件之后我们点击demo.c文件,copy其中的有用代码,如下所示:

  1. void demo_run(void)
  2. {
  3. uint8_t ret;
  4. uint8_t key;
  5. /* 初始化 ATK-MS901M */
  6. ret = atk_ms901m_init(115200);
  7. if (ret != 0)
  8. {
  9. printf("ATK-MS901M init failed!\r\n");
  10. delay_ms(1000);
  11. }
  12. //printf("ATK-MS901M init success!\r\n\n");
  13. demo_key0_fun();
  14. delay_ms(10);
  15. }
  16. void demo_key0_fun(void)
  17. {
  18. atk_ms901m_attitude_data_t attitude_dat; /* 姿态角数据 */
  19. atk_ms901m_gyro_data_t gyro_dat; /* 陀螺仪数据 */
  20. atk_ms901m_accelerometer_data_t accelerometer_dat; /* 加速度计数据 */
  21. atk_ms901m_magnetometer_data_t magnetometer_dat; /* 磁力计数据 */
  22. atk_ms901m_barometer_data_t barometer_dat; /* 气压计数据 */
  23. /* 获取ATK-MS901数据 */
  24. atk_ms901m_get_attitude(&attitude_dat, 100); /* 获取姿态角数据 */
  25. atk_ms901m_get_gyro_accelerometer(&gyro_dat, &accelerometer_dat, 100); /* 获取陀螺仪、加速度计数据 */
  26. atk_ms901m_get_magnetometer(&magnetometer_dat, 100); /* 获取磁力计数据 */
  27. atk_ms901m_get_barometer(&barometer_dat, 100); /* 获取气压计数据 */
  28. /* 串口打印数据 */
  29. printf("Roll: %.02f Pitch: %.02f Yaw: %.02f\r\n", attitude_dat.roll, attitude_dat.pitch, attitude_dat.yaw);
  30. printf("Gx: %.02f/s Gy: %.02f/s Gz: %.02f/s\r\n", gyro_dat.x, gyro_dat.y, gyro_dat.z);
  31. printf("Ax: %.02fG Ay: %.02fG Az: %.02fG\r\n", accelerometer_dat.x, accelerometer_dat.y, accelerometer_dat.z);
  32. printf("Mx: %d My: %d Mz: %d, Temp: %.02f\r\n", magnetometer_dat.x, magnetometer_dat.y, magnetometer_dat.z, magnetometer_dat.temperature);
  33. printf("Pres: %dPa Alt: %dcm Temp: %.02f\r\n", barometer_dat.pressure, barometer_dat.altitude, barometer_dat.temperature);
  34. printf("****************************************\r\n\r\n");
  35. }

运行:

然后我们将demo_run()文件放在while循环中就能使用了,效果如下:(打印的初始化错误是错的,实际上没有问题,我懒得去修改了),可以看见有很多参数,这就是这款陀螺仪的好处,参数很多,角度,加速度,还有磁力计,四元数,气压,海拔高度等

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/1018971
推荐阅读
  

闽ICP备14008679号