用Verilog设计1个单周期8位CPU_模拟8051主要功能和部份指令

一、 任务

  1. 了解用Logisim(或Logisim Revolution、LogicCircuit)从低层门电路开始、逐步设计手工画电路实现一个简单自定义的简单8位CPU的方法和过程。试着改用Verilog 编程设计一个 简单周期CPU框架,能够仿真运行若干类 简单的加减法、逻辑运算、跳转指令等指令。
  2. 了解8051单片机。安装Proteus8软件,设计一个LED流水灯电路,分别用C语言和 51汇编语言编程,实现流水灯正常工作。并解释电路原理图设计、代码设计的工作原理。提交任务时须提交Proteus电路和Keil 源码、可执行Hex文件。 思考下一步你打算模拟实现哪部分8051指令集(以要测试的简单小程序汇编代码依据),将小汇编程序逐条语句手工地翻译为二进制程序数据。

二、 过程

2.1 简单自定义的简单16*16RAM

2.1.1 1 bit memory

需要用到:

  1. 与非门
    在这里插入图片描述

  2. 输入输出
    在这里插入图片描述
    如图绘制:
    在这里插入图片描述
    效果为:
    1)当s为1时,输出o与输入i保持一致,相当于把i的数值存到了o处;
    2)当s为0时,输入i的变化不影响输出o,输出o的值保持原来的值不变。
    可以绘制完可以测试一下
    封装
    在这里插入图片描述
    在这里插入图片描述

2.1.2 8bit memory

添加八个1 bit memeory
在这里插入图片描述
添加8位宽输入输出
在这里插入图片描述
在这里插入图片描述
连接电路图
可以使用总线拆分器
在这里插入图片描述
调整位宽
在这里插入图片描述
在这里插入图片描述
封装
在这里插入图片描述

2.1.3 8-bit Enable

需要用到:
8个与门
1个8位输入
1个1位输入
1个8位输出

在这里插入图片描述
封装
在这里插入图片描述

2.1.4 寄存器组装

在这里插入图片描述
封装
在这里插入图片描述

2.1.5 3-8译码器

需要:
与门 8个
输入 3个
非门 3个
输出 8个
在这里插入图片描述
连线
在这里插入图片描述
封装
在这里插入图片描述

2.1.6 存储器地址寄存器

与寄存器相似,但是e管脚要设置为常量1
在这里插入图片描述
常量可以在这找到
在这里插入图片描述
封装
在这里插入图片描述

2.1.7 4x16Decoder

跟38译码器类似,如图构建
在这里插入图片描述
封装
在这里插入图片描述

2.1.8 内存RAM

  1. 构建一个存储单元
    需要用到8-bit Register
    如图连接:
    在这里插入图片描述
    封装
    在这里插入图片描述
  2. 构建整个256RAM
    首先搭建框架:
    在这里插入图片描述
    连接16x16个RAM单元
    在这里插入图片描述
    封装
    在这里插入图片描述

2.2 用Verilog 编程设计一个 简单周期CPU框架,能够仿真运行若干类 简单的加减法、逻辑运算、跳转指令等指令。

2.2.1 PCADD4

  1. PCADD4
module PCadd4(PC_o,PCadd4);
    input [31:0] PC_o;//偏移量
    output [31:0] PCadd4;//新指令地址
    CLA_32 cla32(PC_o,4,0, PCadd4, Cout);
endmodule

  1. CLA_32
module CLA_32(X,Y,Cin,S,Cout);
    input[31:0]X,Y;
    input Cin;
    output[31:0]S;
    output Cout;
    wire Cout0,Cout1,Cout2,Cout3,Cout4,Cout5,Cout6;
    CLA_4 add0(X[3:0],Y[3:0],Cin,S[3:0],Cout0);
    CLA_4 add1(X[7:4],Y[7:4],Cout0,S[7:4],Cout1);
    CLA_4 add2(X[11:8],Y[11:8],Cout1,S[11:8],Cout2);
    CLA_4 add3(X[15:12],Y[15:12],Cout2,S[15:12],Cout3);
    CLA_4 add4(X[19:16],Y[19:16],Cout3,S[19:16],Cout4);
    CLA_4 add5(X[23:20],Y[23:20],Cout4,S[23:20],Cout5);
    CLA_4 add6(X[27:24],Y[27:24],Cout5,S[27:24],Cout6);
    CLA_4 add7(X[31:28],Y[31:28],Cout6,S[31:28],Cout);
endmodule

  1. CLA_4
module CLA_4(X,Y,Cin,S,Cout);
    input [3:0]X,Y;
    output Cout;
    input Cin;
    output [3:0]S;
    and i0(Y_3,X[3],Y[3]);
    or i1(X_3,X[3],Y[3]);
    and i2(Y_2,X[2],Y[2]);
    or i3(X_2,X[2],Y[2]);
    and i4(Y_1,X[1],Y[1]);
    or i5(X_1,X[1],Y[1]);
    and i6(Y_0,X[0],Y[0]);
    or i7(X_0,X[0],Y[0]);
    not i01(Y_31,Y_3);
    nand i02(Y_32,X_3,Y_2);
    nand i03(Y_33,X_3,X_2,Y_1);
    nand i04(Y_34,X_3,X_2,X_1,Y_0);
    nand i05(Y_35,X_3,X_2,X_1,X_0,Cin);
    nand i00(Cout,Y_31,Y_32,Y_33,Y_34,Y_35);//Cout的输出门级电路实现
    not i_2(Y__3,Y_3);
    and i21(Y_21,Y__3,X_3);
    not i22(Y_22,Y_2);
    nand i23(Y_23,X_2,Y_1);
    nand i24(Y_24,X_2,X_1,Y_0);
    nand i25(Y_25,X_2,X_1,X_0,Cin);
    nand i26(Y_26,Y_22,Y_23,Y_24,Y_25);
    xor i20(S[3],Y_21,Y_26);//S3的输出门级电路实现
    not i_1(Y__2,Y_2);
    and i11(Y_11,Y__2,X_2);
    not i12(Y_12,Y_1);
    nand i13(Y_13,X_1,Y_0);
    nand i14(Y_14,X_1,X_0,Cin);
    nand i15(Y_15,Y_12,Y_13,Y_14);
    xor i10(S[2],Y_11,Y_15);//S2的输出门级电路实现
    not i_0(Y__1,Y_1);
    and i51(Y_51,Y__1,X_1);
    not i52(Y_52,Y_0);
    nand i53(Y_53,X_0,Cin);
    nand i54(Y_54,Y_52,Y_53);
    xor i50(S[1],Y_51,Y_54);//S1的输出门级电路
    not i41(Y__0,Y_0);
    and i42(Y_4,Y__0,X_0);
    xor i40(S[0],Y_4,Cin);//S0的输出门级电路
endmodule

2.2.2 PC

module PC(Clk,Reset,Result,Address);  
    input Clk;//时钟
    input Reset;//是否重置地址。0-初始化PC,否则接受新地址       
    input[31:0] Result;
    output reg[31:0] Address;
    initial begin
        Address  <= 0;
    end
    always @(posedge Clk or negedge Reset)  
    begin  
        if (Reset==0) //如果为0则初始化PC,否则接受新地址
            begin  
                Address <= 0;  
            end  
        else   
            begin
                Address =  Result;  
        end  
    end  
endmodule

2.2.3 INSTMEM

module INSTMEM(Addr,Inst);//指令存储器
    input[31:0]Addr;
    //状态为'0',写指令寄存器,否则为读指令寄存器
    output[31:0]Inst;
    wire[31:0]Rom[31:0];
    assign Rom[5'h00]=32'h20010008;//addi $1,$0,8 $1=8
    assign Rom[5'h01]=32'h3402000C;//ori $2,$0,12 $2=12
    assign Rom[5'h02]=32'h00221820;//add $3,$1,$2 $3=20
    assign Rom[5'h03]=32'h00412022;//sub $4,$2,$1 $4=4
    assign Rom[5'h04]=32'h00222824;//and $5,$1,$2 $5=8
    assign Rom[5'h05]=32'h00223025;//or $6,$1,$2 $6=12
    assign Rom[5'h06]=32'h14220002;//bne $1,$2,2
    assign Rom[5'h07]=32'hXXXXXXXX;
    assign Rom[5'h08]=32'hXXXXXXXX;
    assign Rom[5'h09]=32'h10220002;// beq $1,$2,2
    assign Rom[5'h0A]=32'h0800000D;// J 0D 
    assign Rom[5'h0B]=32'hXXXXXXXX;
    assign Rom[5'h0C]=32'hXXXXXXXX;
    assign Rom[5'h0D]=32'hAD02000A;// sw $2 10($8) memory[$8+10]=10
    assign Rom[5'h0E]=32'h8D04000A;//lw $4 10($8) $4=12
    assign Rom[5'h0F]=32'h00221826;//xor $3,$1,$2
    assign Rom[5'h10]=32'h00021900;//sll $3,$2,4
    assign Rom[5'h11]=32'h00021902;//srl $3,$2,4
    assign Rom[5'h12]=32'h00021903;//sra $3,$2,4
    assign Rom[5'h13]=32'h30470009;//andi $7,$2,9
    assign Rom[5'h14]=32'h382300EF;//xori $3,$1,0xef
    assign Rom[5'h15]=32'h3C011234;//lui $1,0x1234
    assign Rom[5'h16]=32'h0C00001A;//Jal 1A
    assign Rom[5'h17]=32'h0800001A;// J 1A
    assign Rom[5'h18]=32'hXXXXXXXX;
    assign Rom[5'h19]=32'hXXXXXXXX;
    assign Rom[5'h1A]=32'h03E00008;//Jr 16
    assign Rom[5'h1B]=32'hXXXXXXXX;
    assign Rom[5'h1C]=32'hXXXXXXXX;
    assign Rom[5'h1D]=32'hXXXXXXXX;
    assign Rom[5'h1E]=32'hXXXXXXXX;
    assign Rom[5'h1F]=32'hXXXXXXXX;
    assign Inst=Rom[Addr[6:2]];
endmodule

2.2.4 DATAMEM

module DATAMEM(Addr,Din,Clk,We,Dout);
    input [31:0]Addr,Din;
    input Clk,We;
    output [31:0]Dout;
	reg [31:0]ram[0:31];
	integer i;
	initial begin
        for ( i = 0 ; i <= 31 ; i = i + 1) 
            ram [i] = i;
    end
	always @ (posedge Clk) begin
        if (We) ram[Addr[6:2]] <= Din;
	end
	assign Dout = ram[Addr[6:2]];
endmodule


2.2.5 SHIFTER32_L2

module SHIFTER32_L2(X,Sh);
    input [31:0] X;
    output [31:0] Sh;
    parameter z=2'b00;
    assign Sh={X[29:0],z};
endmodule

2.2.6 SHIFTER_COMBINATION

module SHIFTER_COMBINATION(X,PCADD4,Sh);
    input [25:0] X;
    input [31:0] PCADD4;
    output [31:0] Sh;
    parameter z=2'b00;
    assign Sh={PCADD4[31:28],X[25:0],z};
endmodule

2.2.7 MUX4X32

module MUX4X32(A0, A1, A2, A3, S, Y);
    input [31:0] A0, A1, A2, A3;
    input [1:0] S;
    output [31:0] Y;
    function [31:0] select;
        input [31:0] A0, A1, A2, A3;
        input [1:0] S;
            case(S)
                2'b00: select = A0;
                2'b01: select = A1;
                2'b10: select = A2;
                2'b11: select = A3;
            endcase
    endfunction
    assign Y = select (A0, A1, A2, A3, S);
endmodule

2.2.8 MUX2X5

module MUX2X5(A0,A1,S,Y);
    input [4:0]A0,A1;
    input S;
    output [4:0] Y;
    function [4:0] select;
        input [4:0] A0,A1;
        input S;
            case(S)
                1'b0:select=A0;
                1'b1:select=A1;
        endcase
    endfunction
    assign Y=select(A0,A1,S);
endmodule

2.2.9 EXT16T32

module EXT16T32(X,Se,Y);
    input [15:0]X;
    input Se;
    output [31:0]Y;
    wire [31:0]E0,E1;
    wire [15:0]e={16{X[15]}};
    parameter z=16'b0;
    assign E0={z,X};
    assign E1={e,X};
    MUX2X32 i(E0,E1,Se,Y);
endmodule

2.2.10 MUX2X32

module MUX2X32(A0,A1,S,Y);
    input [31:0]A0,A1;
    input S;
    output [31:0]Y;
    function [31:0]select;
        input [31:0]A0,A1;
        input S;
        case(S)
            1'b0:select=A0;
            1'b1:select=A1;
        endcase
    endfunction
    assign Y = select(A0,A1,S);
endmodule

2.2.11 CONUNIT

module CONUNIT(
	input [5:0]Op,
	input [5:0]Func,
	input Z,
	output Regrt,
	output Se,
	output Wreg,
	output Aluqb,
	output [3:0]Aluc,
	output Wmem,
	output [1:0]Pcsrc,
	output Reg2reg,
	output shift,
	output j	
    );
    wire i_add = (Op == 6'b000000 & Func == 6'b100000)?1:0;
    wire i_sub = (Op == 6'b000000 & Func == 6'b100010)?1:0;
    wire i_and = (Op == 6'b000000 & Func == 6'b100100)?1:0;
    wire i_or  = (Op == 6'b000000 & Func == 6'b100101)?1:0;
    wire i_xor = (Op == 6'b000000 & Func == 6'b100110)?1:0;
    wire i_sll = (Op == 6'b000000 & Func == 6'b000000)?1:0;
    wire i_srl = (Op == 6'b000000 & Func == 6'b000010)?1:0;
    wire i_sra = (Op == 6'b000000 & Func == 6'b000011)?1:0;
    wire i_jr  = (Op == 6'b000000 & Func == 6'b001000)?1:0;
    //R
    wire i_addi = (Op == 6'b001000)?1:0;
    wire i_andi = (Op == 6'b001100)?1:0; 
    wire i_ori  = (Op == 6'b001101)?1:0;
    wire i_xori = (Op == 6'b001110)?1:0;
    wire i_lw   = (Op == 6'b100011)?1:0;
    wire i_sw   = (Op == 6'b101011)?1:0;
    wire i_beq  = (Op == 6'b000100)?1:0;
    wire i_bne  = (Op == 6'b000101)?1:0;
    wire i_lui  = (Op == 6'b001111)?1:0;
    //I
    wire i_j    = (Op == 6'b000010)?1:0;
    wire i_jal  = (Op == 6'b000011)?1:0;
    assign Wreg = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_or|i_xori|i_lw|i_lui|i_jal;
    assign Regrt = i_addi|i_andi|i_ori|i_xori|i_lw|i_sw|i_lui|i_beq|i_bne|i_j|i_jal;
    assign Reg2reg  = i_add|i_sub|i_and|i_or|i_xor|i_sll|i_srl|i_sra|i_addi|i_andi|i_ori|i_xori|i_sw|i_beq|i_bne|i_j|i_jal;
    assign Aluqb = i_add | i_sub | i_and | i_or | i_xor | i_sll | i_srl | i_sra | i_beq | i_bne |i_j;
    assign Se   = i_addi | i_lw | i_sw | i_beq | i_bne;
    assign Aluc[3] = i_sra;
    assign Aluc[2] = i_xor |i_lui | i_sll | i_srl | i_sra |i_xori;
    assign Aluc[1] = i_and | i_or | i_lui | i_srl | i_sra | i_andi | i_ori;
    assign Aluc[0] = i_sub | i_ori | i_or | i_sll | i_srl |i_sra| i_beq | i_bne;
    assign Wmem = i_sw;
    assign Pcsrc[0] = (i_beq&Z) | (i_bne&~Z) | i_jal | i_j;
    assign Pcsrc[1] = i_j | i_jr | i_jal;
    assign shift=i_sll | i_srl | i_sra;
    assign j=i_jal | i_jr;
endmodule

2.2.12 REGFILE

module REGFILE(Ra,Rb,D,Wr,We,Clk,Clrn,Qa,Qb);
    input [4:0]Ra,Rb,Wr;
    input [31:0]D;
    input We,Clk,Clrn;
    output [31:0]Qa,Qb;
    wire [31:0]Y;
    wire [31:0]Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0;
    DEC5T32E dec(Wr,We,Y);
    REG32 reg32(D,Y,Clk,Clrn,Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0);
    MUX32X32 select1(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,Ra,Qa);
    MUX32X32 select2(Q31,Q30,Q29,Q28,Q27,Q26,Q25,Q24,Q23,Q22,Q21,Q20,Q19,Q18,Q17,Q16,Q15,Q14,Q13,Q12,Q11,Q10,Q9,Q8,Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0,Rb,Qb);
endmodule

2.2.13 ALU

module ALU(X,Y,Aluc,R,Z);
    input[31:0]X,Y;
    input[3:0]Aluc;
    output[31:0]R;
    output Z;
    wire[31:0]d_as,d_and,d_or,d_xor,d_lui,d_sh,d;
    ADDSUB_32 as32(X,Y,Aluc[0],d_as);
    assign d_and=X&Y;
    assign d_or=X|Y;
    assign d_xor=X^Y;
    assign d_lui={Y[15:0],16'h0};
    SHIFTER shift(Y,X[10:6],Aluc[3],Aluc[1],d_sh);
    MUX6X32 select(d_and,d_or,d_xor,d_lui,d_sh,d_as,Aluc[3:0],R);
    assign Z=~|R;
endmodule

2.2.14 CPU

module CPU(Clk,Reset,Addr,Inst,Qa,Qb,ALU_R,NEXTADDR,D);
    input Clk,Reset;
    output [31:0] Inst,NEXTADDR,ALU_R,Qb,Qa,Addr,D;
    
    wire [31:0]Result,PCadd4,EXTIMM,InstL2,EXTIMML2,D1,X,Y,Dout,mux4x32_2,R;
    wire Z,Regrt,Se,Wreg,Aluqb,Reg2reg,Cout,Wmem,shift,j;
    wire [3:0]Aluc;
    wire [1:0]Pcsrc;
    wire [4:0]Wr,Wr1;
    
    PC pc(Clk,Reset,Result,Addr);
    PCadd4 pcadd4(Addr,PCadd4);
    INSTMEM instmem(Addr,Inst);
    
    CONUNIT conunit(Inst[31:26],Inst[5:0],Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg,shift,j);
    MUX2X5 mux2x5_1(Inst[15:11],Inst[20:16],Regrt,Wr1);
    MUX2X5 mux2x5_2(Wr1,31,j,Wr);
    EXT16T32 ext16t32(Inst[15:0],Se,EXTIMM);
    SHIFTER_COMBINATION shifter1(Inst[25:0],PCadd4,InstL2);
    SHIFTER shifter2(EXTIMM,2,0,0,EXTIMML2);
    REGFILE regfile(Inst[25:21],Inst[20:16],D,Wr,Wreg,Clk,Reset,Qa,Qb);
    MUX2X32 mux2x32_1(EXTIMM,Qb,Aluqb,Y);
    MUX2X32 mux2x32_2(Qa,Inst,shift,X);
    ALU alu(X,Y,Aluc,R,Z);
    DATAMEM datamem(R,Qb,Clk,Wmem,Dout); 
    MUX2X32 mux2x32_3(Dout,R,Reg2reg,D1);
    MUX2X32 mux2x32_4(D1,PCadd4,j,D);
    CLA_32 cla_32(PCadd4,EXTIMML2,0,mux4x32_2,Cout);
    MUX4X32 mux4x32(PCadd4,mux4x32_2,Qa,InstL2,Pcsrc,Result);
    assign NEXTADDR=Result;
    assign ALU_R=R;
endmodule

2.2.15 Test测试代码

module test();
reg Clk,Reset;
wire [31:0] Inst,NEXTADDR,ALU_R,Qb,Qa,Addr,D;
wire [31:0]Result,PCadd4,EXTIMM,InstL2,EXTIMML2,X,Y,Dout,mux4x32_2,R,D1;
wire Z,Regrt,Se,Wreg,Aluqb,Reg2reg,Cout,Wmem,shift,j;

wire [3:0]Aluc;
wire [1:0]Pcsrc;
wire [4:0]Wr,Wr1;
initial begin
Clk=0;
Reset=0;
#5
Reset<=1;
end
always #5 Clk=~Clk;

PC pc(Clk,Reset,Result,Addr);
PCadd4 pcadd4(Addr,PCadd4);
INSTMEM instmem(Addr,Inst);

CONUNIT conunit(Inst[31:26],Inst[5:0],Z,Regrt,Se,Wreg,Aluqb,Aluc,Wmem,Pcsrc,Reg2reg,shift,j);
MUX2X5 mux2x5_1(Inst[15:11],Inst[20:16],Regrt,Wr1);
MUX2X5 mux2x5_2(Wr1,31,j,Wr);
EXT16T32 ext16t32(Inst[15:0],Se,EXTIMM);
SHIFTER_COMBINATION shifter1(Inst[25:0],PCadd4,InstL2);
SHIFTER shifter2(EXTIMM,2,0,0,EXTIMML2);
REGFILE regfile(Inst[25:21],Inst[20:16],D,Wr,Wreg,Clk,Reset,Qa,Qb);
MUX2X32 mux2x32_1(EXTIMM,Qb,Aluqb,Y);
MUX2X32 mux2x32_2(Qa,Inst,shift,X);
ALU alu(X,Y,Aluc,R,Z);
DATAMEM datamem(R,Qb,Clk,Wmem,Dout);
MUX2X32 mux2x32_3(Dout,R,Reg2reg,D1);
MUX2X32 mux2x32_4(D1,PCadd4,j,D);
CLA_32 cla_32(PCadd4,EXTIMML2,0,mux4x32_2,Cout);
MUX4X32 mux4x32(PCadd4,mux4x32_2,Qa,InstL2,Pcsrc,Result);
assign NEXTADDR=Result;
assign ALU_R=R;
endmodule

2.2.16 运行结果

在这里插入图片描述

2.2 C51流水灯

1. 创建工程

点击新建

​​在这里插入图片描述

选择工程目录

在这里插入图片描述

然后一直点下一步知道出现一下页面,选择如下选项:

在这里插入图片描述

完成,在红圈处编写代码

在这里插入图片描述

2. 开始仿真
① 添加电元件

在这里插入图片描述

本次需要用到的元件:LED-YELLOW、RES

在这里插入图片描述

然后点击左侧边栏的LED-YELLOW,并将他旋转之后,再点击幕布添加到原理图内:

在这里插入图片描述

然后依次添加剩余7个LED和电阻

在这里插入图片描述

点击电阻的"30k"修改阻值

在这里插入图片描述

点击左侧总线模式,然后单击幕布,拖动到目标位置双击,添加总线:

在这里插入图片描述

点击左侧结点连接管脚如图:

在这里插入图片描述

添加电源:

在这里插入图片描述

如果自带电源请删除掉:

在这里插入图片描述

最后通过LBL给直线上编号,让支线根据编号对应:
在这里插入图片描述

② 使用Keil来编写代码
Ⅰ准备工作

下载Keil

Keil5 C51版 下载与安装教程(51单片机编程软件)_keil c51_Half_A的博客-CSDN博客

Ⅱ 创建项目

点击顶栏创建项目

在这里插入图片描述

这个界面选择“Mincrochip”的"AT89C51"

在这里插入图片描述

选是

在这里插入图片描述

左上角新建文件

在这里插入图片描述

Ⅲ 写入代码

复制以下代码:

	#include <reg51.h>
	#include <intrins.h>

	void delay_ms(int a)
	{
		int i,j;
		for(i=0;i<a;i++)
		{
			for(j=0;j<1000;j++) _nop_();
	
		}
	}
	
	void main(void)
	{
		while(1)
		{
			P0=0xfe;
			delay_ms(50);
			P0=0xfd;
			delay_ms(50);
			P0=0xfb;
			delay_ms(50);
			P0=0xf7;
			delay_ms(50);
			P0=0xef;
			delay_ms(50);
			P0=0xdf;
			delay_ms(50);
			P0=0xbf;
			delay_ms(50);
			P0=0x7f;
			delay_ms(50);
		}
	}

保存代码为main.c

在这里插入图片描述

在左侧边栏Source Group 1 文件夹右键添加main.c

在这里插入图片描述

Ⅳ 编译

点击魔法棒,在output栏勾选该选项,点ok

在这里插入图片描述

点击编译生成两个头文件

在这里插入图片描述

③ 仿真

双击Proteus界面的芯片

在这里插入图片描述

选择Keil代码目录下的.hex文件

在这里插入图片描述

点击运行

在这里插入图片描述

运行效果

在这里插入图片描述

参考链接

1.https://blog.csdn.net/qq_44040327/article/details/116395694
2. https://blog.csdn.net/lxr0106/article/details/133191034?spm=1001.2014.3001.5501
3. https://blog.csdn.net/qq_42840665/article/details/114003321

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值