3315|0

6069

帖子

4

TA的资源

版主

楼主
 

[GD32F350作品提交] 基于GD32F350的工业控制设备 [复制链接]

本帖最后由 damiaa 于 2018-10-17 15:42 编辑

              [GD32F350作品提交] 基于GD32F350的工业控制设备     
                                      
硬件主要构成:
   GD32F350为CPU
   16路输入 可以作为按键 也可以作为传感器输入采集 软件捕获电平和(按下,弹起)
   16路输出 继电器
   串口输出提示信息,也可以和屏进行接口。

软件构成:      
   GD32基本库
   systick.h   systick.c 有关systick定时的函数
   gd32f3x0_libopt   
   gd32f3x0_it.h  gd32f3x0_it.c 有关定时中断,串口中断,systick中断的函数调用。
   comm.h 公共结构的定义 和宏定义
   gd32board.h gd32board.c 板子基本输入输出,定时器,串口等设备的初始化,输入输出基本函数定义。
   devicecontrol.h devicecontrol.c 软件用到的一些基本函数,比如输入检测,软定时器实现等。
   main.c 主函数,所有实现。
             主要是针对GD32F350实现一个小型的工业控制主板的基本框架,目前先实现一个小的功能:加工设备的运行(按键,传感器,      输 出继电器控制电机启停,串口输出信息等)。


使用硬件资源:
串口0,1。
systick
定时器1,2
GPIO 输入输出IO口


软件详细实现
1,软定时器:
    这个是利用GD32F350硬件定时器1实现N个软定时器,充分利用了CPU的资源,达到了扩充工业控制用定时器功能的目的:
 1,      comm.h中定义结构
      #define SOFTTIMMAX 10
      typedef struct
      {
           uint32_t tim[SOFTTIMMAX];  //10ms*tim
      } SOFTTIMERSTR;

       devicecontrol.h中申明
       uint8_t SetSoftTimer(uint8_t num,uint32_t val);
       uint8_t DecSoftTimer(uint8_t num);
      uint8_t IfSoftTimer(uint8_t num);

      devicecontrol.c中定义:
      SOFTTIMERSTR SOFTTIMER;
  uint8_t SetSoftTimer(uint8_t num,uint32_t val)//设置定时器值
  {
         if(num >= SOFTTIMMAX) return 0;
         SOFTTIMER.tim[num]=val;
         return 1;
  }      
      uint8_t ClrSoftTimer(uint8_t num)  //退出定时器
  {
         if(num >= SOFTTIMMAX) return 0;
         SOFTTIMER.tim[num]=0;
         return 1;
  }
  uint8_t DecSoftTimer(uint8_t num)//设置定时器条件下定时器工作
  {
         if(num >= SOFTTIMMAX) return 0;
         if(SOFTTIMER.tim[num] >1)
                SOFTTIMER.tim[num] -=1;
         return 1;
  }      
  uint8_t IfSoftTimer(uint8_t num)//判断定时器是在定时还是溢出还是退出了。
  {
         if(num >= SOFTTIMMAX) return 99;
         if(SOFTTIMER.tim[num] > 1)
                return 1;
         if(SOFTTIMER.tim[num] == 1)
                return 0;         
             if(SOFTTIMER.tim[num] == 0)
               return 2;
  } 
     devicecontrol.h包含到gd32f3x0_it.c 中gd32f3x0_it.c调用
     void TIMER1_IRQHandler()
     {
        uint8_t i;
        for(i=0;i                 DecSoftTimer(i);
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
      }

      main.c使用时包含devicecontrol.h
      SetSoftTimer(0,6000);调用软定时器0,并设定时间为6000*10MS
      if(IfSoftTimer(0) == 0)        判断 定时器是否溢出。这里定义了SOFTTIMMAX个软定期器可以调用。
      软件定时器好处:1,充分利用硬件定时器资源扩充定时器。2,随意扩充定时器。3,代替传统的延时到达系统响应不停滞。
2,输入检测:    comm.h中定义结构
    typedef struct
   {
          uint8_t     lastedgelevel;            //1 high 0 low  
          uint8_t     nowedgelevel;            //1 high 0 low  
          uint8_t     act;               //result;0x4 no act 0 tolow 1 tohigh
    }KEYDEF;
     devicecontrol.c中定义:
     KEYDEF KeyorIN[16];
     void KEYorINCheck(void)
     {
                uint8_t i,t=16;        
                for(i=0;i                 {               
                        KeyorIN.chktimes <<=1;         
                        if(GetKEYLINEStatus(i)){        KeyorIN.chktimes +=1;        }
                }
                for(i =0;i                 {        
                        if((KeyorIN.chktimes & 0xffffffff)==0 )               
                                KeyorIN.nowedgelevel =LOWLEVEL;         //low
                        if((KeyorIN.chktimes & 0xffffffff)==0xffffffff)        
                                        KeyorIN.nowedgelevel =HIGHLEVEL;                 //high               
                        if((HIGHLEVEL == KeyorIN.lastedgelevel)&&(LOWLEVEL == KeyorIN.nowedgelevel))        //down
                        {
                                        KeyorIN.lastedgelevel =LOWLEVEL;                        
                                        KeyorIN.act =TOLOW ;               
                        }        
                        if((LOWLEVEL == KeyorIN.lastedgelevel)&&(HIGHLEVEL == KeyorIN.nowedgelevel))        //up               
                        {
                                        KeyorIN.lastedgelevel = HIGHLEVEL;
                                        KeyorIN.act =TOHIGH;        
                        }
                }               
        }

        uint8_t IfKeyorIN_LEVEL(uint8_t num)
       {
             return KeyorIN[num].lastedgelevel;
        }

        uint8_t IfKeyorIN_ACT(uint8_t num)
        {
             return KeyorIN[num].act;
         }
        gd32f3x0_it.c调用
       void TIMER2_IRQHandler()
       {
             KEYorINCheck();
             timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
       }

       main.c使用时包含devicecontrol.h有16个输入可以检测 comm.h中定义了
       #define IN1 0
       #define IN2 1
       。。。
      #define IN15 14
      #define IN16 15

       调用入  if(IfKeyorIN_ACT(IN1) == TOLOW) {。。。}      
3,输出
gd32board.c中定义 main.c中调用:有16个输出 comm.h中定义了
#define IN1 0
#define IN2 1
。。。
#define IN15 14
#define IN16 15

void gd_output(uint8_t num,uint8_t ONorOff)
{
          if(ONorOff)
                        GPIO_BOP(OUTPUT_PORT[num]) =  OUTPUT_PIN[num];
                else
                        GPIO_BC( OUTPUT_PORT[num]) =  OUTPUT_PIN[num];
}
如: gd_output(OUT2,ON);//OUT2

4,串口输出提示    
   gd32board.c中定义 初始化函数,主 main.c中调用
中断中实现中断函数 主主 main.c中调用输出打印等
      void gd_eval_com_init(uint32_t com)   
     {
         。。。
      }                  
      void USART1_IRQHandler(void)
       {
           if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_RBNE)){
           /* receive data */
           uartbuf1.receiver_buffer[uartbuf1.rxcount++] = (usart_data_receive(EVAL_COM1) & 0x7F);
            if(uartbuf1.rxcount == uartbuf1.receivesize){
            usart_interrupt_disable(EVAL_COM1, USART_INT_RBNE);
        }
    }

    if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_INT_FLAG_TBE)){
           /* transmit data */
            usart_data_transmit(EVAL_COM1, uartbuf1.transmitter_buffer[uartbuf1.txcount++]);
            if(uartbuf1.txcount == uartbuf1.transfersize){
               usart_interrupt_disable(EVAL_COM1, USART_INT_TBE);
          }
       }
     }
     void USART2_IRQHandler(void)
     {
        if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_RBNE)){
         /* receive data */
         uartbuf2.receiver_buffer[uartbuf2.rxcount++] = (usart_data_receive(EVAL_COM2) & 0x7F);
         if(uartbuf2.rxcount == uartbuf2.receivesize){
            usart_interrupt_disable(EVAL_COM2, USART_INT_RBNE);
        }
     }

     if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_TBE)){
           /* transmit data */
           usart_data_transmit(EVAL_COM2, uartbuf2.transmitter_buffer[uartbuf2.txcount++]);
          if(uartbuf2.txcount == uartbuf2.transfersize){
             usart_interrupt_disable(EVAL_COM2, USART_INT_TBE);
          }
       }
     }
如:main.c中调用 printf("\n\r\turn on!!!");

5,中程序中工业控制流程设计(采用状态机)
     int main(void)
    {
        //systick_config();
         gd_eval_led_init(LED1);
         gd_eval_led_init(LED2);
         gd_eval_led_init(LED3);
          gd_eval_key_init(KEY_WAKEUP, KEY_MODE_GPIO);
          gd_KeyorIn_initN();
          gd_output_initN();
          timer1_init();
          timer2_init();
          /* USART interrupt configuration */
          //nvic_irq_enable(USART0_IRQn, 0, 0);
           nvic_irq_enable(USART1_IRQn, 0, 0);
          gd_eval_com_init(EVAL_COM2);
          /* enable USART TBE interrupt */  
          usart_interrupt_enable(EVAL_COM2, USART_INT_TBE);
          /* wait until USART send the transmitter_buffer *
          usart_interrupt_enable(EVAL_COM2, USART_INT_RBNE);
           beginwork1();
           while (1)
           {
                        work1();
           }
     }
    void beginwork1(void)  //
    {
        gd_output(OUT1,OFF);//OUT1 传动电机
        gd_output(OUT2,OFF);//OUT2 下压电机
        gd_output(OUT3,OFF);//OUT3  卸载电机
        workstats =1;

     }        
     void work1(void)
    {
        switch(workstats)
        {
                case stats1:
                        if(IfKeyorIN_ACT(IN1) == TOLOW)   //            分配启动键为IN1  
                        {        
                                workstats =2;
                                printf("\n\r\turn on!!!");
                                gd_eval_led_on(LED2);
                                gd_output(OUT1,ON);//OUT1
                        }
                        else
                        {
                                gd_eval_led_off(LED2);
                        }        
                    break;
                case stats2:
                        if(IfKeyorIN_ACT(IN3) == TOLOW) //分配IN3为前置传感器
                        {
                                         gd_output(OUT2,ON);//OUT2
                              SetSoftTimer(0,6000);//
                             gd_output(OUT2,OFF);//OUT2
                               workstats =3;
                                   printf("moto1 on!!!");
                        }  
                        if(IfKeyorIN_ACT(IN2) == TOLOW) //分配IN2为停止键
                        {
                                workstats =5;ClrSoftTimer(0);
                        }   
                       if(IfSoftTimer(0) == 0)        
                            {workstats =3;   ClrSoftTimer(0);}        
                        break;
                case stats3:
                      if(IfKeyorIN_ACT(IN4) == TOLOW) //分配IN4为后置传感器
                      {
                            printf("moto2 on!!!");
                            gd_output(OUT2,OFF);//OUT2
                             gd_output(OUT3,ON);//OUT3
                             SetSoftTimer(0,6000);//
                             gd_output(OUT3,OFF);//OUT3
                        }
                        if(IfKeyorIN_ACT(IN2) == TOLOW) //
                        {
                                workstats =5;ClrSoftTimer(0);
                        }               
                        if(IfSoftTimer(0) == 0)        
                            {workstats =4;   ClrSoftTimer(0);}                     
                        break;
                case stats4:
                    gd_output(OUT1,OFF);//OUT1
                    gd_output(OUT2,OFF);//OUT2
                    gd_output(OUT3,OFF);//OUT3
                    workstats =1;
                    break;
                case stats5:
                    printf("moto1,moto2,moto3 off!!!");
                    gd_output(OUT1,OFF);//OUT1
                    gd_output(OUT2,OFF);//OUT2
                    gd_output(OUT3,OFF);//OUT3
                    gd_eval_led_on(LED3);
                    delay_ms(100);
                    gd_eval_led_off(LED3);
                     workstats =1;
                    break;
                default:
                        workstats =1;        
                  break;
            }        
        }            
总结:该状态机形式的工业控制设备框架灵活多变,调试容易,小巧灵活。很容易构成一台新的工业控制设备。  
程序附件:
GD32F3x0_Firmware_Library_V1.0.0_Colibri-F350aa.zip (320.16 KB, 下载次数: 9)

6,硬件原理图相关:
    输入电路   
    输出电路
   
    串口电路
   
    CPU电路:目前采用通用的核心板。   
   电路原理图附件:
      I.SchDoc (334 KB, 下载次数: 5)
      O.SchDoc (124 KB, 下载次数: 5)
      uarttt.SchDoc (153 KB, 下载次数: 5)












此帖出自GD32 MCU论坛
点赞 关注(1)
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表