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 通信 指针