当前位置:Gxlcms > 数据库问题 > STM32F407的Modbus做为主站与从站通讯

STM32F407的Modbus做为主站与从站通讯

时间:2021-07-01 10:21:17 帮助过:16人阅读

u8 RS485_BUFF[100]; u8 Rcv_Len; /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ extern u8 Uart0_send_buff[]; extern u8 Uart0_rev_buff[]; extern vs8 Uart0_send_counter; extern vu8 Uart0_rev_count;//com0串口接收计数器 extern vu8 Uart0_rev_comflag; extern vu8 Crc_counter;//com0校验计数器 extern vu8 *Uart0_send_pointer ;//com0串口发送指针 extern vu8 Uart_send_flag;//从机响应超时标志 /******************************************************************************* * 函 数 名 : RS485_Init * 函数功能 : USART2初始化函数 * 输 入 : bound:波特率 * 输 出 : 无 *******************************************************************************/ void RS485_Init(u32 bound) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOG,ENABLE); //使能GPIOA\G时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);//使能USART2时钟 //串口2引脚复用映射 GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_USART2); //GPIOA2复用为USART2 GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_USART2); //GPIOA3复用为USART2 //USART2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; //GPIOA2与GPIOA3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA2,PA3 //PG8推挽输出,485模式控制 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; //GPIOG8 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //速度100MHz GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽输出 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉 GPIO_Init(GPIOG,&GPIO_InitStructure); //初始化PG8 //USART2 初始化设置 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(USART2, &USART_InitStructure); //初始化串口2 USART_Cmd(USART2, ENABLE); //使能串口 2 USART_ClearFlag(USART2, USART_FLAG_TC); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启接受中断 //Usart2 NVIC 配置 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器、 RS485_TX_EN=0; //默认为接收模式 } /******************************************************************************* * 函 数 名 : USART2_IRQHandler * 函数功能 : USART2中断函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { if(Uart_send_flag==1) { Uart_send_flag=0;//标志没有超时 TIM_Cmd(TIM2, DISABLE); TIM_DeInit( TIM2);//复位TIM2定时器 } if(Uart0_rev_comflag != 1) { if(Uart0_rev_count < 100) { Uart0_rev_buff[Uart0_rev_count++]= USART_ReceiveData(USART2); TIM_DeInit( TIM2);//复位TIM2定时器 TIM2_Init(2,8400); } else { USART_ReceiveData(USART2);//如果接收计数器大于100,放弃接收的数据,防止同总线上有其它数据长大于100的信息导致本接收缓存溢出 } } else { USART_ReceiveData(USART2);//如果接收没有处理,放弃接收的数据 } } if(USART_GetITStatus(USART2, USART_IT_TXE) != RESET) { Uart0_send_counter--; if(Uart0_send_counter>0) { /* Write one byte to the transmit data register */ USART_SendData(USART2, *Uart0_send_pointer++); } else { delay_ms(1); RS485_TX_EN=0; // s8 i ; USART_ITConfig(USART2, USART_IT_TXE, DISABLE); Uart_send_flag = 1;// 数据发送完成 TIM_DeInit( TIM2);//复位TIM2定时器 TIM2_Init(20,8400); } } }
extern u8 RS485_BUFF[100];     //UART2  外设485数据缓存区
extern u8 mag_nav_cmd[50];     //磁导航modbus指令
extern u8 inertia_cmd[50];     //惯性导航modbus指令
extern u8 readrfid_cmd[50];    //读取ID卡modbus指令

extern u8 Uart0_send_buff[]; 
extern u8 Uart0_rev_buff[];
extern vs8 Uart0_send_counter;
extern vu8 Uart0_rev_count;//com0串口接收计数器
extern vu8 Uart0_rev_comflag;
extern vu8 Crc_counter;//com0校验计数器
extern vu8 *Uart0_send_pointer ;//com0串口发送指针
extern vu8 Uart_send_flag;//从机响应超时标志
void Modbus_Function_3(uint8_t device_id,uint8_t reg_H_addr,uint8_t reg_L_addr,uint8_t red_num_H,uint8_t red_num_L); 
u8 time_state;
extern u8 sent_data[20];
/*******************************************************************************
* 函 数 名         : TIM2_Init
* 函数功能             : TIM2初始化函数
* 输    入         : per:重装载值
                               psc:分频系数
* 输    出         : 无
*******************************************************************************/
void TIM2_Init(u32 per,u16 psc)
{
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;   //TIM初始化结构体
    NVIC_InitTypeDef NVIC_InitStructure;                 //优先级结构体
       //APB1  42M                        //APB1_TIM2 84M  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);  //使能TIM2时钟
    
    TIM_TimeBaseInitStructure.TIM_Period=(per-1)*10;     //自动装载症////
    TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;   //分频系数////分频系数和计数值决定定时器值
    TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;  
    TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);   // 初始化定时器TIM2
    
    TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //开启定时器中断
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);   //清楚定时器标志位
    
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //定时器中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =2;        //子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    
    
    TIM_Cmd(TIM2,ENABLE); //使能定时器    
}

/*******************************************************************************
* 函 数 名         : TIM2_IRQHandler
* 函数功能             : TIM2中断函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void TIM2_IRQHandler(void)
{
    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
    {    
      u8 i;
        
        /* TIM IT DISABLE [使能TIM2溢出中断]*/
    TIM_ITConfig(TIM2, TIM_IT_Update, DISABLE);
        /* TIM2 DISABLE counter */
        TIM_Cmd(TIM2, DISABLE);
        TIM_DeInit( TIM2);//复位TIM2定时器
        if(Uart_send_flag==1)
            {
                Uart_send_flag=3;//说明超时
            }
        else
        {
              Uart0_rev_comflag = 1;//接收完成
            for(i=0;i<Uart0_rev_count+1;i++)
            {
              RS485_BUFF[i]= Uart0_rev_buff[i];
            }
            Crc_counter = Uart0_rev_count;//crc校验计数器赋值
            Uart0_rev_count = 0;//接收计数器清零
        }
    }    
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}  

 

STM32F407的Modbus做为主站与从站通讯

标签:导致   add   控制   priority   smi   mode   gis   通信   指针   

人气教程排行