STM32调试485(sp3485)技术总结

发布者:沈阳阿荣最新更新时间:2017-09-23 来源: eefocus关键字:STM32  调试485  sp3485 手机看文章 扫描二维码
随时随地手机看文章

1.首先说明一下本人这次使用的STM32芯片是STM32F103RB,使用的资源是片内的USART1。

2.下面是我的电路连接图:

注:电路可以稍做修改更好,在B和A分别接下拉电阻到地和上拉电阻到5v,阻值选择为10K即可,这是为了在没有进行数据传输时保证两条数据线的状态为确定值。

做一下简单的说明:

(1)PA8是sp3485的发送/接收使能端,sp3485只能支持半双工的通信,所以这个引脚就是来控制这个芯片到底是收数据还是发数据的。

(2)在有些电路连接中,sp3485的A和B端会一个被连接一个上拉电阻到3.3V,另一个会连接一个下拉电阻到GND,这样做的目的是当本sp3485不参与通信时不会影响网络的稳定性。

3.本次调试方式

PC机——USB转232转换头——RS232/RS485双向转换头——sp3485——STM32,因为是第一次调试sp3485芯片,所以当然没有太大意,先拿电脑调试,调试通了再看板子和板子之间的通信了。

4.本次试验的代码:

main函数:


  1. int main(void)  

  2. {  

  3.   

  4.     /* Configure the system clocks */  

  5.     RCC_Configuration();  

  6.         

  7.     /* NVIC Configuration */  

  8.     NVIC_Configuration();  

  9.   

  10.     /* Configure the GPIOs */  

  11.     GPIO_Configuration();  

  12.     

  13.     /* Configure the USART1 */  

  14.     USART_Configuration();  

  15.   

  16.     GPIO_SetBits(GPIOA, GPIO_Pin_8);  //PA8是sp3485发送/接收控制端,这里先设置为发送(实现的功能就是上电之后STM32先向PC发送一个4和一个3)  

  17.   

  18.     delay_ms(2);//稍稍延时一下,原因去查看sp3485的手册吧  

  19.     USART_ClearFlag(USART1,USART_FLAG_TC);//这一句很关键,如果没有这一句这个4会发送不成功或者发送错误的,  

  20.   

  21.                                                                                            //其实手册上讲了使能发送位后会发送一个无用的帧,所以那个帧发送完了这个  

  22.   

  23.                                                                                            //发送完成的标志位USART_FLAG_TC当然也被置位了。  

  24.     USART_SendData(USART1, 4);  

  25.     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);//上面清除了发送完成标志位,那么这里就可以等待发送完成标志位被置位来判断这一帧是否发完了  

  26.   

  27.     USART_SendData(USART1, 3);  

  28.     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  

  29.   

  30.     while(1)  

  31.     {   

  32.   

  33.        GPIO_ResetBits(GPIOA, GPIO_Pin_8);//现在把PA8清零,试试接收PC机发送过来的数据  

  34.   

  35.        delay_ms(2);//稍稍延时一下,原因去查看sp3485的手册吧  

  36.        USART_ClearFlag(USART1,USART_FLAG_RXNE);//既然上面开始发送之前都将发送完成标志位清零,这里也将接收完成标志位清下零,就当是一个好习惯吧  

  37.        while(1)  

  38.       {  

  39.           if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==SET)//判断是否有一帧数据接收完成  

  40.           {              

  41.                buf[j++] = USART_ReceiveData(USART1); //接收完成的话就直接放到缓存区域里    

  42.           }  

  43.          if(10 == j)//接收完成10个之后就跳出去,不再接收了,有个意思就OK了  

  44.          break;  

  45.       }  

  46.     j = 0;//清零一下j变量,使得实验可以反复接收PC发过来的10个数据  

  47.    GPIO_SetBits(GPIOA, GPIO_Pin_8);//将sp3485设置为发送数据  

  48.     while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);  

  49.    delay_ms(2);//稍稍延时一下,原因去查看sp3485的手册吧  

  50.     for(i = 0; i < 10; i++)  

  51.    {  

  52.         USART_SendData(USART1, buf[i]);//将数据依次发送出去  

  53.         while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);   

  54.     }  

  55.  }  

  56. }  

注:在用STM32的串口做485通信的时候,发送数据的时候,检测到最后一个数据发送后的标志位已经置位,但是还不能立即失能485芯片的发送引脚,因为虽然标志位已经置位,485芯片的数据还没有完全发送出去,这个时候需要ms级别的延时,一般2个毫秒左右基本就没有问题了。

RCC设置函数:


  1. void RCC_Configuration(void)  

  2. {  

  3.   /* RCC system reset(for debug purpose) */  

  4.   RCC_DeInit();  

  5.   

  6.   /* Enable HSE */  

  7.   RCC_HSEConfig(RCC_HSE_ON);  

  8.   

  9.   /* Wait till HSE is ready */  

  10.   HSEStartUpStatus = RCC_WaitForHSEStartUp();  

  11.   

  12.   if(HSEStartUpStatus == SUCCESS)  

  13.   {  

  14.     /* HCLK = SYSCLK */  

  15.     RCC_HCLKConfig(RCC_SYSCLK_Div1);   

  16.     

  17.     /* PCLK2 = HCLK */  

  18.     RCC_PCLK2Config(RCC_HCLK_Div1);   

  19.   

  20.     /* PCLK1 = HCLK/2 */  

  21.     RCC_PCLK1Config(RCC_HCLK_Div2);  

  22.   

  23.     /* Flash 2 wait state */  

  24.     FLASH_SetLatency(FLASH_Latency_2);  

  25.     /* Enable Prefetch Buffer */  

  26.     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);  

  27.   

  28.     /* PLLCLK = 8MHz * 9 = 72 MHz */  

  29.     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);  

  30.   

  31.     /* Enable PLL */   

  32.     RCC_PLLCmd(ENABLE);  

  33.   

  34.     /* Wait till PLL is ready */  

  35.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)  

  36.     {  

  37.     }  

  38.   

  39.     /* Select PLL as system clock source */  

  40.     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  

  41.   

  42.     /* Wait till PLL is used as system clock source */  

  43.     while(RCC_GetSYSCLKSource() != 0x08)  

  44.     {  

  45.     }  

  46.   }  

  47.      

  48.   /* Enable USART1 and GPIOA clock */  

  49.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);  

  50. }  

GPIO设置函数:


  1. void GPIO_Configuration(void)  

  2. {  

  3.   GPIO_InitTypeDef GPIO_InitStructure;  

  4.   

  5.   /* Configure USART1 Tx (PA.09) as alternate function push-pull */  

  6.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  

  7.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  

  8.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  9.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  10.       

  11.   /* Configure USART1 Rx (PA.10) as input floating */  

  12.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  

  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  

  14.   GPIO_Init(GPIOA, &GPIO_InitStructure);  

  15.   

  16.  /* Configure PC. as Output push-pull */  

  17.  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  

  18.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10  

  19.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  20.  GPIO_Init(GPIOA, &GPIO_InitStructure);  

  21.   

  22.   

  23.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  

  24.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//GPIO_Mode_Out_PP = 0x10  

  25.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  26.  GPIO_Init(GPIOC, &GPIO_InitStructure);  

  27. }  

USART设置函数:


  1. void USART_Configuration(void)  

  2. {  

  3.   USART_InitTypeDef USART_InitStructure;  

  4.   USART_ClockInitTypeDef  USART_ClockInitStructure;  

  5.   

  6.   

  7. USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;  

  8. USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;  

  9. USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;  

  10. USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  

  11. /* Configure the USART1 synchronous paramters */  

  12. USART_ClockInit(USART1, &USART_ClockInitStructure);  

  13.   

  14. USART_InitStructure.USART_BaudRate = 9600;  

  15. USART_InitStructure.USART_WordLength = USART_WordLength_8b;  

  16. USART_InitStructure.USART_StopBits = USART_StopBits_1;  

  17. USART_InitStructure.USART_Parity = USART_Parity_No ;  

  18. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  

  19.   

  20.   

  21. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  

  22. /* Configure USART1 basic and asynchronous paramters */  

  23. USART_Init(USART1, &USART_InitStructure);  

  24.       

  25.   /* Enable USART1 */  

  26. USART_Cmd(USART1, ENABLE);  

  27. }  

NVIC设置函数:


  1. void NVIC_Configuration(void)  

  2. {  

  3. #ifdef  VECT_TAB_RAM    

  4.   /* Set the Vector Table base location at 0x20000000 */   

  5.   NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);   

  6. #else  /* VECT_TAB_FLASH  */  

  7.   /* Set the Vector Table base location at 0x08000000 */   

  8.   NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);     

  9. #endif  

  10. }  

5.实验结果

不成功,找了很久的原因,首先请检查sp3485与232/485双向转换头的连接线,我得到的最终的正确的连接办法是sp3485的A连接到T/R+,而sp3485的B连接到T/R-。

更改连接顺序之后还是出现了很奇怪的现象,每次上电之后PC的串口调试助手都会接收到04 03 00,都要多一个00(十六进制),还有更奇怪的现象,当在PC机上输入十个数据,点击发送之后,返回来居然是20个数据,前10个数据是错误的,后10个才是我发送过去的数据。。。

这个现象非常奇怪,将程序反复修改,还是不能解决问题,甚至一度怀疑sp3485坏掉了,最后弄了一整天,将sp3485A和B引脚之间的120欧姆的电阻去掉,一切恢复正常了!

说明一下:我的sp3485和232/485互转器之间的距离20cm左右,所以这个距离应该是不用接120欧姆的匹配电阻的。


关键字:STM32  调试485  sp3485 引用地址:STM32调试485(sp3485)技术总结

上一篇:STM32系列第1篇--初探
下一篇:STM32外设驱动篇——DHT11温湿度传感器

推荐阅读最新更新时间:2024-03-16 15:38

stm32下载的问题
原因是JTAG已经被占用,当然不能再用JTAG操作啦!此时要保证CPU不进入正常运行状态,才能使用JTAG。 解决方案:options for target ---- Debug---- 右上方---- use 后面的setting按钮------ 左上方Ort下面的JTAG变为SW即可 改成
[单片机]
<font color='red'>stm32</font>下载的问题
基于STM32设计的车库监控报警系统
一、前言 随着社会的发展,人们的生活水平不断提高对安防问题的关注度越来越高,因而各类防盗设备也层出不穷,本文采用红外测距传感器、摄像头、STM32单片机以及ESP8266无线通信模块设计一种车库防盗报警器,其可安装在车库的里,通过红外线测距检测是否有人入侵,产生报警信号,提醒相关人员采取应急防御措施。该防盗报警器成本低,功能优,防盗效果好,是家居防盗的优良选择。 二、具体需求 (一)主要模块:密码锁开门模块+检测模块+报警模块+拍摄模块+主控制模块+传输存取模块 检测模块:红外测距传感器 报警模块:灯+蜂鸣器 拍摄模块:摄像头 传输存取模块:WIFI模块实现传输,用SD卡存取 主控制模块:TFT显示屏+主控
[单片机]
基于<font color='red'>STM32</font>设计的车库监控报警系统
ARM嵌入式开发--STM32时钟设置
大家都知道在使用单片机时,时钟速度决定于外部晶振或内部RC振荡电路的频率,是不可以改变的。而ARM的出现打破了这一传统的法则,可以通过软件随意改变时钟速度。这一出现让我们的设计更加灵活,但是也给我们的设计增加了复杂性。为了让用户能够更简单的使用这一功能,STM32的库函数已经为我们设计的更加简单方便。 在比较靠前的版本中,我们需要向下面那样设置时钟: ErrorStatus HSEStartUpStatus; /************************************************************************************** * FunctionName : R
[单片机]
stm32通用定时器的使用
一、定时器的种类和时钟 stm一共有8个定时器,其中tim1和tim8为高级定时器。tim2~tim7为通用定时器。 高级定时器的时钟源挂载在apb2上(apb2=AHB),通用定时器挂载在apb1上(apb1=1/2AHB)。 下面给出一张时钟树的图: 从图中可以看出,如果apb1 prescaler=1,则tim2~tim7的时钟为定时器时钟等于apb1的时钟,而在stm32时钟的默认配置中,apb1=1/2 AHB,所以,这里定时器时钟频率是apb1的两倍,即72M。而tim1和TIM7的频率也是72M。 二、stm32通用定时器配置步骤: 1、初始化时钟 RCC_APB1PeriphClockCmd (RCC_APB
[单片机]
<font color='red'>stm32</font>通用定时器的使用
STM32之SysTick例程
#include stm32f10x.h /* RCC时钟配置 */ void RCC_config() { ErrorStatus HSEStartUpStatus; /* RCC寄存器设置为默认配置 */ RCC_DeInit(); /* 打开外部高速时钟 */ RCC_HSEConfig(RCC_HSE_ON); /* 等待外部高速时钟稳定 */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); if(HSEStartUpStatus == SUCCESS) { /* 设置HCLK = SYSCLK */ RCC_HCLKConfig(RCC_SYSC
[单片机]
stm32 PVD 可编程电压监测器
PVD (Programmable Votage Detector) ,即可编程电压监测器 。stm32库函数手册中没有细讲这个模块,只是在 PWM一章中列出了两个相关函数。但是这个功能在实际项目中会有较大的作用, 当电压过低时,对系统的一些数据使用掉电不丢失的 EEPROM 或 Flash 保存起来,同时对外设进行相应的保护操作。 PVD的作用是监视供电电压,在供电电压下降到给定的阀值以下时,产生一个中断,通知软件做紧急处理。当供电电压又恢复到给定的阀值以上时,也会产生一个中断,通知软件供电恢复。供电下降的阀值与供电上升的PVD阀值有一个固定的差值,引入这个差值的目的是为了防止电压在阀值上下小幅抖动,而频繁地产生中断
[单片机]
<font color='red'>stm32</font> PVD 可编程电压监测器
STM32笔记——GPIO
GPIO简介 GPIO是通用输出输入端口的简称,简单来说就是STM32可控制的引脚,STM32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集功能。 GPIO的基本结构 1、保护二极管与上下拉电阻 当外部输入电压高于VDD的电压时,上方的保护二极管导通,当外部输入电压底于Vss的电压时,上方的保护二极管导通,防止不正常电压引入芯片导致芯片烧毁。 2、P-MOS管和N-MOS管 在输出模式部分,线路经过一个由 P-MOS 和 N-MOS 组成的结构,这个结构使其拥有 推挽输出 和 开漏输出 的功能。 3、TTL肖特基触发器 4、IO耐压 STM32是一款3.3V电压的芯片,I
[单片机]
<font color='red'>STM32</font>笔记——GPIO
STM32定时器的几种用法
一、常用的定时功能 (1)基本、通用、高级定时器都有最基本的定时功能,定时功能用到的函数如下: HAL_ TI M_Base_Init 初始化定时,包括分频、 预装值等。 HAL_TIM_ConfigClockSource 选择定时器的 时钟 源 HAL_TIM_Base_Start_IT 开始定时器 HAL_TIM_PeriodElapsedCallb ac k 超时后的回调函数 (2)Cubemx的配置,不管什么定时器,都是这个配置,注意开启中断,计算好最终的定时器时钟 (3)代码片段 1 void MX_TIM12_Init(void) 2 { 3 TIM_ClockConfigTypeDef sClo
[单片机]
<font color='red'>STM32</font>定时器的几种用法
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved