title: STM32外设驱动总结(公司项目需要)
tags: STM32
date: 2019-5-15 22:53:00



今天已经是2019年的5月中旬了,马上要毕业论文检查了,但是我一个字还没有写。本来计划今天写的,无奈无从下手呀,突然想到今天的工作记录还没有写,果断放弃了毕业论文,写论文是不可能写的,,,,(0*0)
今天来总结下我一天内完成的工作成果。

  • STM32-SPI 外置内存的调试(W25Q128)参考的正点原子例程
  • STM32-I2C 外置内存的调试(AT24C128)
  • STM32关键参数的超级串口终端(可以进行关键参数的快速配置)-阿正原创

W25Q128遇到的问题:无法读取FlashID

首先,刚开始调试SPI的时候就遇到了致命的问题,我调试了接近一晚上,但是连Flash的ID都读不出来,一度让我很烦躁,一行代码一行代码的调试,也没有发现异常,毕竟Flash的ID读取也就是几个函数而已,底层的SPI其实是不需要配置的,为了解决这个问题,我尝试了很多办法,代码几乎肯定是没问题的,我把W25Q128换成了W25Q16,依旧无法读取出来ID,此时我又把主机上的Flash换到了一块能正常运行的F4单片机上,此时是可以读出ID的,所以排除了硬件问题,但是代码是否有问题依旧无法确认,一直到下午,把办公室的老大哥,发现了原理图上面的引脚MOSI与MISO的引脚画反了!!!最终我把引脚飞线交叉以后,问题解决了,哎呀,下午的时候和我的恩同事一起去吃了土豆粉。


STM32-I2C 外置内存的调试(AT24C128)

调试代码总是不顺利的,这款IC也出现了问题,初始化无法校验成功,后来发现是我的红底昂一有问题,再加上论坛生的一些资料,帮助我解决了问题,成功实现flash读写。

STM32超级串口的设计
首先我手头的主板为STM32F103R8t6
三个串口已经全部使用了,
串口1用来做调试
串口2用来与NB模组通讯
串口3用来与485设备通讯
最后我次用了串口1作为超级串口终端。

超级串口的用途:

  1. 批量配置设备主要参数,例如:NB模组IP地址、MQTT服务器域名、设备ID、问询设备状态等。
  2. 通过串口助手快速批量设置设备
  3. 通过PC端软件快速便捷设置(QT上位机开发)

超级串口的实现方法:

  1. 串口中断的使用,包括接收中断与空闲中断(用来接收长帧数据)
  2. 自定义字符处理函数(参考网上教程)
  3. 原创类似AT指令的串口配置命令:
    指令配置表:
指令 功能
CITC+IP[192.168.1.120] 更改服务器IP地址
CITC+PORT[1883] 更改服务器端口号
CITC+ID[TEST_NB] 更改设备ID
CITC+USER[admin] 更改MQTT用户名
CITC+PASSWORD[public] 更改MQTT密码
CITC+TOPIC[/device/NB/102365] 更改发布消息Topic

地址对应表:

地址 功能 长度
0-50 存储开机打印信息与程序版本号等 50
50-70 IP地址 20
70-80 PORT端口 10
80-100 ID设备ID 20
100-120 USER用户名 20
120-140 PASSWORD密码 20
150-200 TOPIC消息主题 50

代码简单记录:


截取字符函数:

/***********************************************************函数名称:Find_string(char *pcBuf,char*left,char*right, char *pcRes)函数功能:寻找特定字符串入口参数:char *pcBuf 为传入的字符串char*left   为搜索字符的左边标识符  例如:"["char*right  为搜索字符的右边标识符  例如:"]"char *pcRes 为输出转存的字符串数组返回值:用来校验是否成功,无所谓的。备注:服务器下发命令举例:+MQTTPUBLISH: 0,0,0,0,/device/NB/zx99999999999999_back,6,[reastrobot]
***********************************************************/
int Find_string(char *pcBuf,char*left,char*right, char *pcRes)
{char *pcBegin = NULL;char *pcEnd = NULL;pcBegin = strstr(pcBuf, left);pcEnd = strstr(pcBuf, right);if(pcBegin == NULL || pcEnd == NULL || pcBegin > pcEnd){printf("Mail name not found!\n");}else{pcBegin += strlen(left);memcpy(pcRes, pcBegin, pcEnd-pcBegin);}return 0;
}

超级串口终端代码:

串口中断部分:

/***********************************************************函数名称:USART1_IRQHandler(void)函数功能:串口2中断服务程序入口参数:无返回值:无备注:实现了数据接收中断缓存,以及空闲中断处理,实现长字符数据的接收同时检测是否有下发命令的数据回传。
***********************************************************/
void USART1_IRQHandler(void)                  //串口2中断服务程序
{uint8_t ch;uint8_t Clear = Clear;if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){USART_ClearITPendingBit(USART1, USART_IT_RXNE); //接收中断ch = USART_ReceiveData(USART1);struct_usart.USART1_BUFF[struct_usart.USART1_Length++] = ch;}if ( USART_GetITStatus( USART1, USART_IT_IDLE ) == SET ) //空闲总线中断{USART_ClearITPendingBit(USART1, USART_IT_IDLE);ch = USART_ReceiveData(USART1);if (struct_usart.USART1_Length != 0) //返回值不为空{printf("\r\nBACK_CITC\r\n{%s}\r\n",struct_usart.USART1_BUFF);if (strstr((char*)struct_usart.USART1_BUFF, "CITC")) //是否包含回传数据{printf("\r\nBACK_CITC_OK!\r\n[%s]\r\n",struct_usart.USART1_BUFF);scan_CITC();memset(&struct_usart.USART1_BUFF,0,sizeof(struct_usart.USART1_BUFF));//清空结构体数组(此处不能清空,因为有可能数据正在处理的时候,服务器下发了数据)struct_usart.USART1_Length = 0;}else {printf("\r\nBACK_CITC_ERROR!\r\n");memset(&struct_usart.USART1_BUFF,0,sizeof(struct_usart.USART1_BUFF));//清空结构体数组struct_usart.USART1_Length = 0;               }}}}

接收数据处理部分:

void scan_CITC(void){memset(&CITC_MSG,0,sizeof(CITC_MSG));memset(&CITC_msg,0,sizeof(CITC_msg));if (strstr((char*)struct_usart.USART1_BUFF, "CITC+IP")) //是否包含回传数据{Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(50,(u8*)CITC_MSG,strlen(CITC_MSG));}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+PORT")){Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(70,(u8*)CITC_MSG,strlen(CITC_MSG));}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+ID")){Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(80,(u8*)CITC_MSG,strlen(CITC_MSG));}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+USER")){Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(100,(u8*)CITC_MSG,strlen(CITC_MSG));}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+PASSWORD")){Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(120,(u8*)CITC_MSG,strlen(CITC_MSG));}else if(strstr((char*)struct_usart.USART1_BUFF, "CITC+TOPIC")){Find_string((char*)struct_usart.USART1_BUFF,"[","]",CITC_msg);sprintf(CITC_MSG,"%s%s%s","[",CITC_msg,"]"); //再次组装数据便于不定长数据的截取AT24CXX_Write(150,(u8*)CITC_MSG,strlen(CITC_MSG));}
}

主机开机初始化部分(从内存中读取信息)

/***********************************************************函数名称:CITC_Init()函数功能:内存初始化入口参数:无返回值:
***********************************************************/
void CITC_Init(void)
{AT24CXX_Read(50,datatemp,20);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(IP,"%s",Find_msg);printf("IP: %s\r\n",Find_msg); memset(&Find_msg,0,sizeof(Find_msg));AT24CXX_Read(70,datatemp,10);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(Port,"%s",Find_msg);printf("PORT: %s\r\n",Find_msg); memset(&Find_msg,0,sizeof(Find_msg));AT24CXX_Read(80,datatemp,20);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(ID,"%s",Find_msg);printf("ID: %s\r\n",Find_msg); memset(&Find_msg,0,sizeof(Find_msg));AT24CXX_Read(100,datatemp,20);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(User,"%s",Find_msg);printf("USER: %s\r\n",Find_msg);memset(&Find_msg,0,sizeof(Find_msg));AT24CXX_Read(120,datatemp,20);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(Pwd,"%s",Find_msg);printf("PWD: %s\r\n",Find_msg);memset(&Find_msg,0,sizeof(Find_msg));AT24CXX_Read(150,datatemp,50);Find_string((char*)datatemp,"[","]",Find_msg);  sprintf(TOPIC,"%s",Find_msg);printf("TOPIC: %s\r\n",Find_msg);memset(&Find_msg,0,sizeof(Find_msg));}

晚安世界,希望以后自己更加努力,好好学习,努力工作。
学到更多的东西、学到更多的知识。

STM32外设驱动总结(公司项目需要)相关推荐

  1. 这款开源的STM32外设驱动库,可以直接拿来用!

    软件一行,经常需要用到很多重复的代码,我们有必要花一些时间整理一些常用的.通用的代码,等到用到的时候就可以直接拿来用了.如果没有精力自己去整理,也可以用一些网上比较成熟的代码. 比如本次介绍的基于ST ...

  2. STM32外设驱动---SysTick精准延时

    单片机:STM32F103  库函数:V3.5  描述:利用系统内核文件core_cm3.c内部SysTick实现1ms,1us的精准延时,时钟72MHz,涉及中断服务SysTick_Handler的 ...

  3. RT-Thread STM32系列BSP外设驱动使用教程

    BSP 外设驱动使用教程 简介 本文档是为需要在 RT-Thread 操作系统上使用更多开发板资源的开发者准备的.通过使用 ENV 工具对 BSP 进行配置,可以开启更多板载资源,实现更多高级功能. ...

  4. Linux主机驱动与外设驱动分离思想

    - by 宋宝华(Barry Song) 1主机.外设驱动分离的意义 在Linux设备驱动框架的设计中,除了有分层设计实现以外,还有分隔的思想.举一个简单的例子,假设我们要通过SPI总线访问某外设,在 ...

  5. STM32外设有哪些?外设在总线上是怎么挂载的?

    一:STM32外设有哪些? 外设在STM32库文件的下面路径下:(STM32库:stm32f10x_stdperiph_lib) stm32f10x_stdperiph_lib\STM32F10x_S ...

  6. spi 外设驱动(spi_driver)

    spi驱动模型和i2c的类似,都按照主机外设分离来设计的.但我觉得比i2c的要简明好多. 上文配置的spi驱动最外层是platform总线然后是spi总线然后是字符设备. spi驱动模型分为 spi主 ...

  7. i2c--ioctl--主机控制器驱动(i2c_adapter)--外设驱动(i2c_driver)

    updating... i2c驱动目录 [root@localhost i2c]# pwd /opt/FriendlyArm/mini2440/linux-2.6.32.2/drivers/i2c [ ...

  8. 世界上没有技术驱动型公司

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群"加入公众号专属技术群 来源:http://suo.im/5nMXUE 作者介绍: ...

  9. 世界上没有技术驱动型公司!

    点击上方"后端技术精选",选择"置顶公众号" 技术文章第一时间送达! 以下是知乎上"作为 IT 行业的过来人,你有什么话想对后辈说的?"问题 ...

  10. 世界上几乎没有技术驱动型公司

    一.世界上没有技术驱动型公司 世界上没有技术驱动型公司,不论google.facebook,还是腾讯.阿里,都不是技术驱动型公司.因为技术不是源头,需求才是. 因此一切技术问题,都要服从产品交付和市场 ...

最新文章

  1. 搭建前端私有npm杂记
  2. 实验一基于 的词法分析实验_[源码和文档分享]基于JAVA实现的基于DFA的词法分析程序...
  3. 对话Couchbase首席架构师:Couchbase是目前最好的NoSQL数据库平台
  4. Mac本如何运营php框架,1、Mac系统下搭建thinkPHP框架环境
  5. My task - how is inline creation implemented
  6. Event Recommendation Engine Challenge(基础版)---代码
  7. 在HermesJMS中创建ActiveMQ Session
  8. 关于安卓listview获得item中的控件问题
  9. 9.Java 面试题整理(UML 方面 )
  10. MFC Windows 程序设计(一)-程序员的解放
  11. EPS数据导入CASS中
  12. python音乐下载器
  13. 计算机怎么用鼠标,如何正确使用鼠标,这些知识你知道吗?
  14. 使用腾讯云文字识别提取图片中的文字内容
  15. 轻量级日志系统 PLG(**Promtail + Loki + Grafana**)架构技术调研
  16. 信息检索经典文章-1
  17. 英语单词:through; fall through; write through
  18. javascript结合html5 canvas实现(可调画笔颜色/粗细/橡皮)的涂鸦板
  19. violate原理和用法
  20. wpe解密系列001

热门文章

  1. assignment to ‘float *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]指针类型错
  2. CTF-MISC基础-压缩包隐写总结
  3. 年底知识「大甩卖」,知识付费这杯羹还有的分吗?
  4. BT文件分享服务器,bt是什么意思服务(bt资源库)
  5. 系统自动校时后发广播android,校园定时播放软件
  6. java wps linux 安装_安装wps for linux无法启动
  7. B-树、B+树、B*树
  8. 1.北京理工大学Python与机器学习-绪论
  9. 2022年mysql国家法定节假日脚本
  10. 环境工程学(整理知识点)