本帖最后由 tlled 于 2019-6-29 08:38 编辑
选择第二个题目,主题B:冗余执行系统来完成设计
一、题目B的基础要求:
1. 两个MCU分别作为主控制器与从控制器, 接了同一个ADC输入, 同一个LED输出. 正常情况下主控器完成如下控制模式:
ADC读值分为三个档位
ADC的输入建议使用电位器进行控制, LED输出控制建议使用负逻辑控制(输出低LED亮)。
2. 从控制器同时读取ADC的读数并监视LED输出情况, 监视的状态可以查看, 如接有小屏幕或者通过串口输出当前状态[ADC读数, LED输出状态], 刷新间隔2秒或更短。
二、内容
2.1、项目方案的构想;
主副MCU同时检测ADC电压值和LED等点亮状态,和题目要求的状态是否一致。同时,主、副MCU之间通过串口通信来监听双方运行状态,如果长时间没有收到对方应答数据,可能对方系统出现故障,要显示报警,并根据检测数据进行主副控制切换。在主和副MCU上都有一个LCD显示屏来显示采集的ADC电压值和LED的运行状态。
方案框图:
2.2、设计、搭建;
2.2.1、硬件资源:
a> STC8A8K64单片机,
b> 12864 LCD显示屏
2.2.2、设计的硬件电路
a> 设计硬件平台的电路图
b> LED灯检测电路
在调试过程中,发现R2和R3电阻阻值太大容易采集数据错误,后将电阻分别改成100K和200K。
c> 从机控制主机复位电路
从机通过P3.7口来控制光耦,去控制主机复位电路,达到主机复位目的。
2.2.3、设计的板子运行图片
搭建开发环境,使用keil c51来开发
2.3、调试流程;
2.3.1、第一步、先单机运行题目要求的项目。
项目中的参数和条件设定
a> 比较门限设置:
对门限值的设定,使用MCU的ADC是12位,采样出来的最大数值是0xFFF(4095),把4095等分3分,取两个值最为门限。
#define LIMIT_A 1365
#define LIMIT_B 2730
b> 执行流程图
c、具体代码实现 void fun_adc(void)
{
uchar i;
uchar led_status;
uint adc_temp=0;
uchar adc_val[5];
uchar adc_vol[10];
uint temp=0;
long adc_vot=0;
uint adc_vol_temp=0;
if(adc_fin_flag==1)
{
adc_fin_flag=0;
//-------------------------------------------
//ADC采样
ADCRead();
ADCRead();
adc_temp=0;
for(i=0;i<16;i++)
{
adc_temp+=ADCRead();
}
adc_temp>>=4;
adc_temp = ADCRead(); //读ADC值
//串口输出ADC采集的数据
send_char_com(0x2a);
send_char_com(adc_temp>>8);
send_char_com(adc_temp);
send_char_com(0x2b);
send_char_com(adc_temp/1000);
send_char_com((adc_temp%1000)/100);
send_char_com(((adc_temp%1000)%100)/10);
send_char_com(((adc_temp%1000)%100)%10);
//数据处理
adc_vol[0]=adc_data_convert(adc_temp/1000);
adc_vol[1]=adc_data_convert((adc_temp%1000)/100);
adc_vol[2]=adc_data_convert(((adc_temp%1000)%100)/10);
adc_vol[3]=adc_data_convert(((adc_temp%1000)%100)%10);
adc_vol[4]='\0';
adc_val[0]=adc_data_convert((adc_temp>>8)&0x0f);
adc_val[1]=adc_data_convert((adc_temp>>4)&0x0f);
adc_val[2]=adc_data_convert((adc_temp)&0x0f);
adc_val[3]='\0';
//LCD显示屏显示采集的数据
LCD_P8x16Str(0,2,"ADC:0x");
LCD_P8x16Str(48,2,adc_val);
LCD_P8x16Str(72,2,"=>");
LCD_P8x16Str(88,2,adc_vol);
//
if(adc_temp<LIMIT_A)
{
LED0=1;
led_start_flag=0;
led_status=0;
}
else if( (adc_temp>=LIMIT_A)&(adc_temp<=LIMIT_B) ) //LED0--3Hz闪烁
{
led_start_flag=1; //启动LED闪烁
if(led_finsh_flag==1)
{
led_finsh_flag=0;
LED0=~LED0;
led_status=1;
}
}
else if(adc_temp>LIMIT_B)
{
LED0=0;
led_start_flag=0;
led_status=2;
}
//LCD显示屏显示LED状态
LCD_P8x16Str(0,3,"LED:");
switch (led_status)
{
case 0:
LCD_P8x16Str(33,3,"CLOSE ");
break;
case 1:
if(LED0==0)
{
LCD_P8x16Str(33,3,"3Hz FLASH ");
}
else
{
LCD_P8x16Str(33,3," ");
}
break;
case 2:
LCD_P8x16Str(33,3,"OPEN ");
break;
default:
break;
}
}
}
2.4、制作心得和总结等;
通过这次制作,学习了冗余系统知识,让我认识到了,在特别关键的设备中,冗余执行系统设计的重要性。
2.5、视频展示
2.5.1、调试完主机运行的视频。
手机拍摄的,效果不是太好。
2.5.2、最终的视频
视频操作的步骤:
1、上电后,主控制器控制LED灯,从控制器处于备用状态。旋转电位器主机LCD上显示ADC电压值和LED灯状态,从控制器检测主控制器和LED灯工作状态。
2、按主控制器板上的按键K1,模拟故障1,主控制器不控制LED灯,从机检测到错误后,来控制LED。
3、按主控制器板上的按键K2,退出模拟故障1,恢复正常,从控制器检测到主控制器恢复正常后,从控制器放弃控制LED灯,由主控制器控制。
4、按下主控制器板上的按键K3,来模拟故障2,持续点亮LED,从控制器检测到故障后,发出复位主控制信号,主控制器重启后重新来控制LED灯,从控制器处于备用状态,整个过程完成。
|
不懂这些