2.常亮_&_变量

本文介绍Swift语言中常量(let)与变量(var)的基本用法,对比了与Objective-C的区别,阐述了如何定义及使用这两种类型的变量,并提供了一些实际操作的例子。

常亮 & 变量

Objective - C不同,Swift中在定义属性变量时,是不需要使用property的,而是采用 letvar来取代

定义 letvar

Int 常量

let numberA = 10

Double 常量

let numberB = 10.0

Int 变量

var numberC = 9

错误操作

// let在初始化之后,不能二次赋值
numberA = 9.0

正确操作

// var 能被修改
numberC = 1

自动换行

print(numberA)      10\n

More

  1. Swift: 常量: let 变量: var

  2. Swift中定义 let 和 var 不需要写数据类型,编译器会根据后面数据的真实类型自动推断

Swift开发中,常用 option + Click(Left) 来查看官方文档简写

Swift开发中,常用 option + DoubleClick(Left) 来查看官方文档详情

Swift开发中, 默认不需要在语句结尾加 ; ,写上也不会报错;若一行存在多条语句,则需要加;

Swift中,print() 取代 NSLog()

Swift v1.2 中存在 println(),在v2.0中被移除

from PyQt6.QtCore import QTimer, QByteArray from PyQt6.QtGui import QPixmap from PyQt6.QtWidgets import QApplication, QWidget, QPushButton, QProgressBar, QCheckBox from S08dome import Ui_Form from S08mode2 import Ui_Form1 from serial_son import SerialThread from arcade import load_sound, play_sound, stop_sound import serial.tools.list_ports import warnings class sonwindow(QWidget,Ui_Form1): def __init__(self): super().__init__() self.setupUi(self) class MyWindow(QWidget, Ui_Form): def __init__(self): super().__init__() self.setupUi(self) self.setWindowTitle("Serial Com") self.serial_thread = None self.open_serial_flag = False self.zdon = False self.num = False self.num1 = False self.checkBox.clicked.connect(self.hex_sx) self.checkBox_2.clicked.connect(self.hex_fs) self.pushButton.clicked.connect(lambda :self.plainTextEdit.clear()) self.pushButton_7.clicked.connect(self.mode) self.pushButton_8.clicked.connect(self.baoj) self.pushButton_11.clicked.connect(self.zp) self.pushButton_12.clicked.connect(self.nobaoj) self.horizontalSlider_4.valueChanged.connect(self.up) self.spinBox_3.valueChanged.connect(self.dowm) self.horizontalSlider_3.valueChanged.connect(self.up2) self.spinBox_4.valueChanged.connect(self.dowm2) self.pushButton_2.clicked.connect(self.open_serial_modbus) self.pushButton_6.clicked.connect(self.sx_ck) self.pushButton_4.clicked.connect(self.send) self.pushButton_3.clicked.connect(self.son) self.checkBox_3.setChecked(False) self.lineEdit_2 self.timer = QTimer(self) #######进度条 self.jdt_cz = 0 self.flat = 1 self.run = False self.progressBar_2.setValue(self.jdt_cz) self.progressBar_2.setRange(0,100) self.pushButton_9.clicked.connect(self.fx_flag) self.timer = QTimer(self) self.timer.timeout.connect(self.update) def hex_sx(self): self.num = not self.num def hex_fs(self): self.num1 = not self.num1 def fx_flag(self): if self.openmen == False: if not self.run: # 如果定时器未运行,启动并设置方向 self.run = True self.timer.start(50) # 间隔50ms else: # 如果定时器在运行,切换方向 self.flat *= -1 def update(self): self.jdt_cz += self.flat # 边界保护 if self.openmen == False: if self.jdt_cz >= 100: self.jdt_cz = 100 self.timer.stop() self.run = False self.flat = -1 # 下次自动反向 self.lineEdit_6.setText("打开") self.pp = False elif self.jdt_cz <= 0: self.jdt_cz = 0 self.timer.stop() self.run = False self.flat = 1 # 下次自动反向 self.lineEdit_6.setText("关闭") self.pp = True self.progressBar_2.setValue(self.jdt_cz) ###子页面 def son(self): self.son_1 = sonwindow() self.son_1.show() ###滑条 def up(self,num): self.horizontalSlider_4.setValue(num) self.spinBox_3.setValue(num) def dowm(self,num): self.horizontalSlider_4.setValue(num) self.spinBox_3.setValue(num) def up2(self,num2): self.horizontalSlider_3.setValue(num2) self.spinBox_4.setValue(num2) def dowm2(self,num2): self.horizontalSlider_3.setValue(num2) self.spinBox_4.setValue(num2) def mode(self): self.mode = not self.mode if self.mode: self.lineEdit_10.setText("自动") self.openmen = True # self.zidon() else: self.lineEdit_10.setText("手动") self.openmen = False ###按键切换标签内容 def zidon(self): if self.openmen == True and self.yv == False: self.lineEdit_6.setText("关闭") else: self.lineEdit_6.setText("打开") #######MP3 def baoj(self): if self.pp == False: self.label_23.setStyleSheet("background-color: rgb(255, 0, 0);border-radius:30px;") sound = load_sound("蜂鸣器哔哔响.mp3") self.player = play_sound(sound) self.lineEdit_6.setText("关闭") def nobaoj(self): self.label_23.setStyleSheet("background-color: rgb(0, 85, 0);border-radius:30px;") sound = load_sound("蜂鸣器哔哔响.mp3") player = play_sound(sound) stop_sound(player) ######来回切换图片 def zp(self): self.zp = not self.zp if self.zp: self.label_25.setPixmap(QPixmap("不下雨.png")) self.yv = True else: self.label_25.setPixmap(QPixmap("下雨.jpg")) self.yv = False # def yvzhi(self): # try: # # 将字符串转换为浮点数(假设 self.wd, self.max, self.min 是数值字符串) # current_temp = float(self.wd) # upper_limit = float(self.max) # lower_limit = float(self.min) # # # 判断温度是否超出阈值 # if current_temp > upper_limit or current_temp < lower_limit: # self.label_22.setStyleSheet("background-color: rgb(0, 255, 0); border-radius: 30px;") # else: # self.label_22.setStyleSheet("background-color: rgb(0, 85, 0); border-radius: 30px;") # except ValueError as e: # print(f"数据格式错误: {e}") # except AttributeError as e: # print(f"属性缺失: 确保已接收到数据 - {e}") ###########串口 def sx_ck(self): self.comboBox.clear() serial_ports = serial.tools.list_ports.comports() for port in serial_ports: self.comboBox.addItem(port.device) def open_serial_modbus(self): self.open_serial_flag = not self.open_serial_flag databits = int(8) stopbits = int(1) parity = serial.PARITY_NONE if self.open_serial_flag: self.pushButton_2.setText("关闭串口") self.label_2.setPixmap(QPixmap("指示灯常亮.png.png")) port = self.comboBox.currentText() baudrate = int(self.comboBox_2.currentText()) try: self.serial_thread = SerialThread(port, baudrate, databits,parity,stopbits) self.serial_thread.data_received.connect(self.FirstReader) self.serial_thread.start() except Exception as e: print(f"无法连接到串口 {port}: {str(e)}") else: self.pushButton_2.setText("打开串口") self.label_2.setPixmap(QPixmap("指示灯熄灭.png")) self.serial_thread.serial_client.close() # 改进后的指令发送方法 # def send_custom_instruction_with_delay(self): # try: # # if self.hex_display == False: # instruction = bytes.fromhex(str(self.plainTextEdit_2.toPlainText()))##16 # self.send_protocol(instruction) # # # else: # # instruction = str(self.plainTextEdit_2.toPlainText()).encode("GBK")##字符串 # # self.send_protocol(instruction) # except Exception as e: # print(f"发送指令时发送错误: {e}") # # def send_protocol(self, protocol): # if hasattr(self, 'serial_thread') and self.serial_thread.isRunning(): # self.serial_thread.serial_client.write(protocol) # print("协议发送成功.") # else: # print("串行Modbus RTU连接未打开.") def send(self): if self.num1: self.serial_thread.serial_client.write(bytes.fromhex(str(self.plainTextEdit_2.toPlainText()))) else: self.serial_thread.serial_client.write(str(self.plainTextEdit_2.toPlainText()).encode("GBK")) def format_data(self, data): return ' '.join(f"{byte:02X}" for byte in data) def FirstReader(self, information): if self.num: self.plainTextEdit.appendPlainText(self.format_data(information)) else: try: shu = bytes.fromhex(self.format_data(information).replace(" ", "")).decode("GBK") self.plainTextEdit.appendPlainText(shu) except Exception as e: self.plainTextEdit.appendPlainText(str(e)) self.lineEdit_9.setText(str(int(str(self.format_data(information).split(" ")[1]), 16))) self.lineEdit_7.setText(str(int(self.format_data(information).split(" ")[2], 16))) self.lineEdit_8.setText(str(int(self.format_data(information).split(" ")[3], 16))) # # if self.hex_display == False: # formatted_data = self.format_data(information) # 将接收到的数据格式化为十六进制 # self.plainTextEdit.appendPlainText(f"接收到的信息是:{formatted_data}") # print(f"{formatted_data}") # # else: # # self.plainTextEdit.appendPlainText(f"{information}") ##字符串 # #print(f"{information}") # # # # # self.data_strip = information.strip(" ") # data_hex1 = self.data_strip.upper().encode().hex() # data_hex = self.format_data(data_hex1.encode("gbk")) # byte_array = QByteArray.fromHex(information.encode('utf-8')) # self.hex_data.append(byte_array) # # # 使用GBK编码解码为字符串 # byte_array = QByteArray.fromHex(information.encode('utf-8')) # # # 将 QByteArray 转换为 bytes,然后解码为字符串 # decoded_string = byte_array.data().decode('GBK') # # if self.hex_str: # self.plainTextEdit.appendPlainText(f"{data_hex}") # else: # self.plainTextEdit.appendPlainText(f"{decoded_string}") #######串口读取数据 # def FirstReader(self, information): # self.plainTextEdit.appendPlainText(f"{information}") # self.num1 = information.split(" ")[1].split(" ")[0] # self.num2 = information.split(" ")[2].split(" ")[0] # self.num3 = information.split(" ")[3].split(" ")[0] # self.wd = self.num1.split(" ")[0].strip(" ") # self.max = self.num2.split(" ")[0].strip(" ") # self.min = self.num3.split(" ")[0].strip(" ") # self.lineEdit_9.setText(str(self.wd)) # self.lineEdit_7.setText(str(self.max)) # self.lineEdit_8.setText(str(self.min)) # self.yvzhi() if __name__ == '__main__': warnings.filterwarnings("ignore", category=DeprecationWarning) app = QApplication([]) window = MyWindow() window.show() app.exec()用我程序里的定时器将串口上报数据定时发送 并告诉我添加的部分
05-14
设计一款基于 STM32F103C8T6 单片机的串口按键控制 LED 系统,实现按键、 串口控制 LED 亮灭、LED 闪烁。 1、基础部分 (1)LED1 定时闪烁(需要放置在定时器中断中运行,闪烁间隔时间为 1S) (2)LED2 使用外部中断控制 LED 状态,分别是常亮,呼吸灯和闪烁(需要在这 三个状态之间进行循环切换,常亮-呼吸-闪烁-常亮) (3)LED3 通过串口控制该 LED 亮灭。以上为任务内容。我的代码如下:#include "stm32f10x.h" #include <string.h> // LED引脚定义 #define LED1_PIN GPIO_Pin_1 #define LED2_PIN GPIO_Pin_2 #define LED3_PIN GPIO_Pin_14 #define LED1_PORT GPIOA #define LED2_PORT GPIOA #define LED3_PORT GPIOC #define KEY_PIN GPIO_Pin_0 #define KEY_PORT GPIOA // LED2状态 typedef enum { LED2_CONSTANT = 0, LED2_BREATH = 1, LED2_BLINK = 2 } LED2_Mode_t; // 全局变量 volatile LED2_Mode_t led2_mode = LED2_CONSTANT; volatile uint8_t led3_state = 0; volatile uint16_t breath_value = 0; volatile uint8_t breath_direction = 1; uint8_t usart_rx_buffer[32]; uint8_t rx_index = 0; uint32_t heartbeat_counter = 0; void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE); // LED1 - PA1 GPIO_InitStructure.GPIO_Pin = LED1_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED1_PORT, &GPIO_InitStructure); // LED2 - PA2 GPIO_InitStructure.GPIO_Pin = LED2_PIN; GPIO_Init(LED2_PORT, &GPIO_InitStructure); // LED3 - PC14 GPIO_InitStructure.GPIO_Pin = LED3_PIN; GPIO_Init(LED3_PORT, &GPIO_InitStructure); // 按键 - PA0 GPIO_InitStructure.GPIO_Pin = KEY_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(KEY_PORT, &GPIO_InitStructure); // 初始状态:所有LED关闭 GPIO_SetBits(LED1_PORT, LED1_PIN); GPIO_SetBits(LED2_PORT, LED2_PIN); GPIO_SetBits(LED3_PORT, LED3_PIN); } void USART1_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // USART1 TX (PA9) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // USART1 RX (PA10) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // USART配置 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); } void TIM2_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 10ms中断 TIM_TimeBaseStructure.TIM_Period = 1000 - 1; TIM_TimeBaseStructure.TIM_Prescaler = 720 - 1; // 72MHz/720=100kHz, 1000计数=10ms TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_Cmd(TIM2, ENABLE); } void EXTI_Configuration(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); // USART1中断配置 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART_SendString(char *str) { while(*str) { USART_SendData(USART1, *str++); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); } } int main(void) { SystemInit(); GPIO_Configuration(); USART1_Configuration(); NVIC_Configuration(); TIM2_Configuration(); EXTI_Configuration(); __enable_irq(); USART_SendString("=== STM32 LED Control System ===\r\n"); USART_SendString("Task1: LED1 auto blink (1s interval)\r\n"); USART_SendString("Task2: Press PA0 to switch LED2 modes\r\n"); USART_SendString("Task3: UART commands: LED3_ON, LED3_OFF\r\n"); USART_SendString("System Ready!\r\n"); while(1) { // 减少心跳信号频率,避免刷屏 heartbeat_counter++; if(heartbeat_counter >= 5000000) { // 约5秒 heartbeat_counter = 0; USART_SendString("> "); // 简单的提示符 } } } void TIM2_IRQHandler(void) { static uint32_t timer_counter = 0; if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { timer_counter++; // LED1: 1秒闪烁 (100 * 10ms = 1s) if(timer_counter >= 100) { timer_counter = 0; GPIO_WriteBit(LED1_PORT, LED1_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED1_PORT, LED1_PIN))); } // LED2模式控制 switch(led2_mode) { case LED2_CONSTANT: // 常亮 GPIO_ResetBits(LED2_PORT, LED2_PIN); break; case LED2_BREATH: // 呼吸灯 // 每20ms调整一次亮度 if(timer_counter % 2 == 0) { if(breath_direction) { breath_value += 5; if(breath_value >= 100) breath_direction = 0; } else { breath_value -= 5; if(breath_value <= 0) breath_direction = 1; } } // 软件PWM if((timer_counter % 100) < breath_value) GPIO_ResetBits(LED2_PORT, LED2_PIN); else GPIO_SetBits(LED2_PORT, LED2_PIN); break; case LED2_BLINK: // 闪烁 // 1秒闪烁周期 if(timer_counter % 100 == 0) { GPIO_WriteBit(LED2_PORT, LED2_PIN, (BitAction)(1 - GPIO_ReadOutputDataBit(LED2_PORT, LED2_PIN))); } break; } // LED3控制 - 修复逻辑 if(led3_state) { GPIO_ResetBits(LED3_PORT, LED3_PIN); // LED3_ON时点亮 } else { GPIO_SetBits(LED3_PORT, LED3_PIN); // LED3_OFF时熄灭 } TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } void EXTI0_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line0) != RESET) { // 消抖 for(volatile uint32_t i = 0; i < 10000; i++); if(GPIO_ReadInputDataBit(KEY_PORT, KEY_PIN) == 0) { led2_mode = (LED2_Mode_t)((led2_mode + 1) % 3); breath_value = 0; breath_direction = 1; USART_SendString("LED2 Mode: "); switch(led2_mode) { case LED2_CONSTANT: USART_SendString("Constant ON"); break; case LED2_BREATH: USART_SendString("Breath Light"); break; case LED2_BLINK: USART_SendString("Blink"); break; } USART_SendString("\r\n"); } EXTI_ClearITPendingBit(EXTI_Line0); } } void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); // 字符回显(可选) // USART_SendData(USART1, data); if(data == '\r' || data == '\n') { if(rx_index > 0) { usart_rx_buffer[rx_index] = '\0'; // LED3控制命令 - 修复逻辑 if(strcmp((char*)usart_rx_buffer, "LED3_ON") == 0) { led3_state = 1; // 设置为1,点亮LED USART_SendString("\r\nLED3: ON\r\n"); } else if(strcmp((char*)usart_rx_buffer, "LED3_OFF") == 0) { led3_state = 0; // 设置为0,熄灭LED USART_SendString("\r\nLED3: OFF\r\n"); } else { USART_SendString("\r\nUnknown command. Use: LED3_ON, LED3_OFF\r\n"); } rx_index = 0; } } else if(rx_index < 31) { usart_rx_buffer[rx_index++] = data; } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } }
最新发布
10-27
void Telltale_Display( void ) { uint8_t u8Temp = Receive_MCU_Data.Mark_ID05H.Sig.ABS; static uint8_t u8blink = 0; u8blink = !u8blink; // 每次进来翻转状态 switch ( u8Temp ) { case 1: widget_set_visible(Theme1_Widgets.ABS_ICON, TRUE); // 常亮 break; case 3: widget_set_visible( Theme1_Widgets.ABS_ICON, u8blink ); break; default: widget_set_visible( Theme1_Widgets.ABS_ICON, FALSE ); // 熄灭 break; } uint8_t u8Temp2 = Receive_MCU_Data.Mark_ID05H.Sig.TCS_Light; uint8_t u8Temp3 = Receive_MCU_Data.Mark_ID05H.Sig.TCS_Trigger; if ( u8Temp3 == 1 ) { widget_set_visible( Theme1_Widgets.TC_ICON, u8blink ); } else if ( u8Temp2 == 1 ) { widget_set_visible( Theme1_Widgets.TC_ICON, TRUE ); } else { widget_set_visible( Theme1_Widgets.TC_ICON, FALSE ); // 熄灭 } widget_t* pWidget[] = { Theme1_Widgets.Light_Single_BG, Theme1_Widgets.Light_Single_1, Theme1_Widgets.Light_Single_2, Theme1_Widgets.Light_Single_3, Theme1_Widgets.Light_Single_4 }; static uint8_t u8LastData = 4; uint8_t u8CurrentData = 0; #ifdef TEST // 测试模式:静态变量(保持计数和循环状态) static uint8_t count_250ms = 0; // 250ms 周期计数器 static uint8_t test_index = 0; // 测试值数组索引 // 测试信号循环顺序:0xFF → 0 → 1 → 2 → 3 → 4 const uint8_t test_signals[] = {0xFF, 0, 1, 2, 3, 4}; // 数组度(自动计算,后续修改循环值无需改度) const uint8_t signal_len = sizeof(test_signals) / sizeof(test_signals[0]); // 每 4 次 250ms 切换一次值(4×250ms=1s) if (++count_250ms >= 4) { count_250ms = 0; // 重置计数器 test_index = (test_index + 1) % signal_len; // 循环切换索引 } // 测试模式:从数组取当前信号值 u8CurrentData = test_signals[test_index]; #else // 正常模式:使用实际 MCU 数据 u8CurrentData = Receive_MCU_Data.Signal_ID08H.Sig.GPRS_Signal; #endif if ( u8LastData == u8CurrentData ) { return; // 如果数据未变化,则不进行任何操作 } // 信号为 0xFF 时,隐藏所有控件 if ( u8CurrentData == 0xFF ) { for( uint8_t i = 0; i < 5; i++ ) { widget_set_visible( pWidget[i], FALSE ); } u8LastData = u8CurrentData; // 更新上一次数据状态 } else { widget_set_visible( pWidget[0], TRUE ); // 先隐藏所有控件 // 信号变化时,根据当前值显示相应控件 for( uint8_t i = 1; i < 5; i++ ) { if ( i <= u8CurrentData ) { widget_set_visible( pWidget[i], TRUE ); // 显示当前信号对应的控件 } else { widget_set_visible( pWidget[i], FALSE ); // 隐藏当前信号之后的控件 } } u8LastData = u8CurrentData; // 更新上一次数据状态 } } 代码注释
10-14
#include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" #include "stm32f10x_adc.h" #include "stm32f10x_dma.h" #include "misc.h" // 传感器引脚定义 #define GAS_SENSOR_PIN GPIO_Pin_0 // PA0 - MQ-2气体传感器(ADC) #define FLAME_SENSOR_PIN GPIO_Pin_1 // PA1 - 火焰传感器(数字输入) #define WATER_SENSOR_PIN GPIO_Pin_2 // PA2 - 水位传感器(ADC) #define BUZZER_PIN GPIO_Pin_3 // PA3 - 蜂鸣器(数字输出) // LED状态指示灯 #define STATUS_LED_PIN GPIO_Pin_13 // PC13 - 系统状态LED // 传感器阈值 #define GAS_THRESHOLD 1500 // 气体报警阈值(12位ADC值) #define WATER_THRESHOLD 1250 // 水位报警阈值 #define GAS_HYSTERESIS 200 // 气体迟滞范围 #define WATER_HYSTERESIS 200 // 水位迟滞范围 // 系统状态 typedef enum { SYSTEM_NORMAL = 0, GAS_ALARM, FLAME_ALARM, WATER_ALARM, MULTI_ALARM } SystemStatus; // 全局变量 __IO uint16_t adc_value[2]; // ADC值数组 [0:气体, 1:水位] SystemStatus system_status = SYSTEM_NORMAL; uint32_t alarm_counter = 0; uint8_t flame_state = 0; // 初始化系统时钟 void RCC_Configuration(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); RCC_ADCCLKConfig(RCC_PCLK2_Div6); // ADC时钟 = 72MHz / 6 = 12MHz } // 初始化GPIO void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // 配置气体传感器(PA0)和水位传感器(PA2)为模拟输入 GPIO_InitStructure.GPIO_Pin = GAS_SENSOR_PIN | WATER_SENSOR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置火焰传感器(PA1)为上拉输入 GPIO_InitStructure.GPIO_Pin = FLAME_SENSOR_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蜂鸣器(PA3)为推挽输出 GPIO_InitStructure.GPIO_Pin = BUZZER_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置状态LED(PC13)为推挽输出 GPIO_InitStructure.GPIO_Pin = STATUS_LED_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); // 初始状态:关闭蜂鸣器,开启LED GPIO_ResetBits(GPIOA, BUZZER_PIN); GPIO_SetBits(GPIOC, STATUS_LED_PIN); } // 配置DMA void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc_value; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 2; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE); } // 配置ADC void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; ADC_DeInit(ADC1); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); // 配置ADC通道(气体传感器和水位传感器) ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); // PA0 ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_55Cycles5); // PA2 // 使能ADC DMA ADC_DMACmd(ADC1, ENABLE); // 使能ADC ADC_Cmd(ADC1, ENABLE); // 校准ADC ADC_ResetCalibration(ADC1); while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); while(ADC_GetCalibrationStatus(ADC1)); // 启动ADC转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE); } // 系统状态更新 void UpdateSystemStatus(void) { static uint8_t last_flame_state = 1; static uint16_t last_gas_value = 0; static uint16_t last_water_value = 0; // 读取火焰传感器状态(低电平表示有火焰) flame_state = GPIO_ReadInputDataBit(GPIOA, FLAME_SENSOR_PIN); // 检查传感器状态 uint8_t gas_alarm = (adc_value[0] > GAS_THRESHOLD) || ((last_gas_value > GAS_THRESHOLD) && (adc_value[0] > (GAS_THRESHOLD - GAS_HYSTERESIS))); uint8_t water_alarm = (adc_value[1] > WATER_THRESHOLD) || ((last_water_value > WATER_THRESHOLD) && (adc_value[1] > (WATER_THRESHOLD - WATER_HYSTERESIS))); uint8_t flame_alarm = (flame_state == Bit_RESET) || ((last_flame_state == Bit_RESET) && (flame_state == Bit_RESET)); // 保存当前状态用于下一次判断 last_gas_value = adc_value[0]; last_water_value = adc_value[1]; last_flame_state = flame_state; // 确定系统状态 uint8_t alarm_count = gas_alarm + water_alarm + flame_alarm; if (alarm_count == 0) { system_status = SYSTEM_NORMAL; } else if (alarm_count > 1) { system_status = MULTI_ALARM; } else if (gas_alarm) { system_status = GAS_ALARM; } else if (flame_alarm) { system_status = FLAME_ALARM; } else { system_status = WATER_ALARM; } } // 控制报警器 void ControlAlarm(void) { static uint32_t led_blink_counter = 0; if (system_status == SYSTEM_NORMAL) { // 正常状态:关闭蜂鸣器,LED常亮 GPIO_ResetBits(GPIOA, BUZZER_PIN); GPIO_SetBits(GPIOC, STATUS_LED_PIN); alarm_counter = 0; } else { // 报警状态:开启蜂鸣器,LED闪烁 GPIO_SetBits(GPIOA, BUZZER_PIN); // LED闪烁指示报警类型 led_blink_counter++; if (led_blink_counter % 100 == 0) { GPIO_WriteBit(GPIOC, STATUS_LED_PIN, (GPIO_ReadOutputDataBit(GPIOC, STATUS_LED_PIN) == Bit_SET) ? Bit_RESET : Bit_SET); } // 增加报警计数器(可用于后续功能扩展) alarm_counter++; } } // 简单延时函数 void Delay(uint32_t nCount) { for(; nCount != 0; nCount--); } int main(void) { // 系统初始化 RCC_Configuration(); GPIO_Configuration(); DMA_Configuration(); ADC_Configuration(); // 等待传感器稳定(MQ-2需要预热) for(int i = 0; i < 2000000; i++); while(1) { // 更新系统状态 UpdateSystemStatus(); // 控制报警器 ControlAlarm(); // 简单延时 Delay(0xFFFF); } }
07-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值