RS485通讯实验
RS485通讯实验
1.硬件:
STM32的串口管教加一个485芯片控制IO:
还需要一个USB 转485转换器,一端接485AB,USB口插PC上用串口助手查看数据。
注意点:以板子为核心,PC12置1为向外发送数据,PC12置0为向内接收数据。
2.代码,效果就是串口3发送5字节数据后收到同样5字节数据的返回:
rs485.h文件: #ifndef RS485_RS485_H_ #define RS485_RS485_H_#include "Sys.h"u8 RS485_RX_CNT; //接收缓存区 u8 RS485_RX_BUF[64]; //接收缓冲,最大64个字节.;void RS485_Send_Data(u8 *buf,u8 len); void RS485_Receive_Data(u8 *buf,u8 *len);#endif /* RS485_RS485_H_ */rs485.c文件: #include "rs485.h" #include "Uart.h" volatile unsigned char RS485_REC_Flag = 0; //接收缓存区 u8 RS485_RX_BUF[64]; //接收缓冲,最大64个字节. //接收到的数据长度 u8 RS485_RX_CNT=0;//RS485发送len个字节. //buf:发送区首地址 //len:发送的字节数(为了和本代码的接收匹配,这里建议不要超过64个字节) void RS485_Send_Data(u8 *buf,u8 len) {u8 t;GPIO_SetBits(GPIOC,GPIO_Pin_12);for(t=0;t<len;t++) //循环发送数据{while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);USART_SendData(USART3,buf[t]);}while(USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET);RS485_RX_CNT=0;GPIO_ResetBits(GPIOC,GPIO_Pin_12); } //RS485查询接收到的数据 //buf:接收缓存首地址 //len:读到的数据长度 void RS485_Receive_Data(u8 *buf,u8 *len) {u8 rxlen=RS485_RX_CNT;u8 i=0;u8 lenx = 5;*len=0; //默认为0delay_ms(100); //等待10ms,连续超过10ms没有接收到一个数据,则认为接收结束if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了{for(i=0;i<rxlen;i++){buf[i]=RS485_RX_BUF[i];}RS485_Send_Data(buf,lenx);*len=RS485_RX_CNT; //记录本次数据长度RS485_RX_CNT=0; //清零} }void USART3_IRQHandler(void) {u8 res;if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收到数据{res =USART_ReceiveData(USART3); //读取接收到的数据if(RS485_RX_CNT<64){RS485_RX_BUF[RS485_RX_CNT]=res; //记录接收到的值RS485_RX_CNT++; //接收数据增加1}} }Uart.h文件: #ifndef UART_UART_H_ #define UART_UART_H_#include "Sys.h"#define USART_REC_LEN 200 //定义最大接收字节数 200u16 USART_RX_STA; //接收状态标记 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.void uart_init(u32 bound); void uart3_init(u32 bound);#endif /* UART_UART_H_ */Uart.c文件: #include "Uart.h" void uart_init(u32 bound) {//USART 初始化设置USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(UART5, &USART_InitStructure); //初始化串口1USART_ITConfig(UART5, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(UART5, ENABLE); //使能串口1}void uart3_init(u32 bound) {//USART 初始化设置USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = bound;//串口波特率USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART3, &USART_InitStructure); //初始化串口1USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART3, ENABLE); //使能串口1USART_ClearITPendingBit(USART3, USART_IT_TC);//清除中断TC位}Sys.h文件: #ifndef SYS_SYS_H_ #define SYS_SYS_H_#include <stdio.h> #include <string.h> #include "stm32f10x.h"#define True (1) #define False (0) typedef uint32_t u32;///32位void delay_init(void); void RCC_Configuration(void); void GPIO_RemapConfig(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void systemInit(void); void delay_ms(u16 nms);#endif /* SYS_SYS_H_ */Sys.c文件: #include "Sys.h" #include "Uart.h"static u8 fac_us=0; //us延时倍乘数 static u16 fac_ms=0; //ms延时倍乘数,在ucos下,代表每个节拍的ms数 //初始化延迟函数 //当使用OS的时候,此函数会初始化OS的时钟节拍 //SYSTICK的时钟固定为HCLK时钟的1/8 //SYSCLK:系统时钟 void delay_init() {SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8fac_us=SystemCoreClock/8000000; //为系统时钟的1/8fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数 }void RCC_Configuration(void) {RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOC, ENABLE); //使能USART1,GPIOA时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);}void GPIO_Configuration(void) {GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.10//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//浮空输入GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOA.10}void GPIO_RemapConfig(void) {GPIO_PinRemapConfig(GPIO_PartialRemap_USART3, ENABLE); }void NVIC_Configuration(void) {NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2//中断优先级NVIC设置NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; //TIM3中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级0级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器}//延时nms //注意nms的范围 //SysTick->LOAD为24位寄存器,所以,最大延时为: //nms<=0xffffff*8*1000/SYSCLK //SYSCLK单位为Hz,nms单位为ms //对72M条件下,nms<=1864 void delay_ms(u16 nms) {u32 temp;SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)SysTick->VAL =0x00; //清空计数器SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数do{temp=SysTick->CTRL;}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器SysTick->VAL =0X00; //清空计数器 }void systemInit(void) {SystemInit();delay_init();RCC_Configuration(); // RCC配置GPIO_Configuration(); // GPIO配置GPIO_RemapConfig(); // GPIO重映射NVIC_Configuration(); // NVIC配置uart3_init(9600); }main.c文件: #include "Sys.h" #include "Uart.h" #include "rs485.h"void getSysClk(void) {RCC_ClocksTypeDef get_rcc_clock;RCC_GetClocksFreq(&get_rcc_clock); }int main(void) {TimerFlagCounter = 0x00;TimerFlag = False;USART_RX_STA = 0;RS485_RX_CNT = 0;u8 rs485buf[5];u8 key = 0x05;systemInit();while(1){RS485_Receive_Data(rs485buf,&key);}return 0; }
总结
- 上一篇: 关于人工智能不会使大脑变懒惰的议论文_模
- 下一篇: Frammer X for mac(ma