完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
写在前面的话
不知不觉我也已经鼓捣这个CUBEMX快两个星期了,这期间在网上搜了很多很多教程,也受到很多大佬的指点,终于调通了我这个硬件I2C+USB模拟串口收发传感器数据的小东西。我说句实话,这种体量的小东西确实用不到CUBEMX,我在网上见到的99%的例程全都是用标准库跑出来的,不过呢,既然我们老板有要求,那就要用起来,于是我也从零开始一点一点啃。我也是个新手,如果有不对的地方,欢迎各位大佬指出我的错误哈!希望各位伙伴都能学到点什么! 非常好的入门教程推荐 由于网上关于安装CUBEMX、如何使用CUBEMX生成Keil工程、基础的HAL库函数使用方法等等已经有相当多的文字和视频教程,我就不再献丑了。这边我就直接推荐两个教程给大家: 1.B站小蜜蜂老师的干货铺:CUBEMX教程 点我直接跳转到B站 2.csdn大佬Z小旋的CUBEMX教程 点我直接去大佬的教程 以上两个教程都有涵盖CUBEMX的安装、使用、如何配置时钟树、如何生成工程、基础的HAL库函数用法等等…看完这个教程你的CUBEMX就学会一半了。 我的设备 STM32f103c8最小板 ST-LINK 串口调试助手XCOM Keil-ARM v5 在CUBEMX上的工作 选择自己单片机的型号 配置RCC,因为USB设备是一定要用到RCC中的HSE的 注意:需要使用stlink下载一定要点选sys中的serial wire debug,否则下载会有点麻烦,具体参照我的一篇博客:为什么不按住复位没法下载? 要先点选过USB之后才能点选USB-DEVICE,否则USB-DEVICE那边是灰色的 选择模拟串口 在Clock Configuration这里可能有个粉色的小叉叉,不要紧,点进来之后他会自动弹出一个对话框,问你是否要自动调整时钟树的设定,点yes就可以了。如果没有弹出对话框,就点击 Resolve Clock Issue就行了。在这幅时钟树里,所有错误的时钟都会有粉色高亮背景,如果想要手动调整的话也可以。 另外需要注意的是,USB的输入时钟必须是48Hz,这是由USB传输协议的一些物理和逻辑条件决定的。 生成Keil工程。注意:生成的uv5 project文件在MDK-ARM文件夹下 Keil上的工作 需要了解的函数 1.MX_USB_DEVICE_Init(); 这是USB的初始化函数,可以看到他在main函数中已经被写好了。关于USB设备如何初始化、逻辑流程是怎样的、数据流怎样流动在这里就不多做描述。因为关于USB设备的启动是比较复杂的,在CUBEMX中直接是作为一个中间层在使用,比起HAL库还再封装了一层,如果全都说清楚估计还要再开一篇文章了,有机会我会写一写,因为有关USB的知识在移植平台的时候还是很有用的。 2.uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len); 这是向从机(你的单片机)发送一条数据的函数。两个变量: *buf指向被发送数据存放的起始地址; len则是被发送数据的长度; /*一个逃课小技巧: 可能很多人都发现STM的HAL库函数里,但凡是指针形参全是uint8_t类型的。假设我有个uint16_t类型的数据A想发送 ,直接使用&A是直接报错的,数据类型不一致嘛。 这时候可以声明一个uint8的数组,数组中一共有两个成员,将uint16的数据高八位存放在数组的第一成员中,将第八位放在第二成员中。这样以后不管是什么类型的数据,我只要给他存在一个uint8的数组中,再把数组成员的地址写进函数里就好了。我说的可能不是很清楚,但是只要写出来大家就明白了: uint16_t a; //需要使用的数据 uint8_t buffer[2]; //工具人:8位数组 buffer[0] = a>>8; //经典取高八位操作 buffer[1] = a&0xff; //取低八位 function(&buffer[0],...); //function只是一个代称,任何用到uint8*的函数都可以这样用 function(&buffer[1],...); 说实话,就这个指针的问题我整整纠结了一上午,后来参考了别人的例程才想到这样聪明绝顶的点子。使用指针做形参的好处就是: 1.在很多可以连续收/发的函数中不再需要使用循环,在这个函数的内部就已经带有循环,只要动动小手指填个数组就能轻松发出去很多字节的数据; 2.用指针做形参的时候是直接进入该变量的地址操作的,可以避免在执行函数后变量不变的情况。打个比方吧:我要改一份重要文件,放在C盘,我如果复制一份一模一样的文件,放在D盘,然后再去改动D盘的复制版的话,很有可能我一个脑抽,上交的还是那个没动过的C盘的文件,所以我干脆到C盘去改就万事大吉了; 还有一个逃课小技巧就是:被发送数据的长度可以用sizeof()来取,这个我就不再多说了。*/ 编写程序 在主函数中,各个外设的初始化函数已经写好,我们所需要的就是在main函数中写一个收发的流程就行了。为了证明能发能收,我们想要达到这几个功能: 1.打开串口后发送“u***虚拟串口已连接!” 2.发给从机数据后,向主机发送“已接收!你的数据是:xxx” 首先要解决的问题就是模拟串口接收的问题。 在cdc_if.c中确实有一个函数叫做CDC_Receive_FS();但是这个函数的功能非常简单,只是将收到数据缓存在句柄结构体里,然后表明自己收包完成,准备进入下一次接收。这个函数的返回值是USB设备的状态值,并非收到的数据,所以我们要对这个函数做一点改造,才能在main函数里调取USB接收到的值。 首先我们需要在cdc_if.c中开头的位置声明两个变量: uint8_t USB_Receive_Buffer[50]; //数据缓冲区数组的大小可以根据你想要的收发的数据大小变更 uint16_t USB_Receive_Lenth; 千万不要去函数里面声明啊,局部变量是没办法全局调用的! 接下来在CDC_Receive_FS中进行改造 static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) { /* USER CODE BEGIN 6 */ memcpy(USB_Receive_Buffer,Buf,*Len); USB_Receive_Lenth = *Len; //如果希望接收数据的长度有某个固定上限, //可以利用一个for循环,读取到一定位数后自动跳出循环; USBD_CDC_SetRxBuffer(&hU***DeviceFS, &Buf[0]); USBD_CDC_ReceivePacket(&hU***DeviceFS); return (USBD_OK); /* USER CODE END 6 */ } 如果想要在main中使用全局变量,记得一定要在函数开头处添加全局变量声明: extern uint8_t USB_Receive_Buffer[]; extern uint16_t USB_Receive_Lenth; 好了,接下来要做的就是在main函数的大循环中写一个发送函数就好了,在这里我只贴循环和字符串的定义部分: /* USER CODE BEGIN 2 */ uint8_t test_str1[] = "u*** virtual port connected! rn"; uint8_t test_str2[] ="over! rn"; ; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ CDC_Transmit_FS(test_str1,sizeof(test_str1)); HAL_Delay(1000);//防止发送的太快我看不清楚 CDC_Transmit_FS(USB_Receive_Buffer,USB_Receive_Lenth); HAL_Delay(1000); CDC_Transmit_FS(test_str2,sizeof(test_str2)); HAL_Delay(1000); } /* USER CODE END 3 */ } 成果 用st-link下载好程序,插上USB,这时候我们已经可以发现,插入USB之后电脑不再报错,在设备管理器中应该可以看到自己的板子了。记住自己的这个串口号COM4; 打开随便哪一款串口调试助手,我这里用的是正点原子的XCOM;选择COM4,点击打开串口: 如果不发送任何消息的话,这两条已经设定好的字符串就会一直循环显示;试着发送一条消息,可以成功接收并送回: 在我们的程序中,如过当前没有进行串口数据发送,那么串口发上来数据也一直是最后接收到的数据,也就是说没有实时显示当前发送为null的功能啦,因为我并不需要实时性,所以这一部分就不做了,有兴趣的伙伴可以自己试着做一下。 以上! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1618 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1545 浏览 1 评论
979 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1597 浏览 2 评论
1864浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
645浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
516浏览 3评论
532浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
505浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 20:21 , Processed in 0.802994 second(s), Total 79, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号