研究是基于:
SparkFun ATMEGA32U4 Breakout
https://github.com/sparkfun/32U4_Breakout_Board
32U4_Breakout_Board-master\Examples\32U4_digital_input
源码为:
main.c

/* Created 05/22/2012 by Jordan McConnell at Sparkfun Electronics* This code is beerware, you know what I'm sayin'?** Built on WinXP SP3 and WinAVR-20100110, AVRDUDE 5.10** This code is a simple example of digital input for Sparkfun's* 32U4 Breakout Board using C and standard AVR libraries.  It* teaches you how to read the status of a digital pin to determine* whether its current status is HIGH or LOW.** Pin PF0 is used as a digital input.  If its status is HIGH,* pin PD5 toggles each second, if it's status is LOW, pin PD6* toggles each second instead.** The user can connect LED's to pins PD5 and PD6 or use a multimeter* to verify operation.  If pin PF0 is left unconnected, it's status* will be HIGH due to internal pullup resistors, and PD5 toggles.* If PF0 is connected to ground, PD6 toggles each second instead.*/// Libraries for register names and the delay function
#include <avr/io.h>
#include <util/delay.h>// Macros to make bit manipulation easier
#define set_bit(address,bit) (address |= (1<<bit))
#define clear_bit(address,bit) (address &= ~(1<<bit))
#define toggle_bit(address,bit) (address ^= (1<<bit))// This macro is for checking if a certain bit is set in a given register.
// This is useful here for checking the status of individual input pins.
#define check_bit(address,bit) ((address & (1<<bit)) == (1<<bit))int main(void)
{// The following line sets bit 5 HIGH in register DDRDset_bit(DDRD,5); // Pin PD5 is now configured as an OUTPUTset_bit(DDRD,6); // Pin PD6 is now configured as an OUTPUT// The following line sets bit 0 LOW in register DDRFclear_bit(DDRF,0); // Pin PF0 is now configured as an INPUTset_bit(PORTF,0); // Turn on internal pullups for PF0while(1){// PINF is the register you have to read to check if a particular// pin on port F (PFx) is HIGH or LOWif(check_bit(PINF,0)){// If PF0 is HIGH, toggle pin PD5's output statustoggle_bit(PORTD,5);}else{// If PF0 is LOW, toggle pin PD6's output statustoggle_bit(PORTD,6);}_delay_ms(1000); // Delay 1 second before checking PF0 again}return 0;
}

Makefile

# Hey Emacs, this is a -*- makefile -*-
#----------------------------------------------------------------------------
# WinAVR Makefile Template written by Eric B. Weddington, J鰎g Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin O'Flynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool
# Frederik Rouleau
# Carlos Lamas
#
#----------------------------------------------------------------------------
# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
#                Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
#              with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#                   bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------# MCU name
MCU = atmega32u4# Processor frequency.
#     This will define a symbol, F_CPU, in all source code files equal to the
#     processor frequency. You can then use this symbol in your source code to
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
#     automatically to create a 32-bit value in your source code.
#     Typical values are:
#         F_CPU =  1000000
#         F_CPU =  1843200
#         F_CPU =  2000000
#         F_CPU =  3686400
#         F_CPU =  4000000
#         F_CPU =  7372800
#         F_CPU =  8000000
#         F_CPU = 11059200
#         F_CPU = 14745600
#         F_CPU = 16000000
#         F_CPU = 18432000
#         F_CPU = 20000000
F_CPU = 16000000# Output format. (can be srec, ihex, binary)
FORMAT = ihex# Target file name (without extension).
TARGET = main# Object files directory
#     To put object files in current directory, use a dot (.), do NOT make
#     this an empty or blank macro!
OBJDIR = ./obj# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c# List C++ source files here. (C dependencies are automatically generated.)
CPPSRC = # List Assembler source files here.
#     Make them always end in a capital .S.  Files ending in a lowercase .s
#     will not be considered source files but generated files (assembler
#     output from the compiler), and will be deleted upon "make clean"!
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
#     it will preserve the spelling of the filenames, and gcc itself does
#     care about how the name is spelled on its command-line.
ASRC =# Optimization level, can be [0, 1, 2, 3, s].
#     0 = turn off optimization. s = optimize for size.
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = s# Debugging format.
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
#     AVR Studio 4.10 requires dwarf-2.
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2# List any extra directories to look for include files here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS = # Compiler flag to set the C Standard level.
#     c89   = "ANSI" C
#     gnu89 = c89 plus GCC extensions
#     c99   = ISO C99 standard (not yet fully implemented)
#     gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99# Place -D or -U options here for C sources
CDEFS = -DF_CPU=$(F_CPU)UL# Place -D or -U options here for ASM sources
ADEFS = -DF_CPU=$(F_CPU)# Place -D or -U options here for C++ sources
CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS.......#---------------- Library Options ----------------
# Minimalistic printf version
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)# Minimalistic scanf version
SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)MATH_LIB = -lm# List any extra directories to look for libraries here.
#     Each directory must be seperated by a space.
#     Use forward slashes for directory separators.
#     For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS = 

编译过程:
重点看:avr-objdump -h -S -z main.elf > main.lss


-------- begin --------
avr-gcc (WinAVR 20100110) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.Compiling C: main.c
avr-gcc -c -mmcu=atmega32u4 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=./obj/main.lst  -std=gnu99 -MMD -MP -MF .dep/main.o.d main.c -o obj/main.o Linking: main.elf
avr-gcc -mmcu=atmega32u4 -I. -gdwarf-2 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=obj/main.o  -std=gnu99 -MMD -MP -MF .dep/main.elf.d obj/main.o --output main.elf -Wl,-Map=main.map,--cref     -lmCreating load file for Flash: main.hex
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature main.elf main.hexCreating load file for EEPROM: main.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \--change-section-lma .eeprom=0 --no-change-warnings -O ihex main.elf main.eep || exit 0Creating Extended Listing: main.lss
avr-objdump -h -S -z main.elf > main.lssCreating Symbol Table: main.sym
avr-nm -n main.elf > main.symSize after:
AVR Memory Usage
----------------
Device: atmega32u4Program:     248 bytes (0.8% Full)
(.text + .data + .bootloader)Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)-------- end --------

生成的中间文件:main.lss
内容为:


main.elf:     file format elf32-avrSections:
Idx Name          Size      VMA       LMA       File off  Algn0 .text         000000f8  00000000  00000000  00000054  2**1CONTENTS, ALLOC, LOAD, READONLY, CODE1 .debug_aranges 00000020  00000000  00000000  0000014c  2**0CONTENTS, READONLY, DEBUGGING2 .debug_pubnames 0000001b  00000000  00000000  0000016c  2**0CONTENTS, READONLY, DEBUGGING3 .debug_info   00000110  00000000  00000000  00000187  2**0CONTENTS, READONLY, DEBUGGING4 .debug_abbrev 000000b2  00000000  00000000  00000297  2**0CONTENTS, READONLY, DEBUGGING5 .debug_line   00000153  00000000  00000000  00000349  2**0CONTENTS, READONLY, DEBUGGING6 .debug_frame  00000020  00000000  00000000  0000049c  2**2CONTENTS, READONLY, DEBUGGING7 .debug_str    000000ff  00000000  00000000  000004bc  2**0CONTENTS, READONLY, DEBUGGING8 .debug_loc    00000038  00000000  00000000  000005bb  2**0CONTENTS, READONLY, DEBUGGING9 .debug_ranges 00000048  00000000  00000000  000005f3  2**0CONTENTS, READONLY, DEBUGGINGDisassembly of section .text:00000000 <__vectors>:0:   0c 94 56 00     jmp 0xac    ; 0xac <__ctors_end>4:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>8:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>10:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>14:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>18:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>1c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>20:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>24:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>28:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>2c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>30:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>34:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>38:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>3c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>40:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>44:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>48:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>4c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>50:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>54:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>58:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>5c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>60:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>64:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>68:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>6c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>70:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>74:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>78:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>7c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>80:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>84:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>88:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>8c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>90:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>94:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>98:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>9c:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>a0:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>a4:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>a8:   0c 94 60 00     jmp 0xc0    ; 0xc0 <__bad_interrupt>000000ac <__ctors_end>:ac:   11 24           eor r1, r1ae:   1f be           out 0x3f, r1    ; 63b0:   cf ef           ldi r28, 0xFF   ; 255b2:   da e0           ldi r29, 0x0A   ; 10b4:   de bf           out 0x3e, r29   ; 62b6:   cd bf           out 0x3d, r28   ; 61b8:   0e 94 62 00     call    0xc4    ; 0xc4 <main>bc:   0c 94 7a 00     jmp 0xf4    ; 0xf4 <_exit>000000c0 <__bad_interrupt>:c0:   0c 94 00 00     jmp 0   ; 0x0 <__vectors>000000c4 <main>:
#define check_bit(address,bit) ((address & (1<<bit)) == (1<<bit))int main(void)
{// The following line sets bit 5 HIGH in register DDRDset_bit(DDRD,5); // Pin PD5 is now configured as an OUTPUTc4:   55 9a           sbi 0x0a, 5 ; 10set_bit(DDRD,6); // Pin PD6 is now configured as an OUTPUTc6:   56 9a           sbi 0x0a, 6 ; 10// The following line sets bit 0 LOW in register DDRFclear_bit(DDRF,0); // Pin PF0 is now configured as an INPUTc8:   80 98           cbi 0x10, 0 ; 16set_bit(PORTF,0); // Turn on internal pullups for PF0ca:   88 9a           sbi 0x11, 0 ; 17toggle_bit(PORTD,5);}else{// If PF0 is LOW, toggle pin PD6's output statustoggle_bit(PORTD,6);cc:   50 e4           ldi r21, 0x40   ; 64// PINF is the register you have to read to check if a particular// pin on port F (PFx) is HIGH or LOWif(check_bit(PINF,0)){// If PF0 is HIGH, toggle pin PD5's output statustoggle_bit(PORTD,5);ce:   40 e2           ldi r20, 0x20   ; 32milliseconds can be achieved.*/
void
_delay_loop_2(uint16_t __count)
{__asm__ volatile (d0:   20 e9           ldi r18, 0x90   ; 144d2:   31 e0           ldi r19, 0x01   ; 1while(1){// PINF is the register you have to read to check if a particular// pin on port F (PFx) is HIGH or LOWif(check_bit(PINF,0))d4:   78 9b           sbis    0x0f, 0 ; 15d6:   03 c0           rjmp    .+6         ; 0xde <main+0x1a>{// If PF0 is HIGH, toggle pin PD5's output statustoggle_bit(PORTD,5);d8:   8b b1           in  r24, 0x0b   ; 11da:   84 27           eor r24, r20dc:   02 c0           rjmp    .+4         ; 0xe2 <main+0x1e>}else{// If PF0 is LOW, toggle pin PD6's output statustoggle_bit(PORTD,6);de:   8b b1           in  r24, 0x0b   ; 11e0:   85 27           eor r24, r21e2:   8b b9           out 0x0b, r24   ; 11e4:   80 e1           ldi r24, 0x10   ; 16e6:   97 e2           ldi r25, 0x27   ; 39e8:   f9 01           movw    r30, r18ea:   31 97           sbiw    r30, 0x01   ; 1ec:   f1 f7           brne    .-4         ; 0xea <main+0x26>__ticks = (uint16_t) (__ms * 10.0);while(__ticks){// wait 1/10 ms_delay_loop_2(((F_CPU) / 4e3) / 10);__ticks --;ee:   01 97           sbiw    r24, 0x01   ; 1__ticks = 1;else if (__tmp > 65535){//  __ticks = requested delay in 1/10 ms__ticks = (uint16_t) (__ms * 10.0);while(__ticks)f0:   89 f3           breq    .-30        ; 0xd4 <main+0x10>f2:   fa cf           rjmp    .-12        ; 0xe8 <main+0x24>000000f4 <_exit>:f4:   f8 94           cli000000f6 <__stop_program>:f6:   ff cf           rjmp    .-2         ; 0xf6 <__stop_program>

看一下main.map
重点看:C:\WinAVR-20100110\avr\lib\avr5\crtm32u4.o
这个是单片机跳转到main函数之前的启动代码

部分内容如下:

Archive member included because of file (symbol)c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_exit.o)c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5/crtm32u4.o (exit)Memory ConfigurationName             Origin             Length             Attributes
text             0x00000000         0x00020000         xr
data             0x00800060         0x0000ffa0         rw !x
eeprom           0x00810000         0x00010000         rw !x
fuse             0x00820000         0x00000400         rw !x
lock             0x00830000         0x00000400         rw !x
signature        0x00840000         0x00000400         rw !x
*default*        0x00000000         0xffffffffLinker script and memory mapAddress of section .data set to 0x800100
LOAD c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5/crtm32u4.o
LOAD obj/main.o
LOAD c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libm.a
LOAD c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a
LOAD c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a
LOAD c:/winavr-20100110/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a



重点看: 跳转到main之前做的工作

000000ac <__ctors_end>:ac:   11 24           eor r1, r1ae:   1f be           out 0x3f, r1    ; 63b0:   cf ef           ldi r28, 0xFF   ; 255b2:   da e0           ldi r29, 0x0A   ; 10b4:   de bf           out 0x3e, r29   ; 62b6:   cd bf           out 0x3d, r28   ; 61b8:   0e 94 62 00     call    0xc4    ; 0xc4 <main>bc:   0c 94 7a 00     jmp 0xf4    ; 0xf4 <_exit>

异或运算(相同为0,不同为1)
SREG 设置为0
SPH设置为 0x0a
SPL设置为0xFF

别的都没有设置。

atmega32u4 avr-gcc (WinAVR 2010) 编译 启动代码 crtm32u4.o相关推荐

  1. 全志 android 编译,全志A20启动代码流程分析 ——Android

    现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...

  2. 全志android 编译,全志A20启动代码流程分析 ——Android

    现在的CPU都固化了内部 ROM,内部 ROM中有一般都有一段程序,一般有如下几个功能: 1,初始化,部分外设,如USB,SDCARD 2,初始化DDR(内存)和NandFlash 3,加载boot( ...

  3. 如何用gcc编译C代码

    如何用gcc编译C代码 1.编写 hello word 的两种方法--现成编译器 这个方法大家都经常用,比如DEVCpp,Visual Studio 2017,Visual C++ 6.0等. 简单的 ...

  4. GCC : 什么是编译?什么是静态库?什么是动态库?怎么生成?优先级?

    本文旨在让大家真正明白C程序如何运行.库文件的种类区别.如何生成.如何使用等! 一.简介: gcc 最初是 "GNU C Compiler" 的简称,只是当作一个 C 语言的编译器 ...

  5. 嵌入式开发板03---看门狗、编写启动代码

    看门狗 一般CPU的设计在CPU启动后看门狗默认是工作的,在S5pV210内部的iROM代码(BL0)中,其实已经关过看门狗了.很多CPU内部是没有BL0的因此都要在启动代码的前段自己写代码关闭看门狗 ...

  6. gcc -c -o编译过程

    gcc编译 分步处理 一.预处理 二.编译 三.汇编 四.链接 一步到位 多模块编译 一次性编译: 独立编译: C源文件到可执行文件共经历了4个过程.在使用GCC编译程序时,编译过程可以被细分为四个阶 ...

  7. 编译器:GNU工具链GCC编译器的编译方法和编译步骤

    https://www.runoob.com/w3cnote/working-process-of-the-compiler.html https://www.runoob.com/w3cnote/g ...

  8. TQQ2440第一节:启动代码

    由于网上和我自己用的开发板有气度代码,所以我打算先把ARM9的外围熟悉了在回来看看启动代码,我也大约的看了一下和ARM7的差不多.只是从NANDFLASH启动多了拷贝代码,和MMU初始化的代码,在这里 ...

  9. 嵌入式Linux作业二分析u-boot-1.1.6在smdk2410开发板上的启动代码

    嵌入式Linux实验 嵌入式Linux作业二 文章目录 嵌入式Linux实验 作业要求 一.作业分析 二.实验步骤 1.下载并解压uboot1.1.6源码 2. 分析该版本下开发板smdk2410的相 ...

最新文章

  1. 解决 /var/run/nginx.pid failed
  2. js 连接mysql_关于Node.js 链接mysql超时处理(默认8小时)
  3. 《Web项目实践》实验报告——Web项目实践基础
  4. SAP Cloud for Customer里Lead和LeanLead两个相似的BO
  5. ObjectStreamClass:监视Java对象的序列化
  6. C#3.0新特性 和 Javascript
  7. AVR 矩阵键盘程序源代码2(有连续按键功能)(原创)
  8. matlab2c使用c++实现matlab函数系列教程-polyder函数
  9. 央行DECP开测,拉开全球货币霸权之战大幕 | 凌云时刻
  10. 深度学习在58同城首页推荐中的应用
  11. java 二叉树运用场景_java二叉树有什么作用?有哪些实际应用?
  12. bat脚本重启tomcat
  13. 【Python】操作Excel之分类汇总
  14. xp 无法关闭计算机,xp系统不能关机了怎么办
  15. android studio 报错Permission is only granted to system apps
  16. 适合运动健身的蓝牙耳机推荐,六款适合运动健身的蓝牙耳机
  17. AirDisk存宝Q2 网盘转接器 移动硬盘伴侣NAS私有云
  18. FastReport不打印空白行
  19. 工业机器人编程调试怎么学
  20. 学习jQuery框架获取数据的几种基础方式

热门文章

  1. php调用父类构造,php调用父类构造方法是什么
  2. 液压传动,PLC控制,透明液压元件,实验实训教学
  3. 在不root手机的情况下读取Data目录下的文件
  4. 技术与经济之八:关于优惠与红包
  5. 算法基础课 acwing
  6. arcgis栅格按掩膜提取后unique value变多
  7. 黑马程序员,黑马论坛----'Android26期,毕业67天,就业率98.57%,平均薪水8622元!
  8. java鸭子类型_Golang中的接口与鸭子类型
  9. mysql workbench改密码_在MySQL Workbench8.0中,忘记MySQL root密码的情况下修改密码
  10. iphone6s计算机驱动,iphone6s连接电脑出现驱动问题怎么办