STM32外设驱动总结(公司项目需要)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/switch_love_case/article/details/90247657

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));
	
}

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

猜你喜欢

转载自blog.csdn.net/switch_love_case/article/details/90247657