找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3221|回复: 1
打印 上一主题 下一主题
收起左侧

基于STM32 usart串口的通过信号机—CV表的设计 附程序

[复制链接]
跳转到指定楼层
楼主
一、本项目意义:实现通过USART通信,通过帧信息控制通过信号机状态,可以设置灯丝故障,设置区间状态,点灯信息基于Flash内的固定信息,与帧序列无直接交互,相当于实现了电子连锁,可用于教学实验。
二、CV表内容:应该包括信号设备类型,设备编号,设备灯丝状态(代替灯丝继电器),设备故障设置位(用于教学设置故障),通过信号机需要保存区间内的占用情况
三、CV表示意图





  1. #define Device_Type_Addr  0X08020000     //设备类型地址
  2. #define QJ_Position_Addr  0X08020002     //信号机区间位置
  3. #define DS_State_Addr  0X08020004        //01短路;10断路
  4. #define Fault_Setting_Addr  0X08020006   //故障设置地址:0000 0111(蓝白红/绿黄红)
  5. #define Recerve_Code1_Addr 0x08020008    //保留字节1~4
  6. #define Recerve_Code2_Addr 0x0802000a
  7. #define Recerve_Code3_Addr 0x0802000c
  8. #define Recerve_Code4_Addr 0x0802000e
  9. #define FQ_State_1_8_Addr 0x08020010     //区间1~8占用情况
  10. #define FQ_State_9_16_Addr 0x08020012
  11. #define FQ_State_17_24_Addr 0x08020014
  12. #define FQ_State_25_32_Addr 0x08020016
  13. #define FQ_State_33_40_Addr 0x08020018
  14. #define FQ_State_41_48_Addr 0x0802001a
  15. #define FQ_State_49_56_Addr 0x0802001c
  16. #define FQ_State_57_64_Addr 0x0802001e
复制代码

单片机源程序如下:
  1. #include "led.h"
  2. #include "delay.h"
  3. #include "sys.h"
  4. #include "usart.h"
  5. #include "stmflash.h"
  6. #include "assist_function.h"
  7. #include "adc.h"

  8. // v1.2.3 改进电灯逻辑,实现参数化
  9. //已完全实现Fault标志位的功能,故障自动转移亮灯
  10. //存在问题:亮灯转移所发布的广播信息如何生成
  11. //解决方法:先打草稿模拟情景,总结得,转移信息只与最终显示状态相关,即,转黄,转红,红转
  12. //具体思考跨区情况下,信息帧的生成有何区别


  13. int main(void)
  14. {       
  15.        
  16. //后期添加的变量;        PS不能全大写变量名;
  17.          
  18.          u8 key;
  19.        
  20.          //u16 datatemp[8];//测试用变量
  21.          //datatemp[0] = QJ_Situation();//测试语句
  22.          //printf("\n\rInfo= %08x\n\r",datatemp[0]);//测试语句
  23. //后期添加的变量

  24.          delay_init();                     //延时函数初始化       
  25.          NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
  26.          uart_init(9600);         //串口初始化为9600
  27.          LED_Init();                           //初始化与LED连接的硬件接口          
  28.          Write_CV(0x03,Device_Type_Addr);
  29.          Adc_Init();
  30.    DMA_Init2();
  31.          ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开始采集adc

  32.          
  33.         while(1)
  34.         {
  35.                 RS485_Receive_Data(rs485buf,&key);
  36.                 //取出通信帧内容
  37.                 GetFrame();
  38.                
  39.                 //通信协议内容识别逻辑
  40.                
  41.                 //非广播命令 及 CRC校验 及 设备类型 及 密钥检验 及 是否收到新的帧
  42.                 //CRCCHECK = CRCcheck();return true/false;
  43.                 CRCcheck();
  44.                 if( CRCCHECK && TypeFrame == TongGuoXHJ && AccessFrame == 0xAA && key)
  45.                 {
  46.                         if(OrderFrame == 0x01)
  47.                         {
  48.                                 //修改flash设备编号
  49.                                 //传回相应帧;void SendBackMessage(0x01);根据参数判断需要的返回信息,自动形成格式,提取flash中内容填充帧序列;
  50.                                 Write_CV(SerailFrame,QJ_Position_Addr);
  51.                                 SendBackFrame[0] = 0x10;
  52.                                 SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
  53.                                 SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);       
  54.         SendBack();                               
  55.                         }
  56.                        
  57.                         else if(SerailFrame == STMFLASH_ReadHalfWord(QJ_Position_Addr))
  58.                         {
  59.                                 switch(OrderFrame)
  60.                                 {
  61.                                         case 0x02:
  62.                                                 //读状态:命令+密钥(0xAA)+设备类型+设备编号+00+00+CRC
  63.                                           //返回格式:命令+设备类型+设备编号+灯丝状态+故障信息+00+CRC
  64.                                                 //参数:cv位置
  65.                                                 SendBackFrame[0] = 0x20;
  66.                                                 SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
  67.                                           SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
  68.                                                 SendBackFrame[3] = STMFLASH_ReadHalfWord(DS_State_Addr);
  69.                                                 SendBackFrame[4] = STMFLASH_ReadHalfWord(Fault_Setting_Addr);
  70.                                                 SendBack();
  71.                                                 break;
  72.                                         case 0x03:
  73.                                                 //写状态:命令+密钥(0xAA)+设备类型+设备编号+故障信息+00+CRC
  74.                                           //返回格式:命令+设备类型+设备编号+故障信息+00+00+CRC
  75.                                                 //参数:故障内容
  76.                                        
  77.                                                 Write_CV(Context5Frame,Fault_Setting_Addr);
  78.                                                 SendBackFrame[0] = 0x30;
  79.                                                 SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
  80.                                           SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
  81.                                                 SendBackFrame[3] = STMFLASH_ReadHalfWord(Fault_Setting_Addr);
  82.                                                 SendBack();
  83.                                                 break;
  84.                                         case 0x04:
  85.                                                 //读区间状态:命令+密钥(0xAA)+设备类型+设备编号+00+00+CRC
  86.                                           //返回格式:命令+设备类型+设备编号+最近四个分区的状况+00+00+CRC
  87.                                           //返回此区间前4个区间的状态
  88.                                                 SendBackFrame[0] = 0x40;
  89.                                                 SendBackFrame[1] = STMFLASH_ReadHalfWord(Device_Type_Addr);//0x03
  90.                                           SendBackFrame[2] = STMFLASH_ReadHalfWord(QJ_Position_Addr);
  91.                                                 SendBackFrame[3] = QJ_Situation();
  92.                                                 SendBack();
  93.                                                 break;
  94.                                        
  95.                                         default:break;
  96.                                        
  97.                                 }
  98.                         }
  99.                        
  100.                 }
  101.                
  102.                 //区间信息广播帧;不产生返回帧
  103.                 if(OrderFrame == 0x05 && CRCCHECK && TypeFrame == TongGuoXHJ && key)
  104.                 {
  105.                         //第一组数据区间1~8;9~16;17~24
  106.                         if(AccessFrame == 0x01)
  107.                         {
  108.                                 Write_CV(rs485buf[3],FQ_State_1_8_Addr);
  109.                                 Write_CV(rs485buf[4],FQ_State_9_16_Addr);
  110.                                 Write_CV(rs485buf[5],FQ_State_17_24_Addr);
  111.                         }
  112.                         //第二组数据区间25~32;33~40;41~48
  113.                         if(AccessFrame == 0x02)
  114.                         {
  115.                                 Write_CV(rs485buf[3],FQ_State_25_32_Addr);
  116.                                 Write_CV(rs485buf[4],FQ_State_33_40_Addr);
  117.                                 Write_CV(rs485buf[5],FQ_State_41_48_Addr);
  118.                         }
  119.                         //第三组数据区间49~56;57~64
  120.                         if(AccessFrame == 0x03)
  121.                         {
  122.                                 Write_CV(rs485buf[3],FQ_State_49_56_Addr);
  123.                                 Write_CV(rs485buf[4],FQ_State_57_64_Addr);
  124.                         }
  125.                         //单帧区域广播;命令+密钥(帧类型)+设备类型+区间Sector(0~7;可扩展)+区间信息+00+CRC
  126.                         if(AccessFrame == 0x10)
  127.                         {
  128.                                 Write_CV(Context5Frame,FQ_State_1_8_Addr * 2 * (int)SerailFrame);//待测试(int)SerailFrame
  129.                         }
  130.                         printf("\n\rCopy\n\r");//TEST
  131.                 }
  132.                 //读取电灯信息;判断并点灯
  133.                 if( key ) LightLogic();
  134.                
  135.                

  136.         }         
  137. }
复制代码

全部资料51hei下载地址:
v1.2.4点灯转移需要断线情况下自动实现.7z (206.73 KB, 下载次数: 10)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:711487 发表于 2020-3-19 12:38 来自手机 | 只看该作者
谢谢楼主分享
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表