打印
[STM32F1]

我写的modbus rtu 程序怎么不行,牛人帮忙看下

[复制链接]
1131|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
长缨在手|  楼主 | 2014-8-4 22:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 长缨在手 于 2014-8-4 22:14 编辑

include "stm32f10x.h"

u8 i;

u8 Com0_id = 0x05;//本机串口0的通讯地址
u8 Uart0_rev_buff[100];//com0串口接收缓冲区
u8 Uart0_send_buff[100];//com0串口发送缓冲区
vu8 Uart0_rev_count;
vs8 Uart0_send_counter = 0;
vu8 Uart0_rev_comflag=0;
vu8 Crc_counter = 0;//com0校验计数器
vu8 Uart1_Rx_Num=0;
vu8 *Uart0_send_pointer = Uart0_send_buff;//com0串口发送指针
vu16 Mkgz_bz = 0;//模块故障标志1:输入异常,2:过压,3:欠压,4:过温
vu16 Out_current = 50;//输出电流
vu16 Out_voltage = 240;//输出电压
vu16 Mkzt_bz = 0;//模块状态标志
vu16 OutX_current = 1000;//输出限流
vu16 Jc_voltage = 2530;//均充电压
vu16 Fc_voltage = 2400;//浮充电压
vu16 user_day = 1825;//使用天数
void Delay(vu32 nCount);
unsigned short getCRC16(volatile unsigned char *ptr,unsigned char len) ;
//void mov_data(u8 a[100],u16 b[50],u8 c);
void Modbus_Function_3(void);
void Modbus_Function_6(void);
void RCC_cfg();
void GPIO_cfg();
void USART_cfg();
void NVIC_Configuration();
void Timer2_Configuration();
void Com0_Communication();
void USART1_IRQHandler();
void TIM2_IRQHandler();

void main()
{
    RCC_cfg();
    GPIO_cfg();
    USART_cfg();
    Timer2_Configuration();
    NVIC_Configuration();

while(1)
{                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       Com0_Communication();

}
}


unsigned short getCRC16(volatile unsigned char *ptr,unsigned char len)
{
unsigned char i;
unsigned short crc = 0xFFFF;                                         
if(len==0)
{
len = 1;
}
while(len--)

{
crc ^= *ptr;
for(i=0; i<8; i++)
{
if(crc&1)
{
crc >>= 1;
crc ^= 0xA001;
}
else
{
crc >>= 1;
}
}
ptr++;
}
return(crc);
}



///////////////////////////////////////////////////////////////////////
void Modbus_Function_3(void)
{
u16 tempdress = 0;
u8 i = 3;
u16 crcresult;
tempdress= (Uart0_rev_buff[2] << 8) + Uart0_rev_buff[3];
if((tempdress >= 0x0120) & (tempdress + Uart0_rev_buff[5] < 0x0132))
{
Uart0_send_buff[0] = Com0_id;
Uart0_send_buff[1] = 0x03;
Uart0_send_buff[2] = 2 * Uart0_rev_buff[5];
Uart0_send_counter = 2 * Uart0_rev_buff[5] + 3;
switch(tempdress)
{
case 0x0120:
{
Uart0_send_buff = Mkgz_bz & 0xff;
i++;
Uart0_send_buff = (Mkgz_bz >> 8) & 0xff;
i++;
}//后面不放break的目的是继续往下执行
case 0x0122:
{
   Uart0_send_buff = Out_voltage & 0xff;
   i++;
   Uart0_send_buff = (Out_voltage >> 8) & 0xff;
   i++;
}
case 0x0124:
{

Uart0_send_buff = Out_current & 0xff;
i++;
Uart0_send_buff = (Out_current >> 8) & 0xff;
i++;
}
case 0x0126:
{
Uart0_send_buff = Mkzt_bz & 0xff;
i++;
Uart0_send_buff = (Mkzt_bz >> 8) & 0xff;
i++;
}
case 0x0128://这个地址是备用的里面的数据没有意义
{
Uart0_send_buff = 0x00;
i++;
Uart0_send_buff = 0x00;
i++;
}
case 0x012A:
{
Uart0_send_buff = OutX_current & 0xff;
i++;
Uart0_send_buff = (OutX_current >> 8) & 0xff;
i++;
}
case 0x012C:
{
Uart0_send_buff = Jc_voltage & 0xff;
i++;
Uart0_send_buff = (Jc_voltage >> 8) & 0xff;
i++;
}
case 0x012E:
{
Uart0_send_buff = Fc_voltage & 0xff;
i++;
Uart0_send_buff = (Fc_voltage >> 8) & 0xff;
i++;
}
case 0x0130:
{
Uart0_send_buff = 0x00;
i++;
Uart0_send_buff = 0x00;
i++;
}
}
//UCSRB |= (1<<TXCIE)|(1<<TXEN);//发送、发送中断允许
crcresult = getCRC16(Uart0_send_buff,Uart0_send_counter);
Uart0_send_buff[Uart0_send_counter] = crcresult & 0xff;
Uart0_send_buff[Uart0_send_counter+1] = (crcresult >> 8) & 0xff;
Uart0_send_counter = Uart0_send_counter+1;
//Uart0_send_pointer = Uart0_send_buff;
//USART_SendData(USART1, *Uart0_send_pointer++);
//USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
for(i=0;i<Uart0_send_counter+1;i++)
        {
                  USART_SendData(USART1,Uart0_send_buff);
                        
                  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==0);        
        }        
           
     
}
}

void Modbus_Function_6(void)
{
u16 tempdress = 0;
u8 tx_flat = 0;
u16 crcresult;
tempdress = (Uart0_rev_buff[2]<<8) + Uart0_rev_buff[3];
switch(tempdress)
{
case 0x0126:
{

Mkzt_bz = (Uart0_rev_buff[4]<<8) + Uart0_rev_buff[5];
if(user_day > 0)
{
tx_flat = 1;
}
}break;
case 0x012A:
{
OutX_current = (Uart0_rev_buff[4]<<8) + Uart0_rev_buff[5];
if(user_day > 0)
{
tx_flat = 1;
}
}break;
case 0x012C:
{
Jc_voltage = (Uart0_rev_buff[4]<<8) + Uart0_rev_buff[5];
if(user_day > 0)
{
tx_flat = 1;
}
}break;
case 0x012E:
{
Fc_voltage = (Uart0_rev_buff[4]<<8) + Uart0_rev_buff[5];
if(user_day > 0)
{
tx_flat = 1;
}
}break;
case 0x01EE:
{
user_day = (Uart0_rev_buff[4]<<8) + Uart0_rev_buff[5];
tx_flat = 1;
//eeprom_write_word (&user_day_eep,user_day);
}break;
default: //命令码无效不应答
{
tx_flat = 0;
}
}
if(tx_flat == 1)
{
Uart0_send_buff[0] = Com0_id;
Uart0_send_buff[1] = 0x06;
Uart0_send_buff[2] = Uart0_rev_buff[2];
Uart0_send_buff[3] = Uart0_rev_buff[3];
Uart0_send_buff[4] = Uart0_rev_buff[4];
Uart0_send_buff[5] = Uart0_rev_buff[5];
Uart0_send_counter = 6;
//UCSRB |= (1<<TXCIE)|(1<<TXEN);//发送、发送中断允许
crcresult = getCRC16(Uart0_send_buff,Uart0_send_counter);
Uart0_send_buff[Uart0_send_counter] = crcresult & 0xff;
Uart0_send_buff[Uart0_send_counter+1] = (crcresult >> 8) & 0xff;
Uart0_send_counter = Uart0_send_counter+2;
Uart0_send_pointer = Uart0_send_buff;
USART_SendData(USART1, *Uart0_send_pointer++);
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
}
/////////////////////////////////////////////////////////////
void Com0_Communication(void)
{
s8 i =0;
//GPIO_SetBits(GPIOA,GPIO_Pin_2);
if(Uart0_rev_comflag == 1)//接收完成标志=1处理,否则退出
  
  {  //Uart0_rev_comflag=0;
    GPIO_SetBits(GPIOA,GPIO_Pin_2);
  if(Uart0_rev_buff[0] == Com0_id)//地址错误不应答
    {
   
    unsigned short crcresult;
    unsigned char temp[2];
    crcresult = getCRC16(Uart0_rev_buff,Crc_counter-2);
    temp[1] = crcresult & 0xff;
    temp[0] = (crcresult >> 8) & 0xff;
    if((Uart0_rev_buff[Crc_counter-1] == temp[0])&&(Uart0_rev_buff[Crc_counter-2] == temp[1]))//crc校验错误不应答
      {
     //GPIO_SetBits(GPIOA,GPIO_Pin_2);
       // GPIO_ResetBits(GPIOA,GPIO_Pin_2);
     
      switch(Uart0_rev_buff[1])
          {
            case 0x03:
              {
               if(user_day > 0)
                  {
                  
                    Modbus_Function_3();
                 
                  }
              }
          break;
          case 0x06:
              {
              Modbus_Function_6();
              }
          break;
          }
      }
    }
  //Uart0_rev_comflag = 0;
  for(i = 100;i > -1;i--)
      {
      Uart0_rev_buff = 0;
      }
  }
}


void Delay(vu32 nCount)
{
for(; nCount != 0; nCount--);
}


void RCC_cfg()
{
       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_USART1, ENABLE);
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
}

//IO口配置
void GPIO_cfg()
{
       GPIO_InitTypeDef GPIO_InitStructure;

       GPIO_StructInit(&GPIO_InitStructure);
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
       GPIO_Init(GPIOA , &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
      
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
       GPIO_Init(GPIOA, &GPIO_InitStructure);

}


void USART_cfg()
{
     USART_InitTypeDef USART_InitStructure;
     USART_InitStructure.USART_BaudRate = 9600;
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
     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(USART1, &USART_InitStructure);
     
     USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
     USART_Cmd(USART1, ENABLE);
}

void Timer2_Configuration(void)

{

  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  TIM_DeInit(TIM2);

  TIM_TimeBaseStructure.TIM_Period=8;

  TIM_TimeBaseStructure.TIM_Prescaler=(36000-1);

  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);

  TIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除更新标志位

  //TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);

  TIM_Cmd(TIM2,DISABLE);

}



void NVIC_Configuration(void)//定时器2和串口1中断配置

{

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0);

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);//NVIC_Init函数被包含在misc.c文件中。


NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);



}



void TIM2_IRQHandler(void)
{   

  if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//检查溢出信号

  {  
   
    TIM_ITConfig(TIM2,TIM_IT_Update,DISABLE);
    TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除溢出标志
    TIM_Cmd(TIM2,DISABLE);
  }
     
     Uart0_rev_comflag=1;
   
}

void USART1_IRQHandler(void)
{
      TIM_Cmd(TIM2,DISABLE);
     
   
      if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET) //中断产生
    {  
      
      USART_ClearITPendingBit(USART2,USART_IT_RXNE); //清除中断标志
      Uart0_rev_buff[Uart1_Rx_Num] = USART_ReceiveData(USART2);
      Uart1_Rx_Num++;
      //Crc_counter=Uart1_Rx_Num-1;
      TIM_Cmd(TIM2,ENABLE);
      TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
      
    }
   

}
沙发
长缨在手|  楼主 | 2014-8-4 22:20 | 只看该作者
1.定时器2的中断好像跳不出来
2.我串口接收中断的意思是想等数据全接受完了,定时器中断超过4ms产生标志位Uart0_rev_comflag=1,可是调试的时候为什么Uart0_rev_comflag不等于1啊?????

使用特权

评论回复
板凳
ieexplorer| | 2014-8-5 00:17 | 只看该作者
本帖最后由 ieexplorer 于 2014-8-5 00:18 编辑

太长了,也不懂modbus,不过我觉得至少Uart0_rev_comflag前要加volatile吧

使用特权

评论回复
地板
airwill| | 2014-8-5 10:59 | 只看该作者
程序太长了, 什么思路都不说, 光一个 "不行" 让人家怎么猜得到你的问题?
象这种问题, 你应该把你的编程思路说清楚, 大家帮你参谋参谋.
至于调试, 还得靠你自己, 比较你有程序, 有板子和环境, 可以跟踪调试看波形, 而别人只能靠猜!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

27

帖子

1

粉丝