一、本项目意义:实现通过USART通信,通过帧信息控制通过信号机状态,可以设置灯丝故障,设置区间状态,点灯信息基于Flash内的固定信息,与帧序列无直接交互,相当于实现了电子连锁,可用于教学实验。
二、CV表内容:应该包括信号设备类型,设备编号,设备灯丝状态(代替灯丝继电器),设备故障设置位(用于教学设置故障),通过信号机需要保存区间内的占用情况
三、CV表示意图
- #define Device_Type_Addr 0X08020000 //设备类型地址
- #define QJ_Position_Addr 0X08020002 //信号机区间位置
- #define DS_State_Addr 0X08020004 //01短路;10断路
- #define Fault_Setting_Addr 0X08020006 //故障设置地址:0000 0111(蓝白红/绿黄红)
- #define Recerve_Code1_Addr 0x08020008 //保留字节1~4
- #define Recerve_Code2_Addr 0x0802000a
- #define Recerve_Code3_Addr 0x0802000c
- #define Recerve_Code4_Addr 0x0802000e
- #define FQ_State_1_8_Addr 0x08020010 //区间1~8占用情况
- #define FQ_State_9_16_Addr 0x08020012
- #define FQ_State_17_24_Addr 0x08020014
- #define FQ_State_25_32_Addr 0x08020016
- #define FQ_State_33_40_Addr 0x08020018
- #define FQ_State_41_48_Addr 0x0802001a
- #define FQ_State_49_56_Addr 0x0802001c
- #define FQ_State_57_64_Addr 0x0802001e
复制代码
单片机源程序如下:- #include "led.h"
- #include "delay.h"
- #include "sys.h"
- #include "usart.h"
- #include "stmflash.h"
- #include "assist_function.h"
- #include "adc.h"
- // v1.2.3 改进电灯逻辑,实现参数化
- //已完全实现Fault标志位的功能,故障自动转移亮灯
- //存在问题:亮灯转移所发布的广播信息如何生成
- //解决方法:先打草稿模拟情景,总结得,转移信息只与最终显示状态相关,即,转黄,转红,红转
- //具体思考跨区情况下,信息帧的生成有何区别
- int main(void)
- {
-
- //后期添加的变量; PS不能全大写变量名;
-
- u8 key;
-
- //u16 datatemp[8];//测试用变量
- //datatemp[0] = QJ_Situation();//测试语句
- //printf("\n\rInfo= %08x\n\r",datatemp[0]);//测试语句
- //后期添加的变量
- delay_init(); //延时函数初始化
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
- uart_init(9600); //串口初始化为9600
- LED_Init(); //初始化与LED连接的硬件接口
- Write_CV(0x03,Device_Type_Addr);
- Adc_Init();
- DMA_Init2();
- ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开始采集adc
-
-
- while(1)
- {
- RS485_Receive_Data(rs485buf,&key);
- //取出通信帧内容
- GetFrame();
-
- //通信协议内容识别逻辑
-
- //非广播命令 及 CRC校验 及 设备类型 及 密钥检验 及 是否收到新的帧
- //CRCCHECK = CRCcheck();return true/false;
- CRCcheck();
- if( CRCCHECK && TypeFrame == TongGuoXHJ && AccessFrame == 0xAA && key)
- {
- if(OrderFrame == 0x01)
- {
- //修改flash设备编号
- //传回相应帧;void SendBackMessage(0x01);根据参数判断需要的返回信息,自动形成格式,提取flash中内容填充帧序列;
- Write_CV(SerailFrame,QJ_Position_Addr);
- SendBackFrame[0] = 0x10;
- SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
- SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
- SendBack();
- }
-
- else if(SerailFrame == STMFLASH_ReadHalfWord(QJ_Position_Addr))
- {
- switch(OrderFrame)
- {
- case 0x02:
- //读状态:命令+密钥(0xAA)+设备类型+设备编号+00+00+CRC
- //返回格式:命令+设备类型+设备编号+灯丝状态+故障信息+00+CRC
- //参数:cv位置
- SendBackFrame[0] = 0x20;
- SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
- SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
- SendBackFrame[3] = STMFLASH_ReadHalfWord(DS_State_Addr);
- SendBackFrame[4] = STMFLASH_ReadHalfWord(Fault_Setting_Addr);
- SendBack();
- break;
- case 0x03:
- //写状态:命令+密钥(0xAA)+设备类型+设备编号+故障信息+00+CRC
- //返回格式:命令+设备类型+设备编号+故障信息+00+00+CRC
- //参数:故障内容
-
- Write_CV(Context5Frame,Fault_Setting_Addr);
- SendBackFrame[0] = 0x30;
- SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
- SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
- SendBackFrame[3] = STMFLASH_ReadHalfWord(Fault_Setting_Addr);
- SendBack();
- break;
- case 0x04:
- //读区间状态:命令+密钥(0xAA)+设备类型+设备编号+00+00+CRC
- //返回格式:命令+设备类型+设备编号+最近四个分区的状况+00+00+CRC
- //返回此区间前4个区间的状态
- SendBackFrame[0] = 0x40;
- SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
- SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
- SendBackFrame[3] = QJ_Situation();
- SendBack();
- break;
-
- default:break;
-
- }
- }
-
- }
-
- //区间信息广播帧;不产生返回帧
- if(OrderFrame == 0x05 && CRCCHECK && TypeFrame == TongGuoXHJ && key)
- {
- //第一组数据区间1~8;9~16;17~24
- if(AccessFrame == 0x01)
- {
- Write_CV(rs485buf[3],FQ_State_1_8_Addr);
- Write_CV(rs485buf[4],FQ_State_9_16_Addr);
- Write_CV(rs485buf[5],FQ_State_17_24_Addr);
- }
- //第二组数据区间25~32;33~40;41~48
- if(AccessFrame == 0x02)
- {
- Write_CV(rs485buf[3],FQ_State_25_32_Addr);
- Write_CV(rs485buf[4],FQ_State_33_40_Addr);
- Write_CV(rs485buf[5],FQ_State_41_48_Addr);
- }
- //第三组数据区间49~56;57~64
- if(AccessFrame == 0x03)
- {
- Write_CV(rs485buf[3],FQ_State_49_56_Addr);
- Write_CV(rs485buf[4],FQ_State_57_64_Addr);
- }
- //单帧区域广播;命令+密钥(帧类型)+设备类型+区间Sector(0~7;可扩展)+区间信息+00+CRC
- if(AccessFrame == 0x10)
- {
- Write_CV(Context5Frame,FQ_State_1_8_Addr * 2 * (int)SerailFrame);//待测试(int)SerailFrame
- }
- printf("\n\rCopy\n\r");//TEST
- }
- //读取电灯信息;判断并点灯
- if( key ) LightLogic();
-
-
- }
- }
复制代码
全部资料51hei下载地址:
v1.2.4点灯转移需要断线情况下自动实现.7z
(206.73 KB, 下载次数: 10)
|