个人分享
登录

串口 转发 成功 3.0.0

391
  • admin
    管理员
    /*
     * STM32F407 串口双向透传
     * ------------------------------------------------------------
     * 485主机接口  : PB6(RX)/PB7(TX)/PB5(EN)  9600
     * 井下数据口   : PA2(USART2_TX)/PA3(USART2_RX)  300
     * 调试口       : PA9/PA10(USART1) 115200
     */
    
    #include <Arduino.h>
    #include <SoftwareSerial.h>
    
    // ==================== 硬件配置 ====================
    #define RS485_RX PB7
    #define RS485_TX PB6
    #define RS485_EN PB5
    
    #define EEPROM_BASE 0x080E0000
    
    
    // ==================== 引脚定义 ====================
    // 开关 控制引脚
    #define CL_0 PB0  // PB0 长短缆切换
    #define CL_1 PB1  // PB1 长短缆切换
    
    #define KZ PE10  // PE10 KZ1
    
    
    // 增益  编码输出引脚 (1-16)
    #define ENCODE_PB2 PB2  // PB2 (最高位)
    #define ENCODE_PE7 PE7  // PE7
    #define ENCODE_PE8 PE8  // PE8
    #define ENCODE_PE9 PE9  // PE9 (最低位)
    
    // ADC 输入引脚
    
    #define ADC1_PIN PA5  // PA5/ADC1 长短缆检测
    #define ADC2_PIN PA6  // PA6/ADC2 控制器输出电压
    #define ADC3_PIN PA7  // PA7/ADC3 控制器输出电流
    
    // 解码管脚
    #define PCODE_PIN PA1
    #define NCODE_PIN PA0
    
    // 使用你的方式定义串口
    Uart Serial1(USART1);
    Uart Serial2(USART2);
    SoftwareSerial rs485(RS485_RX, RS485_TX);
    // ==================== 485函数开始 ====================
    // 切换到发送模式
    void setTxMode() {
      digitalWrite(RS485_EN, HIGH);
      delayMicroseconds(200);  // 等待方向稳定
    }
    
    // 切换到接收模式
    void setRxMode() {
      rs485.flush();           // 等待发送完成
      delayMicroseconds(200);  // 确保最后字节发送完成
      digitalWrite(RS485_EN, LOW);
    }
    
    // 发送多个字节(基础版)
    void rs485Write(const uint8_t* data, size_t length) {
      setTxMode();                // 切换到发送模式
      rs485.write(data, length);  // 发送数据
      setRxMode();                // 切换回接收模式
    }
    
    // ==================== 485方向控制 ====================
    void rs485SetReceive() {
      digitalWrite(RS485_EN, LOW);
      delayMicroseconds(10);
    }
    
    void rs485SetTransmit() {
      digitalWrite(RS485_EN, HIGH);
      delayMicroseconds(10);
    }
    
    // ==================== RS485发送 ====================
    void rs485Write(uint8_t data) {
      rs485SetTransmit();
      rs485.write(data);
      rs485.flush();
      rs485SetReceive();
    }
    
    void rs485WriteBuffer(uint8_t* buf, uint16_t len) {
      rs485SetTransmit();
      for (uint16_t i = 0; i < len; i++) {
        rs485.write(buf[i]);
      }
      rs485.flush();
      rs485SetReceive();
    }
    
    // ==================== Flash写多个字节 ====================
    // 保存数据到Flash(2字节对齐)
    void saveData(uint8_t* data, uint16_t len) {
        HAL_FLASH_Unlock();
        
        // 擦除扇区
        FLASH_EraseInitTypeDef e = {};
        e.TypeErase = FLASH_TYPEERASE_SECTORS;
        e.Sector = 11;
        e.NbSectors = 1;
        e.VoltageRange = FLASH_VOLTAGE_RANGE_3;
        uint32_t err;
        HAL_FLASHEx_Erase(&e, &err);
        
        // 2字节对齐写入
        for (int i = 0; i < len; i += 2) {
            uint16_t w = 0xFFFF;
            if (i < len) w = data[i];
            if (i+1 < len) w |= (data[i+1] << 8);
            HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, EEPROM_BASE + i, w);
        }
        
        HAL_FLASH_Lock();
    }
    
    // 读取数据
    void loadData(uint8_t* buf, uint16_t len) {
        for (int i = 0; i < len; i++) {
            buf[i] = *(uint8_t*)(EEPROM_BASE + i);
        }
    }
    
    // ====================// ====================// ====================// ====================// ====================
    
    // 长短缆管脚赋值
    void setDecode(uint8_t val) {
        digitalWrite(PCODE_PIN, val & 0x01);
        digitalWrite(NCODE_PIN, (val >> 1) & 0x01);
    }
    
    // 增益管脚赋值
    void setEncode(uint8_t val) {
        digitalWrite(ENCODE_PE9, val & 0x01);
        digitalWrite(ENCODE_PE8, (val >> 1) & 0x01);
        digitalWrite(ENCODE_PE7, (val >> 2) & 0x01);
        digitalWrite(ENCODE_PB2, (val >> 3) & 0x01);
    }
    
    
    // ====================// ====================// ====================// ====================// ====================
    
    // 超时接收(精简版)
    bool readRs485(uint8_t* buffer, uint16_t maxLen, uint16_t* len, uint32_t timeoutMs = 100) {
        *len = 0;
        if (!buffer || maxLen == 0 || !rs485.available()) return false;
        
        uint32_t start = millis();
        while (*len < maxLen && (millis() - start) < timeoutMs) {
            if (rs485.available()) {
                buffer[(*len)++] = rs485.read();
                start = millis();  // 收到数据重置超时
            }
            delayMicroseconds(50);
        }
        return (*len > 0);
    }
    
    // ==================== 数据转发 ====================
    void forwardData() {
      // 1. RS485 -> 调试口 + 井下口
      while (rs485.available()) {
        uint8_t data = rs485.read();
        Serial1.write(data);
        Serial2.write(data);
      }
    
      // 2. 调试口 -> RS485 + 井下口
      while (Serial1.available()) {
        uint8_t data = Serial1.read();
        rs485Write(data);
        Serial2.write(data);
      }
    
      // 3. 井下口 -> RS485 + 调试口
      while (Serial2.available()) {
        uint8_t data = Serial2.read();
        rs485Write(data);
        Serial1.write(data);
      }
    }
    
    // ==================== Setup ====================
    void setup() {
      pinMode(RS485_EN, OUTPUT);
      rs485SetReceive();
      Serial1.begin(115200);  // 调试口
      Serial2.begin(300);     // 井下口
      rs485.begin(9600);      // RS485
      pinMode(RS485_RX, INPUT_PULLUP);
      pinMode(RS485_TX, OUTPUT);
    //////////////////////////adc设置////////////////////////////
        pinMode(ADC1_PIN, INPUT_ANALOG);
        pinMode(ADC2_PIN, INPUT_ANALOG);
        pinMode(ADC3_PIN, INPUT_ANALOG);
    
    ///////////长短兰///////////////增益////////////////////////////
        pinMode(PCODE_PIN, OUTPUT);
        pinMode(NCODE_PIN, OUTPUT);
        pinMode(ENCODE_PB2, OUTPUT);
        pinMode(ENCODE_PE7, OUTPUT);
        pinMode(ENCODE_PE8, OUTPUT);
        pinMode(ENCODE_PE9, OUTPUT);
    
        // 设置长短缆: PCODE=1, NCODE=0
       // setDecode(0x01);
        
        // 设置增益: 0x0A (1010)
       // setEncode(0x0A);
    
       
    ///////////eprom 写入////////////////////////////
    
        // 准备4字节数据  可以是编号 长短缆 和增益
        uint8_t myData[4] = {0x0A, 0x01, 0x12, 0x34};
        
        //saveData(myData, sizeof(myData));
        Serial1.println("Saved!");
    }
    
    // ==================== Loop ====================
    void loop() {
      forwardData();
      delay(1000);
      
      
    	//============================================================================================
        uint8_t readBuf[4];
        loadData(readBuf, sizeof(readBuf));
        
        for (int i = 0; i < 4; i++) {
            Serial1.printf("Byte%d: 0x%02X\r\n", i, readBuf[i]);
        }
    
    	//============================================================================================
        int a1 = analogRead(ADC1_PIN);
        int a2 = analogRead(ADC2_PIN);
        int a3 = analogRead(ADC3_PIN);
        
        Serial1.printf("%4d  %4d  %4d\r\n", a1, a2, a3);
        delay(5000);
    	
    	//============================================================================================
    	
    	uint8_t buffer[64];
        uint16_t len = 0;
        
        // 接收数据,超时100ms
        if (readRs485(buffer, sizeof(buffer), &len, 100)) {
            Serial.print("Received ");
            Serial.print(len);
            Serial.print(" bytes: ");
            for (uint16_t i = 0; i < len; i++) {
                Serial.printf("%02X ", buffer[i]);
            }
            Serial.println();
        }
    	
    	
    	
    	
    	
    	
    
    }
    
    // ==================== 系统时钟配置 ====================
    extern "C" void SystemClock_Config(void) {
      RCC_OscInitTypeDef RCC_OscInitStruct = {};
      RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
    
      __HAL_RCC_PWR_CLK_ENABLE();
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
    
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLM = 12;
      RCC_OscInitStruct.PLL.PLLN = 336;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
      RCC_OscInitStruct.PLL.PLLQ = 7;
      if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
        Error_Handler();
      }
    
      RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
      if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
        Error_Handler();
      }
    
      SystemCoreClock = 168000000UL;
    }
  • admin
    管理员
    #1

    已经完成 eprom 增益 长短缆 的功能

发表回复

登录后回复