55.基于IIC协议的EEPROM驱动控制(2)

news2024/11/15 23:36:06

        升腾A7pro的EEPROM芯片为24C64芯片,器件地址为1010_011。

        (1)Visio整体设计视图(IIC_SCL为250KHz,IIC_CLK为1MHz,addr_num为1,地址字节数为2字节,addr_num为0,地址字节数为1字节):

(2)IIC_ctrl模块状态转移图:

(3)按键消抖模块代码及注释解析:

module key_filter(clk,reset_n,key_in,key_p_flag,key_r_flag,key_state);

    input clk;
    input reset_n;
    input key_in;
    
    output reg key_p_flag;
    output reg key_r_flag;
    output reg key_state;
    
    reg key_in1;
    reg key_in2;
    reg key_in3;
    reg [3:0]STATE;
    
//抖动时间往往小于20ms,20ms = 20_000_000ns = 20ns * 1_000_000;   (1_000_000)D = (1111_0100_0010_0100_0000)B   需要一个20位的寄存器,用于计数
    reg [19:0]cnt_20ms;
    reg en_cnt_20ms;

    wire podge;
    wire nedge;
    wire arrive_time_20ms;
    
//状态设计
    parameter IDLE      = 4'b0001;          //释放稳定状态
    parameter P_SHAKE   = 4'b0010;          //按下抖动状态
    parameter DOWN      = 4'b0100;          //按下稳定状态
    parameter R_SHAKE   = 4'b1000;          //释放抖动状态
    
    parameter CNT_MAX   = 20'd999_999;
    
//异步输入key_in 信号的同步化————“打两拍”
    always@(posedge clk)begin
        key_in1 <= key_in;
        key_in2 <= key_in1;
    end

//上升沿、下降沿设计
    always@(posedge clk)
        key_in3 <= key_in2;
        
    assign podge = key_in2  &&  (!key_in3);     //上升沿
    assign nedge = (!key_in2)  &&  key_in3;     //下降沿
        
//20ms计数器模块设计    
    always@(posedge clk or negedge reset_n)
        if(!reset_n)
            cnt_20ms <= 20'd0;
        else if(en_cnt_20ms &&(cnt_20ms == CNT_MAX))
            cnt_20ms <= 20'd0;
        else if(en_cnt_20ms)
            cnt_20ms <= cnt_20ms + 20'd1;
        else 
            cnt_20ms <= 20'd0;
            
//计满20ms信号设计           
    assign arrive_time_20ms = (cnt_20ms == CNT_MAX);
    
//状态机主程序设计
    always@(posedge clk or negedge reset_n)
        if(!reset_n)begin
            key_r_flag  <= 1'd0;
            key_p_flag  <= 1'd0;
            key_state   <= 1'd1;
            STATE       <= IDLE;
            en_cnt_20ms <= 1'd0;
        end
        else begin
            case(STATE)
                IDLE:begin
                    key_r_flag <= 1'd0;
                    key_state  <= 1'd1;
                    if(nedge)begin
                        STATE <= P_SHAKE;
                        en_cnt_20ms <= 1'd1;
                    end
                    else 
                        STATE <= STATE;
                end
                
                P_SHAKE:begin
                    if(arrive_time_20ms)begin
                        STATE <= DOWN;
                        en_cnt_20ms <= 1'd0;
                        key_p_flag <= 1'd1;
                        key_state <= 1'd0;
                    end
                    else if(podge)begin
                        STATE <= IDLE;
                        en_cnt_20ms <= 1'd0;
                    end
                    else 
                        STATE <= STATE;  
                end
                
                DOWN:begin
                    key_p_flag <= 1'd0;
                    key_state <= 1'd0;
                    if(podge)begin
                        STATE <= R_SHAKE;
                        en_cnt_20ms <= 1'd1;
                    end
                    else 
                        STATE <= STATE;          
                end
                
                R_SHAKE:begin
                    if(arrive_time_20ms)begin
                        STATE <= IDLE;
                        en_cnt_20ms <= 1'd0;
                        key_r_flag <= 1'd1;
                        key_state  <= 1'd1;
                    end
                    else if(nedge)begin
                        STATE <= DOWN;
                        en_cnt_20ms <= 1'd0;
                    end
                    else 
                        STATE <= STATE; 
                end
                
                default:begin
                    key_r_flag <= 1'd0;
                    key_p_flag <= 1'd0;
                    key_state  <= 1'd1;
                    STATE      <= IDLE;
                end
            endcase
        end

endmodule

(4)IIC_ctrl模块Verilog代码:

module IIC_ctrl(

    input   wire            clk         ,
    input   wire            reset_n     ,
    input   wire            IIC_start   ,
    input   wire            wr_en       ,
    input   wire            rd_en       ,
    input   wire    [15:0]  byte_addr   ,
    input   wire    [7:0]   wr_data     ,
    input   wire            addr_num    ,
    
    output  reg             IIC_SCL     ,
    inout   wire            IIC_SDA     ,
    output  reg             IIC_clk     ,
    output  reg             IIC_end     ,
    output  reg     [7:0]   rd_data     
    
);

    reg     [4:0]       cnt_1M          ;      //计数最大值是25  一个五位宽的寄存器足以胜任计数任务
    reg     [15:0]      state           ;
    reg     [1:0]       IIC_clk_cnt     ;
    reg                 EN_IIC_clk_cnt  ;
    reg     [2:0]       bit_cnt         ;
    reg                 ack             ;
    reg                 sda_out         ;
    reg     [7:0]       rd_data_reg     ;
        
    wire                sda_in          ;
    wire                EN_IIC_SDA      ;
    
    parameter IDLE        =  16'b0000_0000_0000_0001    ;       //空闲状态
    parameter START       =  16'b0000_0000_0000_0010    ;       //发送开始信号
    parameter SEND_D_A    =  16'b0000_0000_0000_0100    ;       //发送控制命令(器件地址+写操作)   {7'b1010_011,1'b0}
    parameter ACK_1       =  16'b0000_0000_0000_1000    ;       //等待响应 
    parameter SEND_B_H    =  16'b0000_0000_0001_0000    ;       //发送存储地址高8位  
    parameter ACK_2       =  16'b0000_0000_0010_0000    ;       //等待响应
    parameter SEND_B_L    =  16'b0000_0000_0100_0000    ;       //发送存储地址低8位
    parameter ACK_3       =  16'b0000_0000_1000_0000    ;       //等待响应
    parameter WR_DATA     =  16'b0000_0001_0000_0000    ;       //写入单比特数据   
    parameter ACK_4       =  16'b0000_0010_0000_0000    ;       //等待响应
    parameter START_2     =  16'b0000_0100_0000_0000    ;       //发送开始信号
    parameter SEND_RD_A   =  16'b0000_1000_0000_0000    ;       //发送控制命令(器件地址+读操作)   {7'b0101_011,1'b1} 
    parameter ACK_5       =  16'b0001_0000_0000_0000    ;       //等待响应
    parameter RD_DATA     =  16'b0010_0000_0000_0000    ;       //读出单比特数据
    parameter NO_ACK      =  16'b0100_0000_0000_0000    ;       //等待无响应信号
    parameter END         =  16'b1000_0000_0000_0000    ;       //结束单比特传输
    
    parameter DEVICE_ADD  =  7'b1010_011 ;                      //EEPROM器件地址设定
    

/*-----------IIC_clk生成模块--------------------*/
//IIC_clk 频率要求1MHz,而系统时钟clk频率为50MHz,半个周期需要计数25次(5位寄存器)

always@(posedge clk or negedge reset_n)
    if(!reset_n)
        cnt_1M <= 5'd0;
    else if(cnt_1M == 5'd24)
        cnt_1M <= 5'd0;
    else 
        cnt_1M <= cnt_1M + 5'd1;
     
always@(posedge clk or negedge reset_n)
    if(!reset_n)
        IIC_clk <= 1'd0;
    else if(cnt_1M == 5'd24)
        IIC_clk <= ~IIC_clk;
    else 
        IIC_clk <= IIC_clk;
  
/*----------------状态机设计-----------------------*/  

always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        state <= IDLE;
    else begin
        case(state)
            IDLE      :
                        if(IIC_start)
                            state <= START;
                        else 
                            state <= state;
            START     : 
                        if(IIC_clk_cnt == 2'd3)
                            state <= SEND_D_A;
                        else 
                            state <= state;           
            SEND_D_A  : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= ACK_1;
                        else 
                            state <= state;
            ACK_1     : 
                        if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) &&  (addr_num == 1'd1))
                            state <= SEND_B_H;
                        else if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (addr_num == 1'd0))
                            state <= SEND_B_L;
                        else 
                            state <= state;  
            SEND_B_H  : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= ACK_2;
                        else 
                            state <= state;
            ACK_2     : 
                        if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))
                            state <= SEND_B_L;
                        else 
                            state <= state;  
            SEND_B_L  : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= ACK_3;
                        else 
                            state <= state;
            ACK_3     : 
                        if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (wr_en == 1'd1))
                            state <= WR_DATA;
                        else if((IIC_clk_cnt == 2'd3) && (ack == 1'd0) && (rd_en == 1'd1))
                            state <= START_2;
                        else 
                            state <= state;
            WR_DATA   : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= ACK_4;
                        else 
                            state <= state;
            ACK_4     : 
                        if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))
                            state <= END;
                        else 
                            state <= state; 
            START_2   : 
                        if(IIC_clk_cnt == 2'd3)
                            state <= SEND_RD_A;
                        else 
                            state <= state; 
            SEND_RD_A : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= ACK_5;
                        else 
                            state <= state;
            ACK_5     : 
                        if((IIC_clk_cnt == 2'd3) && (ack == 1'd0))
                            state <= RD_DATA;
                        else 
                            state <= state; 
            RD_DATA   : 
                        if((bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
                            state <= NO_ACK;
                        else 
                            state <= state;
            NO_ACK    : 
                        if(IIC_clk_cnt == 2'd3)
                            state <= END;
                        else 
                            state <= state; 
            END       : 
                        if((bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))
                            state <= IDLE;
                        else 
                            state <= state;
            default   : state <= IDLE;
        endcase       
    end
        
/*----------------IIC_clk_cnt 、 EN_IIC_clk_cnt设计-----------------------*/
always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        IIC_clk_cnt <= 2'd0;
    else if(!EN_IIC_clk_cnt) 
        IIC_clk_cnt <= 2'd0;
    else 
        IIC_clk_cnt <= IIC_clk_cnt + 2'd1;

always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        EN_IIC_clk_cnt <= 1'd0;
    else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))
        EN_IIC_clk_cnt <= 1'd0;
    else if(IIC_start)
        EN_IIC_clk_cnt <= 1'd1;
    else 
        EN_IIC_clk_cnt <= EN_IIC_clk_cnt;

/*--------------------bit_cnt设计-----------------------*/
always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        bit_cnt <= 3'd0;
    else if((state == IDLE)||(state == START)||(state == ACK_1)
                ||(state == ACK_2)||(state == ACK_3)||(state == ACK_4) 
                ||(state == START_2)||(state == ACK_5)||(state == NO_ACK))
        bit_cnt <= 3'd0;
    else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))
        bit_cnt <= 3'd0;
    else if(IIC_clk_cnt == 2'd3)
        bit_cnt <= bit_cnt + 3'd1;
    else 
        bit_cnt <= bit_cnt;

/*--------------------ack 、 sda_in信号设计---------------------------*/
always@(*)
    begin
        case(state)
            ACK_1,ACK_2,ACK_3,ACK_4,ACK_5   : if(IIC_clk_cnt == 2'd0)
                                                    ack <= sda_in   ;
                                              else 
                                                    ack <= ack      ;
            default                         : ack = 1'd1;
        endcase
    end

assign sda_in = IIC_SDA ;

/*--------------------IIC_SCL设计-----------------------*/
always@(*)
    begin
        case(state)
            IDLE:
                    IIC_SCL <= 1'd1;
            START:
                    if(IIC_clk_cnt == 2'd3)
                        IIC_SCL <= 1'd0;
                    else 
                        IIC_SCL <= 1'd1;
            SEND_D_A,ACK_1,SEND_B_H,ACK_2,SEND_B_L,ACK_3,WR_DATA,
                ACK_4,START_2,SEND_RD_A,ACK_5,RD_DATA,NO_ACK:
                    if((IIC_clk_cnt == 2'd1) || (IIC_clk_cnt == 2'd2))
                        IIC_SCL <= 1'd1;
                    else 
                        IIC_SCL <= 1'd0;
            END:
                    if((bit_cnt == 3'd0) && (IIC_clk_cnt == 2'd0))
                        IIC_SCL <= 1'd0;
                    else 
                        IIC_SCL <= 1'd1;
            default:
                    IIC_SCL <= 1'd1;
        endcase
    end
    
/*--------------------sda_out 、 rd_data_reg设计-----------------------*/
always@(*)
    begin
        case(state)
            IDLE        :begin
                            sda_out <= 1'd1; 
                            rd_data_reg <= 8'd0;
                         end
            START       :
                if(IIC_clk_cnt >= 2'd1)
                    sda_out <= 1'd0; 
                else 
                    sda_out <= 1'd1;
            SEND_D_A    :
                if(bit_cnt <= 3'd6)
                    sda_out <= DEVICE_ADD[6 - bit_cnt];
                else 
                    sda_out <= 1'd0;
            ACK_1,ACK_2,ACK_3,ACK_4,ACK_5   :
                sda_out <= 1'd1;
            SEND_B_H    :  
                sda_out <= byte_addr[15-bit_cnt]; 
            SEND_B_L    :  
                sda_out <= byte_addr[7-bit_cnt];     
            WR_DATA     :
                sda_out <= wr_data[7-bit_cnt];        
            START_2     :
                if(IIC_clk_cnt >= 2'd2)
                    sda_out <= 1'd0; 
                else 
                    sda_out <= 1'd1;   
            SEND_RD_A   :
                if(bit_cnt <= 3'd6)
                    sda_out <= DEVICE_ADD[6 - bit_cnt];
                else 
                    sda_out <= 1'd1;                 
            RD_DATA     :begin
                            sda_out <= 1'd1;
                            if(IIC_clk_cnt == 2'd2)
                                rd_data_reg[7 - bit_cnt] <=  sda_in;
                            else    
                                rd_data_reg <= rd_data_reg;
                         end
            NO_ACK      :
                sda_out <= 1'd1;
            END         :
                if((bit_cnt == 3'd0) && (IIC_clk_cnt <= 2'd2))
                    sda_out <= 1'd0;
                else 
                    sda_out <= 1'd1;
            default     :begin
                    sda_out <= 1'd1;
                    rd_data_reg <= rd_data_reg;
            end
        endcase
    end
 
/*--------------------rd_data设计-----------------------*/ 
always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        rd_data <= 8'd0;
    else if((state == RD_DATA) && (bit_cnt == 3'd7) && (IIC_clk_cnt == 2'd3))
        rd_data <= rd_data_reg;
    else    
        rd_data <= rd_data;
        
/*--------------------EN_IIC_SDA设计-----------------------*/ 
//EN_IIC_SDA信号为1,表示IIC_SDA输出;反之,EN_IIC_SDA信号为0,表示IIC_SDA作为输入.

assign EN_IIC_SDA = ((state == IDLE) || (state == START) || (state == SEND_D_A) 
                        || (state == SEND_B_H) || (state == SEND_B_L) || (state == WR_DATA)
                        || (state == START_2) || (state == SEND_RD_A) || (state == NO_ACK)
                        || (state == END));
                        
/*--------------------IIC_SDA设计-----------------------*/ 
assign IIC_SDA = EN_IIC_SDA ? sda_out : 1'dz;

/*--------------------IIC_end设计-----------------------*/ 
always@(posedge IIC_clk or negedge reset_n)
    if(!reset_n)
        IIC_end <= 1'd0;
    else if((state == END) && (bit_cnt == 3'd3) && (IIC_clk_cnt == 2'd3))
        IIC_end <= 1'd1;
    else 
        IIC_end <= 1'd0;

endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2081016.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows Docker 部署 SolrCloud

一、简介 Solr 集群是一个基于 Lucene 的高性能全文搜索服务器集群&#xff0c;它通过集成 ZooKeeper 来实现分布式索引和搜索功能。Solr 集群具备以下特点&#xff1a; 分布式索引与搜索&#xff1a;Solr 能够将大索引分成多个小索引&#xff0c;分布在多个节点上&#xff0…

网络安全实训六(靶机实例DC-3)

1 信息收集 1.1 获取靶机IP 1.2 扫描靶机网站的目录 1.3 扫描端口和服务器信息 1.4 进入网站 1.5 在msf中给搜索joomla扫描器 1.6 设置参数查看joomla版本信息 1.7 按照版本号搜索漏洞 1.8 查看漏洞使用 2 渗透 2.1 查看是否存在SQL注入 2.2 获取到数据库信息 2.3 爆破列表 2…

Datawhale AI夏令营第五期学习!

学习日志 日期&#xff1a; 2024年8月27日 今日学习内容&#xff1a; 今天&#xff0c;我学习了如何在深度学习任务中使用卷积神经网络&#xff08;CNN&#xff09;进行图像分类的基本流程&#xff0c;并成功地在JupyterLab中运行了一个完整的项目。以下是我今天的学习和操作…

【html+css 绚丽Loading】000021 万象轮回珠

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享htmlcss 绚丽Loading&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495…

使用C#进行屏幕截图(screenCapturer)

1.具体是应用了Nuget包 ScreenCapturer 2.编写相关核心代码&#xff0c;实现截取电脑部分区域图片 ScreenCapturer.ScreenCapturerTool screenCapturer new(); if (screenCapturer.ShowDialog() DialogResult.OK) {Bitmap bmp (Bitmap)screenCapturer.Image;pictureBox1.Ba…

【不合理的递归区间】快排递归引发区间错误,除以0未定义

问题描述 力扣语法报错&#xff1a;含义是有可能会除以0&#xff0c;该行为未定义&#xff0c;但问题是我这里压根就没用到除法。 #include<stdlib.h> #include<time.h>class Solution { public:vector<int> sortArray(vector<int>& nums) {sra…

【JavaWeb】定时任务和批量插入数据库数据

定时任务 需要在项目启动类添加注解开启支持定时任务&#xff1a; 以下示例是定时任务插入数据的操作&#xff1a; package com.yupi.yupao.once.importuser;import com.yupi.yupao.mapper.UserMapper; import com.yupi.yupao.model.domain.User; import org.springframework…

软件测试——论坛系统测试用例

功能测试 其他测试 测试用例 用例编号 用例描述 优先级 预置条件 操作步骤 测试数据 预期结果 测试结果Bug ID软件版本测试员SNS_User_Register_001注册成功使用合法的数据成功注册一个新账号P11、已打开注册页面 2、准备一个未注册用户信息1、输入用户昵称 2、输入用户名 3、…

Unity(2022.3.41LTS) - 摄像机

目录 一、基本概念 二、重要属性 三、摄像机模式 四、脚本控制 五、渲染设置 六. 组件详细介绍 一、基本概念 作用&#xff1a;摄像机决定了玩家在游戏中能够看到的内容。它就像是玩家的眼睛&#xff0c;从特定的位置和角度观察场景&#xff0c;并将场景中的物体渲染到屏…

北冥坞“学件”系统

简介 学件由周志华教授在 2016 年提出 [1, 2]。在学件范式下&#xff0c;世界各地的开发者可分享模型至学件基座系统&#xff0c;系统通过有效查搜和复用学件帮助用户高效解决机器学习任务&#xff0c;而无需从零开始构建机器学习模型。 北冥坞是学件的第一个系统性开源实现&…

客户端字符集小于数据库字符集导致乱码

一、现象 使用plsql或者sqlplus客户端 查询某个表的数据库均显示乱码&#xff0c;如下图所示&#xff1a; 二、原因分析 1、查看数据库的字符集 2、查看客户端的字符集 3、比较 数据库的字符集AL16UTF18&#xff08;服务端&#xff09;是大于en_US.UTF-8&#xff08;客户端&…

【Linux】gcc(工具篇)

文章目录 背景知识gcc的使用预处理&#xff08;进行宏替换&#xff09;编译&#xff08;生成汇编&#xff09;汇编&#xff08;生成机器可识别代码&#xff09;连接&#xff08;生成可执行文件或库文件&#xff09; gcc选项函数库函数库一般分为静态库和动态库两种C/C静态库的安…

Python 程序设计基础教程

Python 程序设计基础教程 撰稿人&#xff1a;南星六月雪 第 一 章 变量与简单数据类型 1.1 变量 先来观察以下程序&#xff1a; world "Hello Python!" print(world)world "Hello Python,I love you!" print(world)运行这个程序&#xff0c;将看到两…

一个利用率超高的大数据实验室是如何练成的?

在当今这个数据爆炸的时代&#xff0c;大数据已成为推动各行各业创新与发展的核心动力。一个高效运转、利用率超高的大数据实验室&#xff0c;不仅是技术创新的摇篮&#xff0c;更是企业竞争力的重要体现。那么&#xff0c;如何构建并维持这样一个实验室呢&#xff1f;本文将探…

【机器学习】软输出和硬输出的基本概念和区别、如何选择软输出还是硬输出、联系函数的作用以及线性判别分析和逻辑回归的基本概念(含python代码)

引言 在机器学习中&#xff0c;“软输出”&#xff08;Soft Output&#xff09;和"硬输出"&#xff08;Hard Output&#xff09;是两种不同的预测输出形式&#xff0c;通常用于分类问题中 文章目录 引言一、软输出和硬输出1.1 硬输出&#xff08;Hard Output&#xf…

深入理解C语言指针原理——深入底层机制

概述 在C语言中&#xff0c;指针是处理内存的核心工具。为了更好地理解指针如何工作&#xff0c;我们需要深入了解指针与底层硬件和操作系统之间的交互方式。本文将探讨指针的底层实现、内存布局、以及它们如何影响程序的行为。 内存模型 虚拟内存 现代操作系统为每个进程提…

Java算法—排序篇之快速排序(Quick sort)

快速排序&#xff08;Quick sort&#xff09; 核心思路&#xff1a; 从数列中挑出一个元素&#xff0c;一般都是左边第一个数字&#xff0c;称为 “基准数”;创建两个指针&#xff0c;一个从前往后走&#xff0c;一个从后往前走。先执行后面的指针&#xff0c;找出第一个比基…

io进程----库

目录 一丶定义 二丶分类 1.静态库 2.动态库 三丶静态库制作 四丶动态库制作 总结&#xff1a; 一丶定义 当使用别人的函数时除了包含头文件以外还需要有库 头文件&#xff1a;函数声明、结构体等类型定义、头文件、宏定义、其他头文件等 库&#xff1a;把一些常…

Java 使用QQ邮箱的接收发送功能,入门级教程

进入qq邮箱主页面&#xff0c;点击账号 下滑找到POP3...如果没有开启&#xff0c;需要开启&#xff0c;开启后&#xff0c;点击管理服务 然后点击生成授权码 按照步骤执行完成后&#xff0c;会给你需要的授权码 1.拿到授权码后&#xff0c;导入相关依赖&#xff0c;和yml相关配…

基于STM32开发的智能家居温度控制系统

目录 引言环境准备工作 硬件准备软件安装与配置系统设计 系统架构硬件连接代码实现 系统初始化温度监测与显示风扇/加热器控制Wi-Fi通信与远程监控应用场景 家庭环境的智能温度管理办公楼的节能温控系统常见问题及解决方案 常见问题解决方案结论 1. 引言 随着人们对生活质量…