• 28_基于FPGA的简易电子密码锁


    28_基于FPGA的简易电子密码锁

    实验原理

    设计一个密码锁的控制电路,当输入正确密码时,输出开锁信号,并同时用红灯亮、绿灯熄灭表示开锁;用绿灯亮、红灯熄灭表示关锁; 在锁的控制电路中储存一个可以修改的 4 位密码;从第一个按钮触动后的 5 秒内若未将锁打开,则电路自动复位并进入自锁状态,使之无法再打开,并由扬声器发出持续 20 秒的报警信号。

    硬件原理图

    实验代码

    控制模块

    -- ******************************************************************************

    -- 控制模块

    -- 操作步骤

    -- 上电首先按下key5按键进行复位操作

    -- (1)按下key3按键输入第一个密码,输入完第一个密码后按下key3;输入第二个密码,第二个密码输入完成后后按下key3

    -- 输入第三个密码,第三个密码输入完成后后按下key3;输入第四个密码,第四个密码输入完成后后按下key3,输入完成;

    -- (2)只有密码输入正确后才能进行修改密码;

    -- (3)修改密码操作如下:

    -- 按下key1进入修改密码状态,然后通过key2数字选择按键,每输入一个密码,按下key3按键一次,数码管跳至下一位,输入下一个密码,

    -- 4个密码输入完成后按下key4按键,确定输入的密码就会重新装载进去。第三位数码管会显示当前输入的密码的次序。

    -- 取消修改密码按下key5

    -- *******************************************************************************

    library IEEE;

    use IEEE.std_logic_1164.all;

    use IEEE.std_logic_unsigned.all;

    use IEEE.std_logic_arith.all;

    entity control is

    port(

    clk:in std_logic; --50M时钟输入

    reset_n:in std_logic; --复位信号输入

    set_signal:in std_logic; --设置密码按键

    select_signal:in std_logic; --

    ok_signal:in std_logic; --

    set_ok_signal:in std_logic; --

     

    fm_time_over:in std_logic; --蜂鸣器20秒相应完成信号

    fm_20:in std_logic;

    password1_out:out std_logic_vector(3 downto 0); --

    password2_out:out std_logic_vector(3 downto 0); --

    password3_out:out std_logic_vector(3 downto 0); --

    password4_out:out std_logic_vector(3 downto 0); --

    ok_signal_counter_out:out std_logic_vector(2 downto 0);--四个数码管的标号

    motor_open:out std_logic; --电机开关标志

    start_flag:out std_logic;

    password_yes:out std_logic;

    password_no:out std_logic;

    password_set_out:out std_logic

    );

    end control;

    architecture control_behave of control is

    signal key_counter:std_logic_vector(3 downto 0); --按键按下次数计数器

    signal password_set:std_logic; --设置密码标志,'1'为设置密码,'0'为没有设置密码

    signal password_set_finish:std_logic; --密码设置成功信号

    signal ok_signal_counter:std_logic_vector(2 downto 0);--输入密码个数计数器

    signal current_password1:std_logic_vector(3 downto 0);--当前第一个密码

    signal current_password2:std_logic_vector(3 downto 0);--当前第二个密码

    signal current_password3:std_logic_vector(3 downto 0);--当前第三个密码

    signal current_password4:std_logic_vector(3 downto 0);--当前第四个密码

    signal current_password1_temp:std_logic_vector(3 downto 0);--当前第一个密码

    signal current_password2_temp:std_logic_vector(3 downto 0);--当前第二个密码

    signal current_password3_temp:std_logic_vector(3 downto 0);--当前第三个密码

    signal current_password4_temp:std_logic_vector(3 downto 0);--当前第四个密码

    signal password1:std_logic_vector(3 downto 0); --输入第一个密码

    signal password2:std_logic_vector(3 downto 0); --输入第二个密码

    signal password3:std_logic_vector(3 downto 0); --输入第三个密码

    signal password4:std_logic_vector(3 downto 0); --输入第四个密码

    signal set_signal_re1:std_logic;

    signal set_signal_re2:std_logic;

    signal password_yes_temp:std_logic;

    signal password_no_temp:std_logic;

    signal start_flag_reg:std_logic;

    type state is(

    prepare,--准备状态

    start--开始状态

    );

    signal current_state:state;--一开始处于准备状态

     

    type set_state is(

    prepare,--准备状态

    start--开始状态

    );

    signal current_set_state:set_state;--一开始处于准备状态

    begin

    password_set_out <= not password_set;

    ok_signal_counter_out <= ok_signal_counter;

    start_flag <= start_flag_reg;

    -- //****************************************************************************************************

    -- // 模块名称:产生设置密码信号password_set

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    password_set <= '0';

    current_set_state <= prepare;

     

    current_password1 <= "0001";

    current_password2 <= "0001";

    current_password3 <= "0001";

    current_password4 <= "0001";

     

    elsif(clk'event and clk = '0')then--下降沿触发

    if((password_yes_temp = '1'and password_no_temp = '0') or password_set = '1')then--只有输入密码正确后才能修改密码

    case current_set_state is

    when prepare=>

    if(set_signal = '0')then

    current_set_state <= start;

    password_set <= '1';

    else

    current_set_state <= prepare;

    password_set <= '0';

    end if;

    when start =>

    if(set_ok_signal = '0')then--设置完成

    --重新装载密码

    current_password1 <= current_password1_temp;

    current_password2 <= current_password2_temp;

    current_password3 <= current_password3_temp;

    current_password4 <= current_password4_temp;

    current_set_state <= prepare;

    password_set <= '0';

    else

    password_set <= '1';

    current_set_state <= start;

    end if;

    when others=>null;

    end case;

    else

    null;

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:违时信号的产生

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    current_state <= prepare;

    start_flag_reg <= '0';

    elsif(clk'event and clk = '1')then--上升沿沿触发

    if(password_set = '0')then--非设置密码状态

    case current_state is

    when prepare=>

    if(select_signal = '0')then

    start_flag_reg <= '1';

    current_state <= start;

    else

    start_flag_reg <= '0';

    current_state <= prepare;

    end if;

    when start=>

    if(ok_signal_counter = "100")then--输入密码完成

    start_flag_reg <= '0';

    current_state <= prepare;

    elsif(fm_time_over = '1')then--蜂鸣器响应20s完成

    start_flag_reg <= '0';

    current_state <= prepare;

    else--两者未完成

    start_flag_reg <= '1';

    current_state <= start;

    end if;

    end case;

    else

    current_state <= prepare;

    start_flag_reg <= '0';

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:产生按键输入数字

    -- // 功能描述:

    -- //****************************************************************************************************

    process(select_signal,reset_n)

    begin

    if(reset_n = '0')then

    key_counter <= "0000";

    elsif(select_signal'event and select_signal = '0')then--下降沿触发

    if(key_counter = "1001")then

    key_counter <= "0000";

    else

    key_counter <= key_counter + '1';

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:统计输入密码的个数4

    -- // 功能描述:

    -- //****************************************************************************************************

    process(ok_signal,reset_n)

    begin

    if(reset_n = '0')then

    ok_signal_counter <= "000";

    elsif(ok_signal'event and ok_signal = '0')then--下降沿触发

    if(fm_20 = '0')then--在不违时的情况下可以进行输入密码

    if(ok_signal_counter = "100")then

    ok_signal_counter <= "001";

    --密码输入完成

    else

    ok_signal_counter <= ok_signal_counter + '1';

    end if;

    else

    ok_signal_counter <= "000";

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:存储输入密码的个数4

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    ----------------------------------

    current_password1_temp <= "0000";

    current_password2_temp <= "0000";

    current_password3_temp <= "0000";

    current_password4_temp <= "0000";

    ----------------------------------

    password_yes_temp <= '0';

    password_no_temp <= '1';

    password1 <= "0000";

    password2 <= "0000";

    password3 <= "0000";

    password4 <= "0000";

    motor_open <= '1';--电机关

    elsif(clk'event and clk = '1')then--上升沿触发

    if(fm_20 = '0')then--在不违时的情况下可以进行输入密码

    case ok_signal_counter is

    when "001"=>

    if(password_set = '0')then--非设置密码

    password1 <= key_counter;

    else--设置密码

    current_password1_temp <= key_counter;

    password1 <= "0000";

    motor_open <= '1';--电机关

    password_yes_temp <= '0';

    password_no_temp <= '0';

    end if;

    when "010"=>

    if(password_set = '0')then--非设置密码

    password2 <= key_counter;

    else--设置密码

    current_password2_temp <= key_counter;

    password2 <= "0000";

    motor_open <= '1';--电机关

    password_yes_temp <= '0';

    password_no_temp <= '0';

    end if;

    when "011"=>

    if(password_set = '0')then--非设置密码

    password3 <= key_counter;

    else--设置密码

    current_password3_temp <= key_counter;

    password3 <= "0000";

    motor_open <= '1';--电机关

    password_yes_temp <= '0';

    password_no_temp <= '0';

    end if;

    when "100"=>

    if(password_set = '0')then--非设置密码

    password4 <= key_counter;

    if(current_password1 = password1 and

    current_password2 = password2 and

    current_password3 = password3 and

    current_password4 = password4)then

    password_yes_temp <= '1';

    password_no_temp <= '0';

    motor_open <= '0';--电机开

    else

    password_yes_temp <= '0';

    password_no_temp <= '1';

    motor_open <= '1';--电机关

    end if;

    else--设置密码

    current_password4_temp <= key_counter;

    password4 <= "0000";

    motor_open <= '1';--电机关

    password_yes_temp <= '0';

    password_no_temp <= '0';

    end if;

    when others=>null;

    end case;

    else

    password_yes_temp <= '0';

    password_no_temp <= '1';

    password1 <= "0000";

    password2 <= "0000";

    password3 <= "0000";

    password4 <= "0000";

    motor_open <= '1';--电机关

    end if;

    end if;

    end process;

    -- 当处于设置密码状态时,两个灯是不亮的

    password_yes <= not ((password_yes_temp) and (not password_set));--接绿色led141引脚

    password_no <= not ((password_no_temp) and (not password_set));--接红色led142引脚

     

    -- //****************************************************************************************************

    -- // 模块名称:数码管显示数字选择模块

    -- // 功能描述:

    -- //****************************************************************************************************

    process(reset_n,password_set,

    current_password1_temp,current_password2_temp,current_password3_temp,current_password4_temp,

    password1,password2,password3,password4)

    begin

    if(reset_n = '0')then

    password1_out <= "0000";

    password2_out <= "0000";

    password3_out <= "0000";

    password4_out <= "0000";

    elsif(password_set = '1')then--设置密码

    password1_out <= current_password1_temp;

    password2_out <= current_password2_temp;

    password3_out <= current_password3_temp;

    password4_out <= current_password4_temp;

    else--非设置密码

    password1_out <= password1;

    password2_out <= password2;

    password3_out <= password3;

    password4_out <= password4;

    end if;

    end process;

     

     

    end control_behave;

     

    数码管显示模块

    -- ******************************************************************************

    -- 计时模块

    -- *******************************************************************************

    library IEEE;

    use IEEE.std_logic_1164.all;

    use IEEE.std_logic_unsigned.all;

    use IEEE.std_logic_arith.all;

    entity time_counter is

    port(

    clk:in std_logic; --50M时钟输入

    reset_n:in std_logic; --复位信号输入

    password1_in:in std_logic_vector(3 downto 0); --

    password2_in:in std_logic_vector(3 downto 0); --

    password3_in:in std_logic_vector(3 downto 0); --

    password4_in:in std_logic_vector(3 downto 0); --

    ok_signal_counter_in:in std_logic_vector(2 downto 0);

     

    seg_duan:out std_logic_vector(7 downto 0); --数码管段信号输出

    seg_wei:out std_logic_vector(7 downto 0) --数码管位信号输出

    );

    end time_counter;

    architecture time_counter_behave of time_counter is

    signal clk_1hz: std_logic;

    signal count: std_logic_vector(24 downto 0);

    signal clk_scan: std_logic;

    signal seg_select: std_logic_vector(2 downto 0);

    signal scan_count: std_logic_vector(13 downto 0);

    begin

    -- //****************************************************************************************************

    -- // 模块名称:50M时钟分频至1HZ模块

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    clk_1hz <= '0';

    count <= "0000000000000000000000000";

    elsif(clk'event and clk = '1')then--上升沿触发

    if(count = "1011111010111100001000000")then--

    count <= "0000000000000000000000000";

    clk_1hz <= not clk_1hz;

    else

    count <= count + '1';

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:数码管扫描时钟产生模块

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    scan_count <= "00000000000000";

    clk_scan <= '0';

    elsif(clk'event and clk = '1')then--上升沿触发

    if(scan_count = "10011100010000")then

    scan_count <= "00000000000000";

    clk_scan <= not clk_scan;

    else

    scan_count <= scan_count + '1';

    end if;

    end if;

    end process;

    process(clk_scan,reset_n)

    begin

    if(reset_n = '0')then

    seg_select <= "000";

    elsif(clk_scan'event and clk_scan = '1')then--上升沿触发

    seg_select <= seg_select + '1';

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:数码管显示模块

    -- // 功能描述:

    -- //****************************************************************************************************

    process(clk)

    begin

    if(clk'event and clk = '1')then--上升沿触发

    case seg_select is

    when "000"=>--显示第1个密码

    seg_wei <= "11111110";

    case password4_in is

    when "0000"=>seg_duan <= "11000000";--0

    when "0001"=>seg_duan <= "11111001";--1

    when "0010"=>seg_duan <= "10100100";--2

    when "0011"=>seg_duan <= "10110000";--3

    when "0100"=>seg_duan <= "10011001";--4

    when "0101"=>seg_duan <= "10010010";--5

    when "0110"=>seg_duan <= "10000010";--6

    when "0111"=>seg_duan <= "11111000";--7

    when "1000"=>seg_duan <= "10000000";--8

    when "1001"=>seg_duan <= "10010000";--9

    when others=>null;

    end case;

    when "001"=>--显示第2个密码

    seg_wei <="11111101";

    case password3_in is

    when "0000"=>seg_duan <= "11000000";--0

    when "0001"=>seg_duan <= "11111001";--1

    when "0010"=>seg_duan <= "10100100";--2

    when "0011"=>seg_duan <= "10110000";--3

    when "0100"=>seg_duan <= "10011001";--4

    when "0101"=>seg_duan <= "10010010";--5

    when "0110"=>seg_duan <= "10000010";--6

    when "0111"=>seg_duan <= "11111000";--7

    when "1000"=>seg_duan <= "10000000";--8

    when "1001"=>seg_duan <= "10010000";--9

    when others=>null;

    end case;

    when "010"=>--显示第3个密码

    seg_wei <="11111011";

    case password2_in is

    when "0000"=>seg_duan <= "11000000";--0

    when "0001"=>seg_duan <= "11111001";--1

    when "0010"=>seg_duan <= "10100100";--2

    when "0011"=>seg_duan <= "10110000";--3

    when "0100"=>seg_duan <= "10011001";--4

    when "0101"=>seg_duan <= "10010010";--5

    when "0110"=>seg_duan <= "10000010";--6

    when "0111"=>seg_duan <= "11111000";--7

    when "1000"=>seg_duan <= "10000000";--8

    when "1001"=>seg_duan <= "10010000";--9

    when others=>null;

    end case;

    when "011"=>--显示第4个密码

    seg_wei <="11110111";

    case password1_in is

    when "0000"=>seg_duan <= "11000000";--0

    when "0001"=>seg_duan <= "11111001";--1

    when "0010"=>seg_duan <= "10100100";--2

    when "0011"=>seg_duan <= "10110000";--3

    when "0100"=>seg_duan <= "10011001";--4

    when "0101"=>seg_duan <= "10010010";--5

    when "0110"=>seg_duan <= "10000010";--6

    when "0111"=>seg_duan <= "11111000";--7

    when "1000"=>seg_duan <= "10000000";--8

    when "1001"=>seg_duan <= "10010000";--9

    when others=>null;

    end case;

    when "100"=>--

    seg_wei <="11011111";--显示当前输入密码的次序

    case ('0' & ok_signal_counter_in) is

    when "0000"=>seg_duan <= "11000000";--0

    when "0001"=>seg_duan <= "11111001";--1

    when "0010"=>seg_duan <= "10100100";--2

    when "0011"=>seg_duan <= "10110000";--3

    when "0100"=>seg_duan <= "10011001";--4

    when "0101"=>seg_duan <= "10010010";--5

    when "0110"=>seg_duan <= "10000010";--6

    when "0111"=>seg_duan <= "11111000";--7

    when "1000"=>seg_duan <= "10000000";--8

    when "1001"=>seg_duan <= "10010000";--9

    when others=>null;

    end case;

    when others=>null;

    end case;

    end if;

    end process;

    end time_counter_behave;

     

    超时报警模块

    -- ******************************************************************************

    -- 按键模块,进行按键消抖和按键编码

    -- *******************************************************************************

    library IEEE;

    use IEEE.std_logic_1164.all;

    use IEEE.std_logic_unsigned.all;

    use IEEE.std_logic_arith.all;

    entity bell is

    port(

    clk:in std_logic; --50M时钟输入

    reset_n:in std_logic; --复位信号输入

    start_flag:in std_logic; --蜂鸣器开始相应信号

    fm_time_over:out std_logic;

    pwm_out:out std_logic; --蜂鸣器驱动脉冲

    fm_20:out std_logic

    );

    end bell;

    architecture bell_behave of bell is

    signal count:std_logic_vector(14 downto 0);

    signal pwm_signal:std_logic;

    signal long_count:std_logic_vector(14 downto 0);

    signal short_count:std_logic_vector(12 downto 0);

    signal pwm_en:std_logic;

    type state is(

    prepare,--准备状态

    start,--开始状态

    stop

    );

    signal current_state:state;--一开始处于准备状态

    begin

    fm_20 <= pwm_en;

    -- //****************************************************************************************************

    -- // 模块名称:蜂鸣器驱动脉冲产生模块

    -- // 功能描述:1KHz

    -- //****************************************************************************************************

    process(clk,reset_n)

    begin

    if(reset_n = '0')then

    count <= "000000000000000";

    pwm_signal <= '0';

    elsif(clk'event and clk = '1')then--上升沿触发

    if(count = "110000110101000")then

    count <= "000000000000000";

    pwm_signal <= not pwm_signal;

    else

    count <= count + '1';

    end if;

    end if;

    end process;

    -- //****************************************************************************************************

    -- // 模块名称:蜂鸣器响应时间产生模块

    -- // 功能描述:

    -- //****************************************************************************************************

    process(pwm_signal,reset_n)

    begin

    if(reset_n = '0')then

    current_state <= prepare;

    short_count <= "0000000000000";

    long_count <= "000000000000000";

    fm_time_over <= '0';

    pwm_en <= '0';

    elsif(pwm_signal'event and pwm_signal = '1')then--上升沿触发

    case current_state is

    when prepare=>

    if(start_flag = '1')then

    if(short_count = "1101101011000")then--5s

    short_count <= "0000000000000";

    current_state <= start;

    else

    short_count <= short_count + '1';

    current_state <= prepare;

    end if;

    else

    current_state <= prepare;

    short_count <= "0000000000000";

    long_count <= "000000000000000";

    fm_time_over <= '0';

    pwm_en <= '0';

    end if;

    when start=>

    if(long_count = "100111000100000")then--20s

    long_count <= "000000000000000";

    pwm_en <= '0';

    fm_time_over <= '1';

    current_state <= stop;

    else

    current_state <= start;

    long_count <= long_count + '1';

    pwm_en <= '1';

    fm_time_over <= '0';

    end if;

    when stop=>

    pwm_en <= '0';

    fm_time_over <= '1';

    current_state <= prepare;

    short_count <= "0000000000000";

    long_count <= "000000000000000";

    end case;

    end if;

    end process;

    pwm_out <= pwm_en and pwm_signal;

    end bell_behave;

     

    实验操作

    上电

    接入5V电源,用配套的线,USB那端接电脑即可;

    电源开关

    按下电源开关

    显示

    数码管开始显示

    显示的数码管为"0000"

    右边的四个是显示当前输入的密码,从左到右分别是第一个到第四个密码

    复位

    按下复位按键,此时数码管清零0000;

    电子锁自锁

    仅有红灯亮着,表示电子锁锁住了

    输入错误密码

    正确密码"1111",例如输入错误密码"2222"

    Key2用于选择输入密码数:0~9,选择好后按下key1按键,表示确定。

    第一步:按下key1按键输入第一个密码输入完第一个密码后按下key1。

    第二步:开始输入第二个密码,输入第二个密码,第二个密码输入完成后按下key1。

    第三步:开始输入第三个密码,输入第三个密码,第三个密码输入完成后按下key1。

    第四步:开始输入第四个密码,输入第四个密码,第四个密码输入完成后按下key1,输入完成;

    这个过程的操作必须在5s内,否则就违时,蜂鸣器就会响20s。

    完成后红色灯还是亮着的,绿色灯没有亮。

    输入正确密码

    输入正确密码"1111"

    Key2用于选择输入密码数:0~9,选择好后按下key1按键,表示确定。

    第一步:按下key1按键输入第一个密码,左边的数码管会显示1,输入完第一个密码后按下key1。

    第二步:开始输入第二个密码,输入第二个密码,第二个密码输入完成后按下key1。

    第三步:开始输入第三个密码,输入第三个密码,第三个密码输入完成后按下key1。

    第四步:开始输入第四个密码,输入第四个密码,第四个密码输入完成后按下key1,输入完成;

    这个过程的操作必须在5s内,否则就违时,蜂鸣器就会响20s。

    完成后红色灯灭,绿色灯亮;

     

    修改密码

    只有在输入正确密码后,才能进行修改密码;

    第一步:按下key1按键,ledD4亮,表示可以进行修改密码;

    第二步:输入新密码,输入新密码与输入密码的过程一致,输入完成后,让左边的数码管显示"1",然后按下key3按键,ledD4灭,表示确定输入的新密码,FPGA就会将新的密码进行加载。

    例如将新密码改为"2222"

    输入过程红灯和绿灯是不显示的。

    重新输入修改后的密码

    输入新的正确密码"2222"

    Key2用于选择输入密码数:0~9,选择好后按下key1按键,表示确定。

    第一步:按下key1按键输入第一个密码,左边的数码管会显示1,输入完第一个密码后按下key1。

    第二步:开始输入第二个密码,输入第二个密码,第二个密码输入完成后按下key1。

    第三步:开始输入第三个密码,输入第三个密码,第三个密码输入完成后按下key1。

    第四步:开始输入第四个密码,输入第四个密码,第四个密码输入完成后按下key1;

    这个过程的操作必须在5s内,否则就违时,蜂鸣器就会响20s。

    完成后红色灯灭,绿色灯亮;

     

    输入密码时间超过5s

    如果按下密码选择按键key1,然后在5s内没有输入好正确的密码,则蜂鸣器会响起。

    蜂鸣器响应20s

    在违时后蜂鸣器会相应20s,且这个时间内是不能进行密码输入的;

     

     

     

    大西瓜FPGA-->https://daxiguafpga.taobao.com

    配套开发板:https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-24211932856.3.489d7241aCjspB&id=633897209972

    博客资料、代码、图片、文字等属大西瓜FPGA所有,切勿用于商业! 若引用资料、代码、图片、文字等等请注明出处,谢谢!

       

    每日推送不同科技解读,原创深耕解读当下科技,敬请关注微信公众号"科乎"。

  • 相关阅读:
    Android studio 几个坑,值得注意下。
    Android studio使用技巧,不定期更新。
    Android生猛上手,先写个拨号器。
    Ubuntu11.10安装教程,非虚拟机
    在线编辑器CKEditor,多图上传功能实现
    sql 中的NULL小问题 ,大bug
    工资低的.Net程序员,活该你工资低
    30岁的老龄程序员 ,不学习就会被淘汰
    计算商品税额和商品价格保留小数的时候的坑
    大话设计模式--简单工厂模式
  • 原文地址:https://www.cnblogs.com/logic3/p/15915958.html
Copyright © 2020-2023  润新知