【21ic第三届设计大赛】+ 冗余执行系统

[复制链接]
1497|9
 楼主 | 2019-5-31 16:14 | 显示全部楼层 |阅读模式
本帖最后由 tlled 于 2019-6-13 11:29 编辑

    选择第二个题目,主题B:冗余执行系统来完成设计
一、题目B的基础要求:   
    1. 两个MCU分别作为主控制器与从控制器, 接了同一个ADC输入, 同一个LED输出. 正常情况下主控器完成如下控制模式:
    ADC读值分为三个档位
         06104.png
        ADC的输入建议使用电位器进行控制, LED输出控制建议使用负逻辑控制(输出低LED亮)。

    2. 从控制器同时读取ADC的读数并监视LED输出情况, 监视的状态可以查看, 如接有小屏幕或者通过串口输出当前状态[ADC读数, LED输出状态], 刷新间隔2秒或更短。

   二、内容

    2.1、项目方案的构想;
        主副MCU同时检测ADC电压值和LED等点亮状态,和题目要求的状态是否一致。同时,主、副MCU之间通过串口通信来监听双方运行状态,如果长时间没有收到对方应答数据,可能对方系统出现故障,要显示报警,并根据检测数据进行主副控制切换。在主和副MCU上都有一个LCD显示屏来显示采集的ADC电压值和LED的运行状态。
        方案框图:
         06133.png

    2.2、设计、搭建;               

        2.2.1、硬件资源:
        a> STC8A8K64单片机,
        b> 12864 LCD显示屏

        2.2.2、设计的硬件电路
        a> 设计硬件平台的电路图
         3.png
        
        b> LED灯检测电路
         06111.png
        在调试过程中,发现R2和R3电阻阻值太大容易采集数据错误,后将电阻分别改成100K和200K。
        c> 从机控制主机复位电路
        从机通过P3.7口来控制光耦,去控制主机复位电路,达到主机复位目的。
         06131.png
        2.2.3、设计的板子运行图片
         2.jpg
         1.jpg
        搭建开发环境,使用keil c51来开发
         4.png
        
    2.3、调试流程;

    2.3.1、第一步、先单机运行题目要求的项目。

    项目中的参数和条件设定
    a> 比较门限设置:
    对门限值的设定,使用MCU的ADC是12位,采样出来的最大数值是0xFFF(4095),把4095等分3分,取两个值最为门限。
    #define    LIMIT_A            1365
    #define    LIMIT_B            2730  

    b> 执行流程图
    06132.png       

    c、具体代码实现   
  1. void fun_adc(void)
  2. {
  3.         uchar i;
  4.         uchar led_status;
  5.         uint adc_temp=0;
  6.         uchar adc_val[5];
  7.         uchar adc_vol[10];

  8.         uint temp=0;
  9.         
  10.         long adc_vot=0;
  11.         uint adc_vol_temp=0;
  12.         if(adc_fin_flag==1)
  13.         {
  14.                 adc_fin_flag=0;
  15.                 //-------------------------------------------
  16.                 //ADC采样
  17.                 ADCRead();
  18.                 ADCRead();
  19.                 adc_temp=0;
  20.                 for(i=0;i<16;i++)
  21.                 {
  22.                         adc_temp+=ADCRead();
  23.                 }
  24.                 adc_temp>>=4;
  25.                 adc_temp = ADCRead();                //读ADC值
  26.                 //串口输出ADC采集的数据
  27.                 send_char_com(0x2a);  
  28.                 send_char_com(adc_temp>>8);
  29.                 send_char_com(adc_temp);
  30.         
  31.                 send_char_com(0x2b);
  32.                 send_char_com(adc_temp/1000);
  33.                 send_char_com((adc_temp%1000)/100);
  34.                 send_char_com(((adc_temp%1000)%100)/10);
  35.                 send_char_com(((adc_temp%1000)%100)%10);
  36.                 //数据处理
  37.                 adc_vol[0]=adc_data_convert(adc_temp/1000);
  38.                 adc_vol[1]=adc_data_convert((adc_temp%1000)/100);
  39.                 adc_vol[2]=adc_data_convert(((adc_temp%1000)%100)/10);
  40.                 adc_vol[3]=adc_data_convert(((adc_temp%1000)%100)%10);
  41.                 adc_vol[4]='\0';
  42.         
  43.                 adc_val[0]=adc_data_convert((adc_temp>>8)&0x0f);
  44.                 adc_val[1]=adc_data_convert((adc_temp>>4)&0x0f);
  45.                 adc_val[2]=adc_data_convert((adc_temp)&0x0f);
  46.                 adc_val[3]='\0';
  47.                 //LCD显示屏显示采集的数据
  48.                 LCD_P8x16Str(0,2,"ADC:0x");
  49.                 LCD_P8x16Str(48,2,adc_val);        
  50.                 LCD_P8x16Str(72,2,"=>");        
  51.                 LCD_P8x16Str(88,2,adc_vol);        
  52.                 //
  53.                 if(adc_temp<LIMIT_A)
  54.                 {
  55.                         LED0=1;
  56.                         led_start_flag=0;        
  57.                         led_status=0;
  58.                 }
  59.                 else if( (adc_temp>=LIMIT_A)&(adc_temp<=LIMIT_B) )  //LED0--3Hz闪烁
  60.                 {
  61.                         led_start_flag=1;                //启动LED闪烁
  62.                         if(led_finsh_flag==1)
  63.                         {
  64.                                 led_finsh_flag=0;
  65.                                 LED0=~LED0;
  66.                                 led_status=1;
  67.                         }
  68.                 }
  69.                 else if(adc_temp>LIMIT_B)
  70.                 {
  71.                         LED0=0;
  72.                         led_start_flag=0;
  73.                         led_status=2;
  74.                 }
  75.                 //LCD显示屏显示LED状态
  76.                 LCD_P8x16Str(0,3,"LED:");
  77.                 switch (led_status)
  78.     {
  79.             case 0:
  80.                                 LCD_P8x16Str(33,3,"CLOSE     ");
  81.                     break;
  82.             case 1:
  83.                                 if(LED0==0)
  84.                                 {
  85.                                         LCD_P8x16Str(33,3,"3Hz FLASH ");
  86.                                 }
  87.                                 else
  88.                                 {
  89.                                         LCD_P8x16Str(33,3,"          ");
  90.                                 }
  91.                                 
  92.                     break;
  93.                         case 2:
  94.                                 LCD_P8x16Str(33,3,"OPEN      ");
  95.                     break;
  96.             default:
  97.                     break;
  98.     }
  99.         }
  100. }
复制代码
  

      
        
    2.4、作品展示、制作心得和总结等;


    2.5、视频展示
    2.5.1、调试完主机运行的视频。
    手机拍摄的,效果不是太好。
    https://v.youku.com/v_show/id_XNDIyMTY4MzA0OA==.html?spm=a2h0j.11185381.listitem_page1.5!2~A

    06101.png

    https://v.youku.com/v_show/id_XNDIyMTg1MjE1Ng==.html?spm=a2hzp.8244740.0.0

    06102.png

    2.5.2、最终的视频
    视频操作的步骤:
    1、上电后,主控制器控制LED灯,从控制器处于备用状态。旋转电位器主机LCD上显示ADC电压值和LED灯状态,从控制器检测主控制器和LED灯工作状态。
    2、按主控制器板上的按键K1,模拟故障1,主控制器不控制LED灯,从机检测到错误后,来控制LED。
    3、按主控制器板上的按键K2,退出模拟故障1,恢复正常,从控制器检测到主控制器恢复正常后,从控制器放弃控制LED灯,由主控制器控制。
    4、按下主控制器板上的按键K3,来模拟故障2,持续点亮LED,从控制器检测到故障后,发出复位主控制信号,主控制器重启后重新来控制LED灯,从控制器处于备用状态,整个过程完成。
    https://v.youku.com/v_show/id_XNDIyNTkyOTMzMg==.html?spm=a2h3j.8428770.3416059.1





使用特权

评论回复

评论

tlled 2019-6-16 14:10 回复TA
@z18028685796 :参与活动,边学边用。 
z18028685796 2019-6-10 19:01 回复TA
不懂这些 
| 2019-5-31 19:11 | 显示全部楼层
建议不仅仅通过串口来互相检测, 还能直接通过输出口来检测, 从机平时IO配为输入检测主机对LED的输出控制. 即行为级别的监控. 个人建议供参考!

使用特权

评论回复
 楼主 | 2019-6-10 08:08 | 显示全部楼层
zhanzr21 发表于 2019-5-31 19:11
建议不仅仅通过串口来互相检测, 还能直接通过输出口来检测, 从机平时IO配为输入检测主机对LED的输出控制.  ...

谢谢指点,我也学习下

使用特权

评论回复
 楼主 | 2019-6-10 08:10 | 显示全部楼层
本帖最后由 tlled 于 2019-6-10 17:18 编辑

[media=x,500,375][/media]测试视频
https://v.youku.com/v_show/id_XNDIyMTg1MjE1Ng==.html?spm=a2hzp.8244740.0.0

视频连接怎么发不了呢

修改后可以了

使用特权

评论回复
 楼主 | 2019-6-11 08:33 | 显示全部楼层
主从MCU对LED灯的状态的检测,在程序中单独检测IO口输出电平状态不能直接反应实际LED的输出状态,所有在硬件上增加下面电路 06111.png
主从MCU都可以直接控制DL1灯点亮,主从MCU控制IO口都设置成开漏模式。MCU控制IO口设置输出低电平,不影响对方的控制。
在控制DL1点亮的同时,主从ADC检测控制IO口引脚的电压,在DL导通时,ADC检测到电压0V,在DL1关闭时,ADC检测到的电压有2V左右。
电路上R2和R3串联,电阻值很大,不会点亮DL1灯。

使用特权

评论回复
| 2019-6-12 09:25 | 显示全部楼层
学习下

使用特权

评论回复
 楼主 | 2019-6-13 08:41 | 显示全部楼层
从机控制主机复位电路的实现 06131.png

使用特权

评论回复
 楼主 | 2019-6-16 14:08 | 显示全部楼层

共同学习

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

关闭

热门推荐上一条 /4 下一条

在线客服 快速回复 返回顶部 返回列表