STM32F107串口1通讯modbus-学习示例_第1页
STM32F107串口1通讯modbus-学习示例_第2页
STM32F107串口1通讯modbus-学习示例_第3页
STM32F107串口1通讯modbus-学习示例_第4页
STM32F107串口1通讯modbus-学习示例_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、/ / /*文件名称*功能描述:STM32F107 串口 1 通讯*参数: None*返回值: None*作者: 汪仁海*日期: 2013 年 1 月 28 日*修改人*日期*0x01定义设备地址50 /定义接收数据最大长度50 /定义发送数据最大长度#include main.h #define USART1_USART1_Addr#define USART1_GetDataNum#define USART1_OutDataNum#define USART1_RTU_03ReadOrder#define USART1_RTU_04ReadOrder#define USART1_RTU_04W

2、riteOrder 内操作0x04 /定义 mobus RTU 03 读指令0x03 /定义 mobus RTU 04 读指令/串口接收数据超计数常数0x10 / 定义 mobus RTU 04 写指令 ,在定义地址寄存器#define USART1_TIM2_COUNT 3 u8 USART1_GetDataUSART1_GetDataNum;/ 定义接收数组u8 USART1_GetDataCpyeUSART1_GetDataNum;/ 定义接收数组有效数据暂存区u8 USART1_OutDataUSART1_OutDataNum;/ 定义发送数组u16 USART1_MobusWordU

3、SART1_MobusWordNum;/MOBUS RTU 寄存器 16bit 字节数组 u8 USART1_GetDataCount;/ 串口接收数据个数u8 USART1_GetDataCountCpye;/ 串口接收数据个数转存区u8 USART1_OutDataCount;/ 串口发送数据个数u8 USART1_GetDataFlag;串口接收数据继续有效标识符,0为无效,大于0为有效u16 USART1_GetMobusAddr;/ 串口接收到指令操作地址u16 USART1_GetMobusAddrCpye;/ 串口接收到指令操作地址u8 USART1_GetMobusOrder;

4、/ 串口接收到指令操作命令u8 USART1_GetMobusOrderCpye;/ 串口接收到指令操作命令u8 USART1_GetMobusLen;/ 串口接收到指令操作数据长度u8 USART1_GetMobusOrderFlag;/ 串口接收到指令操作数据是否有效标记符*/* 对外输入输出接口函数部分*/*/u8 USART1_GetMobusOrder_Flag(void)/ 串口接收到指令操作数据是否有效标记符 return USART1_GetMobusOrderFlag;void USART1_GetMobusOrder_SetFlag(u8 ch)/ 设置串口指令操作数据标记

5、符 USART1_GetMobusOrderFlag=ch;u16 ReadMobusWord(u16 addr) / 读 Mobus 数组指定地址的数据if(addr=USART1_MobusWordAddr)&(addr=USART1_MobusWordAddr)&(addr(USART1_MobusWordAddr+USART1_Mob usWordNum)USART1_MobusWordaddr-USART1_MobusWordAddr=data;return 1;elsereturn 0;*/* 初始化函数 */* 数据初始化 */void USART1_InitData(void)

6、u16 i=0;for(i=0;iUSART1_GetDataNum;i+)USART1_GetDatai=0;USART1_GetDataCpyei=0;for(i=0;iUSART1_OutDataNum;i+)USART1_OutDatai=0;for(i=0;iUSART1_MobusWordNum;i+)USART1_MobusWordi=i;/USART1_MobusWordi=0;USART1_MobusWord0=USART1_USART1_Addr;/ 起始寄存器为该设备的地址USART1_GetDataCount=0;/ 串口接收数据个数USART1_GetDataCoun

7、tCpye=0;/ 串口接收数据个数转存区USART1_GetDataFlag=0;/ 串口接收数据继续有效标识符USART1_GetMobusLen=0;/ 串口接收到指令操作数据长度/* 串口过时接收复位函数 */void USART1_IsReset(void)/ 串口过时接收复位函数if(USART1_GetDataFlag1)USART1_GetDataCount=0;/ 串口接收数据个数清零elseUSART1_GetDataFlag-;/ 串口接收数据标识符减*/* 指令有效判断函数*/*/* 返回指定数值指定长度字符串的 u16 GetCRC16(u8 ch,u16 len)

8、/ u16 i,j;u16 crc = 0xFFFF;if(len=0)CRC 值 *返回指定数值指定长度字符串的 CRC 值len = 1;for(j=0;jlen;j+)crc A= chj;for(i=0; i= 1; crc A= 0xA001;elsecrc = 1;return(crc);/* 判断指定数值,指定长度的最后两位 CRC 值是否正确 */u16 IsCRC16(u8 ch,u16 len) / 判断指定数值,指定长度的最后两位 CRC 值是否正确 u16 a,b;b=0x0000;a=GetCRC16(ch,len-2); b=(b|chlen-1)8)|chlen-

9、2;if(a=b)return 1;elsereturn 0;/* 判断接收到得指令地址是否有效*u8 IsGetCharAddr(void)/判断接收到得指令地址是否有效u8 flagAddr=0,flagCRC=0;u16 GetCharAddr=0x0000;GetCharAddr=USART1_GetDataCpye2;GetCharAddr=(GetCharAddr=USART1_MobusWordAddr)&(GetCharAddr8)&0xff;ch4=data&0xff;data=GetCRC16(ch,5); / 返回指定数值指定长度字符串的 CRC 值 ch6=(data8

10、)&0xff;ch5=data&0xff;Uart1PutCharNum(ch,7);break;case USART1_RTU_04WriteOrder:/04 指令写操作 if(USART1_GetDataCpye4=0x00)&(USART1_GetDataCpye5=0x01)/ 只 允 许 写一个字符data=USART1_GetDataCpye7;WriteMobusWord(USART1_GetMobusAddrCpye,(data8)&0xff;ch3=data&0xff;ch4=0x00;ch5=0x01;data=GetCRC16(ch,6); / 返回指定数值指定长度字符

11、串的 CRC 值 ch7=(data8)&0xff;ch6=data&0xff;Uart1PutCharNum(ch,8);break;default:break;*/* 串口处理函数 */*函数名: USART1_Configuration输 入 :输 出 :功能说明:初始化串口硬件设备,启用中断配置步骤:(1) 打开 GPIO 和 USART1 的时钟(2) 设置 USART1 两个管脚 GPIO 模式(3) 配置 USART1 数据格式、波特率等参数(4) 使能 USART1 接收中断功能(5) 最后使能 USART1 功能 */ void USART1_Configuration(vo

12、id)GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/RS485 控制引脚配置GPIO_InitStructure.GPIO_Pin =GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure);/* 第 1 步:打开 GPIO 和 USART 部件的时钟 *

13、/* 第 2 步:将 USART Tx 的 GPIO 配置为推挽复用模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 第 3 步:将 USART Rx 的 GPIO 配置为浮空输入模式 由于 CPU 复位后, GPIO 缺省都是浮空输入模式,因此下面这个步骤不是必须的 但是,我还

14、是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);/* 第 4 步:配置 USART1 参数- BaudRate = 115200 baud- Word Length = 8 Bits- One Stop Bit- N

15、o parity- Hardware flow control disabled (RTS and CTS signals)- Receive and transmit enabled*/USART_InitStructure.USART_BaudRate = 2400; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_

16、No; USART_InitStructure.USART_HardwareFlowControlUSART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure);/* 若接收数据寄存器满,则产生中断 */USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); /USART_ITConfig(USART1, USART_IT_TXE, ENABLE);/

17、* 第 5 步:使能 USART1 , 配置完毕 */USART_Cmd(USART1, ENABLE);/* 如下语句解决第 1 个字节无法正确发送出去的问题 */USART_ClearFlag(USART1, USART_FLAG_TC); / 清标志 USART1_InitData();/ 初始化数据/*/*/* STM32 串口 1 的 RS485 读写设置/* 0 :读外部数据/* 1:向外发送数据/*u8 SetUart1_RS485(u8 ch)u32 i;if(ch=1)/发送状态GPIO_SetBits(GPIOA,GPIO_Pin_8);for(i=0;i15000;i+)

18、/ 延时 1050nselse/接收状态for(i=0;i15000;i+)/ 延时 1050nsGPIO_ResetBits(GPIOA,GPIO_Pin_8);return GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_8);*/*/*/*/*/*/*/*/* STM32 向串口 1发送 1字节/*/*/* void Uart1_PutChar(u8 ch)SetUart1_RS485(1);USART_SendData(USART1, (u8) ch); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) =

19、 RESET); SetUart1_RS485(0);/*/*/* STM32 向串口 1 发送一串字节 */*/*/*/u8 Uart1PutCharNum(u8 ch,u8 num)u8 i;SetUart1_RS485(1);for(i=0;inum;i+)USART_SendData(USART1, chi);while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) = RESET); SetUart1_RS485(0); return i;*/* */* STM32 在串口 1 接收 1 字节 */* 说明:串口 1 接收中断 */* */*

20、void USART1_IRQHandler(void)u8 USART1GetData,i;/* 串 口 接 收 寄 存 器 满 中 断 处*/若接收数据寄存器if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) 满USART1GetData = USART_ReceiveData(USART1);USART1_GetDataFlag=USART1_TIM2_COUNT;/ 串口接收数据继续有效标识符 /接收数据到缓冲区if(USART1_GetDataCountUSART1_GetDataNum) USART1_GetDataUSART

21、1_GetDataCount+=USART1GetData;else USART1_GetDataCount=0;USART1_GetDataUSART1_GetDataCount+=USART1GetData;/* 接收数据的判断*/判断接收数据指令设备地址if(USART1_GetDataCount=1)if(USART1_GetData0!=USART1_USART1_Addr)USART1_GetDataCount=0;/ 串口接收数据复位/判断指令命令类型 if(USART1_GetDataCount=2) if(USART1_GetData1=USART1_RTU_04ReadOr

22、der)/4x 读命令USART1_GetMobusLen=8;/ 串口接收到指令操作数据长度USART1_GetMobusOrderCpye=USART1_RTU_04ReadOrder;/ 串口接收到指令 操作命令else if(USART1_GetData1=USART1_RTU_04WriteOrder)/4x 写命令USART1_GetMobusLen=11;/ 串口接收到指令操作数据长度USART1_GetMobusOrderCpye=USART1_RTU_04WriteOrder;/ 串口接收到指令 操作命令elseUSART1_GetDataCount=0;/ 串口过时接收复位

23、函数 /接收完一个读写指令if(USART1_GetDataCount=USART1_GetMobusLen)/USART1_GetDataCountCpye=USART1_GetMobusLen; for(i=0;iUSART1_GetDataCountCpye;i+)USART1_GetDataCpyei=USART1_GetDatai;USART1_GetMobusOrderFlag=1;/ 串口接收到指令操作数据是否有效标记符 /Uart1_PutChar(USART1GetData);/*文件名称 功能描述 参 返 作 日数 值 者 期SysTick 时钟处理串口 1 数据例None

24、None汪仁海2013 年 1 月 28 日* * 修 改 人 : * 日 期 :*#include main.hu16 SysTick_count;void SysTick_Configuration(void)/运行状态指示灯闪烁引脚定义GPIO_InitTypeDef GPIO_InitStructure;/控制引脚配置GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/* 选 择 外 部 时 钟GPIO_Init(GPIOA, &GPIO_InitStructure);SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);/* 开定时中断 */* 时间加载, 10ms*/HCLK/8 */SysTick_ITConfig(ENABLE);SysTi

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论