版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1.1单片机与STM32
欢迎加入“学银在线课程”《C语言及单片机控制技术》(徐亮老师主持),可使用“学习通”APP扫描下面二维码加入课程,或者百度搜索“学银在线”进入官网后搜索课程名称进入课程主页并加入课程。
本课程即将登陆“智慧职教”平台,敬请期待……知识目标:
了解单片机的发展史及其主要应用领域、STM32的由来以及产品线简介。1.1.1什么是单片机单片机是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU、随机存储器RAM、只读存储器ROM、多种I/O口和中断系统、定时器/计数器等功能(可能还包括显示驱动电路、脉宽调制电路、模拟多路转换器、A/D转换器等电路)集成到一块硅片上构成的一个小而完善的微型计算机系统。1.1.2单片机发展史单片机诞生于20世纪70年代末,经历了SCM、MCU、SoC三大阶段。
1、SCM即单片微型计算机(SingleChipMicrocomputer)阶段,这一阶段单片机的主要特点是追求如何将计算机体系单片化,即将计算机的CPU、RAM、ROM、总线等部件集成在一片芯片上,便于嵌入到设备之中。这一阶段的代表产品有Intel公司的MCS-48单片机。
2、MCU即微控制器(MicroControllerUnit)阶段,由于在实际项目中,单片机往往需要与各种外设芯片协同工作才能完成特定的控制功能,为了进一步简化单片机应用电路的设计,单片机芯片上集成了越来越多的外设,称为“片内外设”。这一阶段单片机的特点就是单片机集成的片内外设越来越多,单片机控制板卡的独立外设芯片越来越少。在发展MCU方面,早期最著名的厂家当数Philips公司,本文介绍的STM32系列单片机也是MCU大家庭中的一员。
3、SoC单片机(SystemOnChip),与MCU相比,SoC单片机可以看做是一种专用型单片机。比如国产的乐鑫ESP8266单片机,内核是一个32位的精简指令集处理器,自带一个WIFI模块;再比如高通的骁龙处理器,CPU只占整个芯片面积的15%,其余被GPU(GraphicsProcessingUnit,图像处理器)、DSP(DigitalSignalProcessing,数字处理)单元、基带/射频前端、Modem(调制解调器)等模块占据。1.1.3STM32的诞生与发展
STM32系列单片机是来自欧洲的意法半导体公司(STMicroelectronics,简称ST)旗下众多半导体产品之一。2007年6月11日,STM32单片机诞生于北京,同年STM32单片机在全球通用MCU市场排第11名,此后一路高歌猛进,2015年上升到第3名,2018年继续上升到第2名,2021年登顶第1名。
与传统单片机不同,STM32的内核并非由ST自主研发,而是采用了英国ARM公司授权的Cortex-M内核,围绕内核增加了外设并进行封装。除了STM32之外,目前市面上还有恩智浦(NXP)、新唐(Nuvoton)等知名半导体公司推出了属于自己的基于Cortex-M内核的单片机。1.1.4STM32丰富的产品线
截止2023年9月,STM32单片机提供4大类16个系列共计1291个型号,并且还在持续更新中。
STM32产品广泛应用于工业控制、消费电子、物联网、通讯设备、医疗服务、安防监控等应用领域,其优异的性能进一步推动了生活和产业智能化的发展。Tobecontinued...1.2STM32的引脚与封装知识目标:
了解STM32的引脚结构,掌握简单的单片机最小系统的设计。1.2.1引脚结构本课程选择的STM32的型号是STM32F103R6,该型号芯片基于ARMCortex-M3内核,其主要特性为:⑴电源电压直流2.0~3.6V;⑵封装LQFP64(10×10mm);⑶输入/输出引脚数51个;⑷程序存储器(FlashMemory)32KB,静态随机存储器(SRAM)6KB;⑸最高主频72MHz;⑹片内外设有ADC、DMA、PWM、RTC、Timers;⑺通信接口有I2C、SPI、USART、CAN、USB2.0;⑻工作温度-40~+85℃。⑼工业级芯片。a.引脚分布图b.芯片实物图芯片引脚的主要功能有:⑴电源引脚:VDD_x、VSS_x(x=1~4)、VDDA、VSSA、VBAT(电池正极);⑵时钟源输入输出引脚:OSC_IN、OSC_OUT、OSC32_IN、OSC32_OUT;⑶复位引脚NRST;⑷输入输出引脚PAx、PBx、PCx、PDx(x=0~15),共计51个引脚;⑸大部分引脚具备多重功能,比如PA9、PA10分别为串口1(USART1)的数据发送引脚与数据接收引脚。具体后续章节将会介绍。1.2.2最小系统
所谓单片机最小系统,即单片机运行所需最少的外部条件:⑴
电源●VDD_1、~VDD_4数字量电源正极,内部连通,VSS_1~VSS_4数字量电源负极,内部连通;●VDDA、VSSA,模拟量电源正负极,若不用ADC、DAC,或对精度要求不高时可以直接与数字量电源正负极相连;●VBAT作为电池正极输入端,一般用于RTC供电,若不用RTC则直接与数字量电源正极相连。通常给定电源电压为3.3V。⑵复位电路STM32的复位方式有系统复位、上电复位、备份区域复位三种,其中系统复位又分为外部复位、WWDG(窗口看门狗)复位、IWDG(独立看门狗)复位、软件复位、低功耗管理复位五种情况,这里仅介绍其中的外部复位。
外部复位电路的典型电路如下图所示,当系统上电或在运行过程中按下图中按钮时,STM32可按BOOT模式的设定进行复位,关于BOOT模式的具体内容将在1.3节中介绍。⑶时钟电路STM32的时钟源输入引脚一共有四个,可划分为两组:●OSC_IN和OSC_OUT引脚用于连接外部高速晶振(4~16MHz,典型值8MHz);●OSC32_IN、OSC32_OUT引脚用于连接外部低速晶振(32.768kHz),如果不用RTC就不用接。无论高速晶振还是低速晶振,当设计方案对时钟源精度要求不高时,都可以选择内部RC振荡器来代替外部晶振。内部高速RC振荡器频率为8MHz,内部低速RC振荡器频率为40kHz。专业术语:HSI——内部高速时钟HSE——外部高速时钟LSI——内部低速时钟LSE——外部低速时钟几种晶振外部高速晶振与外部低速晶振的电路分别如下两图所示。单片机最小系统典型电路如下图所示,当然可根据实际需要对电路进行修改。Tobecontinued...1.3STM32的内部构造知识目标:
了解与程序开发相关的部分单片机内部构造,主要包括存储结构、启动模式与时钟树三部分。1.3.1Cortex-M3的存储结构
Cortex-M3的存储器(包括FlashROM、SRAM等)采用统一编址方式,寻址空间为4GB(32位寻址,,0x00000000~0xFFFFFFFF)。4GB寻址空间被分为8个主块(Block0~Block7),每块512MB。
FlashROM(用于存放程序)位于Block0中,地址范围0x08000000~0x0801FFFF,STM32F103R6地址范围0x08000000~0x08007FFF(共计32KB);SRAM(用于存放程序运行中产生的临时数据)位于Block1中,起始地址0x20000000,STM32F103R6地址范围0x20000000~0x200017FF(共计6KB);Peripherals(片上外设映射地址)位于Block2中,起始地址0x40000000。
由于STM32使用C语言开发程序,因此程序与数据的存储地址完全由编译器自动分配,无需人为干预。定义变量,比如:
inta=12;
编译器为变量a自动分配一个4字节的SRAM空间并赋予初值12。定义常量,比如:
constintb=23;
当变量b为常量时,编译器为变量b自动分配一个4字节的ROM空间并赋予初值23。1.3.2STM32的启动(BOOT)模式STM32F103系列单片机具有三种启动方式,如下表所示,分别为从MainFlashmemory(主闪存)启动、从Systemmemory(系统存储器)启动和从EmbeddedSRAM(内置静态随机存储器)启动。
其中尤以前两种启动方式最为常见:①从主闪存启动即正常运行用户编写的程序,②从系统存储器启动即进入ST公司预置的BootLoader(启动加载程序),一般用于从串口1下载用户程序(具体将在1.4部分介绍)。对于STM32F103R6而言,BOOT0引脚即60号引脚,BOOT1引脚即28号引脚(PB2)。1.3.3时钟树STM32片内外设较多,为了实现低功耗设计,允许用户对各种外设的时钟信号进行配置,由此构成了如右图所示的时钟树。
STM32内部采用了PLL(Phase-LockedLoop,锁相环)技术,可以将总线频率最高倍频至72MHz。Tobecontinued...1.4STM32的程序开发方式知识目标:
了解STM32的程序开发流程,了解与STM32程序开发相关的软件与硬件知识。1.4.1STM32程序开发流程概述利用STM32CubeIDE的图形化配置工具生成工程目录与初始化代码利用STM32CubeIDE的代码编辑工具编写程序并生成HEX文件利用FlashLoaderDemonstrator将程序下载至单片机FlashROM利用Proteus仿真模拟硬件实物调试软件仿真模拟1.4.2STM32CubeIDE简介STM32CubeIDE是ST官方在2019年推出的STM32专用IDE。
STM32CubeIDE由原先两个工具软件整合而成:一个是ST公司在2016年推出的图形化配置工具STM32CubeMX,;另一个是ST公司在2017年从Atollic收购的ARM编程工具TrueSTUDIO,其主要功能是用于编写STM32程序代码。1.4.3硬件实物调试简介STM32可以通过ISP、ST-LINK、J-LINK三种途径下载程序,本课程主要介绍第一种程序下载方式——ISP方式。该方式需要用到ST免费提供的FlashLoaderDemonstrator工具,并且需要在IDE中设定生成HEX文件(默认不生成HEX文件)。1.4.4软件仿真模拟简介STM32电路仿真软件采用了来自英国Labcenter公司出品的EDA工具Proteus,2016年末Proteus8.6中开始增加对STM32的支持,推荐使用Proteus8.15及以上版本。Tobecontinued...2.1C语言入门与顺序结构能力目标:
理解并掌握C语言基本数据类型,以及算术运算符、逗号运算符、赋值运算符三类运算符的使用,能使用Dev-C++编写简单的顺序结构程序。任务要求:根据随机输入的半径r,计算得到相应的圆周长、圆面积、球面面积、球体积。2.1.1计算机语言与C语言(1)计算机语言概述●机器语言机器码是唯一能被计算机CPU直接识别的代码,它由二进制编码按一定规律构成。但由于不同的CPU集成的指令集不尽相同,因此即便是完成相同的功能,机器码的编写方式也不一样。●汇编语言本质上汇编语言与机器语言没有区别,只是将晦涩难懂的二进制编码用英文助记符来代替,方便人们编写代码。汇编代码与机器代码逐条对应,工作量基本相同。●高级语言如果说机器语言、汇编语言是完全站在计算机CPU的角度考虑问题,那么高级语言就是偏向于站在人类的角度考虑问题了。高级语言通过字母、符号、数字的组合,以一种简单、优雅的方式书写代码,程序更紧凑,结构更清晰,可以有效的提高人们的工作效率。(2)C语言的产生与发展
●1972年,美国贝尔实验室的DennisM.Ritchie在B语言的基础上设计出了一种全新的计算机语言,这就是C语言。
●1978年,DennisM.Ritchie与BrianW.Kernighan合著了著名的《TheCProgrammingLanguage》,但此书并没有给出一个完整的C语言的标准。C语言之父——DennisM.Ritchie(1941年9月9日-2011年10月12日)
●1983年,美国国家标准化协会(AmericanNationalStandardsInstitute,简称ANSI)在《TheCProgrammingLanguage》的基础上制定了第一个C语言标准,并于1989年正式发布,称为“C89”标准,这也是后来人们熟知的“ANSIC”标准。
●后来,国际标准化组织(InternationalOrganizationforStandardization,简称为ISO)接纳了“C89”标准,并在此基础上不断修改,陆续推出了“C90”、“C99”、“C11”标准,这些也被人们称为“ISOC”标准。(3)C语言的标识符与关键字标识符是构成C语言代码的重要元素之一,标识符由英文字母、数字和下划线组成,而且开头只能是字母或者下划线,比如:a、Ab、Ba1、_1a,都是合法的标识符。值得注意的是,C语言区分大小写字母。ANSIC保留了32个标识符作为C语言的关键字,不能重做其他定义。(表见下一页)关键字功能关键字功能auto声明自动变量short声明短整型变量或函数int声明整型变量或函数long声明长整型变量或函数float声明浮点型变量或函数double声明双精度变量或函数char声明字符型变量或函数struct声明结构体变量或函数union声明共用数据类型enum声明枚举类型typedef用以给数据类型取别名const声明只读变量unsigned声明无符号类型变量或函数signed声明有符号类型变量或函数extern声明变量是在其他文件正声明register声明寄存器变量static声明静态变量volatile说明变量在程序执行中可被隐含地改变关键字功能关键字功能void声明函数无返回值或无参数,声明无类型指针if条件语句else条件语句否定分支(与if连用)switch用于开关语句case开关语句分支for一种循环语句do循环语句的循环体while循环语句的循环条件goto无条件跳转语句continue结束当前循环,开始下一轮循环break跳出当前循环default开关语句中的“其他”分支sizeof计算数据类型长度return子程序返回语句(可以带参数,也可不带参数)循环条件2.1.2使用Dev-C++编写计算机C程序Dev-C++是一种免费的C/C++集成开发环境(IntegratedDevelopmentEnvironment,简称IDE),适合用来学习C/C++语言。在计算机桌面上找到Dev-C++的图标并双击运行。选择菜单栏“文件”→“新建”→“项目”新建项目。进入所示编程界面。
编写程序并按下“编译运行”按钮,弹出运行窗口。2.1.3C语言的基本数据类型
本次课仅学习其中的基本数据类型:整型、浮点型、字符类型(1)整型
其中,int是一般整型,short是短整型,long是长整型,unsigned表示无符号,即类似于数学的正整数。
实际上,int型数据长度不定,与编译器有很大关系,有可能长度为2个字节,也有可能长度为4个字节。类别数据类型字节长度取值范围一般整型int2-3,2768~3,2767短整型short2-3,2768~3,2767长整型long4-21,4748,3648~21,4748,3647无符号一般整型unsignedint20~6,5535无符号短整型unsignedshort20~6,5535无符号长整型unsignedlong40~42,9496,7295
C语言是强类型语言,所有变量必须先定义再使用。变量的定义格式:类型说明符变量名;变量的赋值格式:变量名=常量、变量或表达式;整型变量的定义与赋值:
这里的“=”不同于数学上等号的意义,属于C语言的赋值运算符,表示将“=”右边的常量、变量或表达式的值赋给左边的变量。inta,b,c;a=12,b=014,c=0xC;
可以一次只定义一个变量,也可以一次定义多个变量,多个变量之间用逗号运算符“,”隔开。变量也可以在定义的同时进行初始化:以上,三个变量a、b、c实际上赋值的内容是一样的,只是分别采用十进制、八进制、十六进制进行了赋值,八进制前缀“0”,十六进制前缀“0x”或者“0X”,如果十六进制数据中出现了字母,大小写皆可。inta=12,b=014,c=0xC;(2)浮点型
浮点型类似于数学的实数类型,有float、double两种,float是一般浮点型,double是双精度浮点型。浮点型变量的定义与赋值:以上,变量a、b分别采用了十进制小数形式、指数形式进行了赋值,其中指数形式“4.56e1”即为4.56×101的意思,这里“e”也可以写成“E”。类别数据类型字节长度取值范围有效位单精度浮点型float4±1.0e-37~±1.0e+387双精度浮点型double8±1.0e-307~±1.0e+30816floata,b;a=12.3,b=4.56e1;(3)字符型字符型变量一般用来存放字符对应的ASCII码,比如:以上,变量a、b实际上赋值的内容是一样的,变量a赋予字符7,变量b赋予字符7对应的ASCII码。实际使用的时候,字符型变量往往也用来存放整数数据。类别数据类型字节长度取值范围字符型char1-128~127无符号字符型unsignedchar10~255chara,b;a=’7’,b=55;ASCII码表(引自百度百科)2.1.4格式输入/输出函数格式输入函数用于从输入设备(比如键盘)向计算机输入数据,格式输出函数用于计算机向输出设备(比如显示器)输出数据。格式输入/输出函数是由C标准库函数提供,在使用它们的时候,必须使用预处理命令中的“包含”命令将标准输入/输出头文件“stdio.h”包含到当前项目中来。#include<stdio.h>main(){……}……值得注意的是,预处理命令不是C语言语句。以包含命令为例,简单的说就是在编译器编译之前,将头文件中的内容替换该包含命令,再进行编译。
(1)格式输出函数——printf()格式输出函数的一般形式是:printf(“格式控制字符串”,输出列表);
括号内内容由两部分构成:
①格式控制字符串作用是指定输出格式,它又由三部分构成:●显示字符串,按原样输出。●格式化占位符,用于按照指定格式将数据输出,由“%”和特定的字符组成,常用格式化占位符如表所示(后页),输出时自动按指定格式显示变量或表达式的值。●转义字符,在输出时会被自动转换为对应的操作命令,常用的转移字符如表所示(后页)。
●格式占位符:占位符作用占位符作用%d以十进制整数形式输出%s输出字符串%x或%X以十六进制整数形式输出%f以小数形式输出实数%c输出单个字符%e或%E以指数形式输出实数转义字符作用转义字符作用\n换行符,将当前位置移到下一行开头\\输出一个反斜杠“\”\r回车符,将当前位置移到本行开头\’输出一个单引号“’”\t水平制表符\”输出一个双引号“””\v垂直制表符\0空字符,也是字符串结束标志
●转义字符:
②输出列表输出变量或表达式的列表,用逗号运算符“,”隔开,输出列表中变量或表达式的个数必须与格式控制字符串的个数一一对应。例如:运行结果:chara=’7’;printf("字符%c的ASCII码是%d\n",a,a);(2)格式输入函数——scanf()格式输入函数的一般形式是:scanf(“格式控制字符串”,地址列表);变量的地址是由取地址运算符“&”后跟变量名构成,比如“&a”表示变量a在计算机内存中的地址。
比如:运行结果:inta,b,c;scanf("%d%d%d",&a,&b,&c);printf("变量a,b,c的值分别是:%d,%d,%d\n",a,b,c);2.1.5C语言的运算符(一)
(1)算术运算符首先演示整数的运算:运算符功能应用举例+加法运算符x+y-减法运算符x-y*乘法运算符x*y/除法运算符x/y%取模(求余数)运算符x%y++自增运算符x++或者++x--自减运算符x--或者--xinta=13,b=3;printf("和:%d差:%d积:%d商:%d余数:%d\n",a+b,a-b,a*b,a/b,a%b);格式结果:值得注意的是,13/3的结果是整除的结果4,只有整数才能做整除与取模运算。C语言中,四则运算同样遵循“先乘除后加减”的原则,如果需要改变运算次序,可以用小括号“()”来提升运算优先等级,比如:floata=1,b=2,c=3,d=4,r;r=(a+b)/c+d;自增/减运算符属于单目运算符,符号与变量的位置不同,程序运行的效果也截然不同。接着演示自增运算符的使用方法:运行结果:总结:若++/--运算符在前是先自增/减再执行语句,若++/--运算符在后则是先执行语句再自增/减。inta=1,b=1;printf("a的值是%d,b的值是%d\n",++a,b++);printf("a的值是%d,b的值是%d\n",a,b);
(2)赋值运算符演示程序:运行结果:运算符功能举例运算符功能举例=赋值a=b;&=位与赋值a&=b等价于a=a&b+=加赋值a+=b等价于a=a+b^=位异或赋值a^=b等价于a=a^b-=减赋值a-=b等价于a=a-b|=位或赋值a|=b等价于a=a|b*=乘赋值a*=b等价于a=a*b<<=左移赋值a<<=n等价于a=a<<n/=除赋值a/=b等价于a=a/b>>=右移赋值a>>=n等价于a=a>>n%=取模赋值a%=b等价于a=a%b
inta=11,b=13,c=15,d=17,e=19;a+=1;b-=2;c*=3;d/=4;e%=5;printf("a:%d,b:%d,c:%d,d:%d,e:%d\n",a,b,c,d,e);
(3)逗号运算符逗号运算构成的表达式一般形式是:
表达式1,表达式2,表达式3,…,表达式n以上表达式的功能是,从左往右依次求出每个表达式的值,表达式n的值即为整个逗号表达式的值。演示程序:运行结果:inta=2,b;b=(a++,a+3);printf("b:%d\n",b);2.1.6任务程序的编写
(现场操作演示...)
圆周长:圆面积:球面面积:球体积:Tobecontinued...2.2C语言分支结构能力目标:
理解、区分并掌握C语言的逻辑运算符与位运算符,理解并掌握C语言的比较运算符,能利用if语句与switch语句实现分支结构程序。任务要求:
任务A:输入年份,判断该年份是否为闰年。
任务B:某商场举办优惠购物活动,购物满5000元打8折,购物满2000元,不满5000元打8.5折,购物满1000元,不满2000元打9折,其余不打折,输入购物金额数,自动计算折后价。2.2.1C语言的运算符(二)(1)逻辑运算符在逻辑关系中,用整型或字符型数字“0”代表“假”,用非零值代表“真”,但逻辑表达式的计算结果只有“0”或者“1”。演示程序://逻辑与运算printf("And:%d,%d,%d,%d\n",0&&0,0&&1,2&&0,3&&4);//逻辑或运算printf("Or:%d,%d,%d,%d\n",0||0,0||1,2||0,3||4);//逻辑非运算printf("Not:%d,%d\n",!0,!1);运算符功能表达式&&逻辑与a&&b||逻辑或a||b!逻辑非!a
运行结果:(2)位运算符运算符功能举例运算符功能举例&按位与a&b^按位异或a^b|按位或a|b<<左移a<<n~按位取反~a>>右移a>>n首先演示按位与、按位或、按位取反、按位异或运算符的使用:运行结果:下面是四个表达式的手工验算过程:01000010B=42H,11111011B=FBH,10000101B=85H,10111001B=B9Hunsignedchara=0x7A,b=0xC3;printf("%x,%x,%x,%x\n",a&b,a|b,(unsignedchar)(~a),a^b);接着演示左移运算符:运行结果:
下面是手工验算过程:55H=01010101Bunsignedchardat=0x55;dat=dat<<1;printf("左移一位:%x\n",dat);dat=dat<<3;printf("继续左移三位:%x\n",dat);C语言的左移运算表达式在移动数据位的过程中左侧移出位丢弃,右侧补010101010B=AAH,01010000B=50H
右移运算与左移运算类似,不做演示。
(3)关系运算符关系运算符用来表达数值的大小,关系成立则运算结果为“真”(1),否则为“假”(0)。演示程序:运行结果:chara,b;a=(3>=2),b=(3==2);printf("%d,%d\n",a,b);运算符符号实例读作大于>小于等于<=大于等于>=等于==小于<不等于!=
(4)运算优先级
*C语言中的运算优先级一共分为16级,数字越小,优先级就越高。优先级运算符结合方向优先级运算符结合方向1后缀运算符:[]().->++(后置)--(后置)从左往右2一元运算符:++(前置)--(前置)!~+-*(指针)&从右往左3类型转换运算符:()从右往左4乘除法运算符:*/%从左往右5加减法运算符:+-从左往右6移位运算符:<<>>从左往右7关系运算符:>>=<<=从左往右8关系运算符:==!=从左往右9位运算符:&从左往右10位运算符:^从左往右11位运算符:|从左往右12逻辑运算符:&&从左往右13逻辑运算符:||从左往右14条件三目运算符:?:从右往左15赋值运算符:=+=-=*=/=%=&=^=|=<<=>>=从右往左16逗号运算符:,从左往右2.2.2分支语句(1)if语句if分支语句的通用格式为:if语句的流程图:
if(条件表达式1)分支语句1;elseif(条件表达式2)分支语句2;elseif(条件表达式3)分支语句3;……elseif(条件表达式n)分支语句n;else分支语句n+1;例如,随机输入数字0~9,输出与其对应的英文翻译:charnum;printf("输入数字0~9:");scanf("%d",&num);If(num==0)printf("Zero\n");elseif(num==1)printf("One\n");elseif(num==2)printf("Two\n");elseif(num==3)printf("Three\n");elseif(num==4)printf("Four\n");elseif(num==5)printf("Five\n");elseif(num==6)printf("Six\n");elseif(num==7)printf("Seven\n");elseif(num==8)printf("Eight\n");elseif(num==9)printf("Nine\n");elseprintf("输入数字超限!\n");
运行结果:C语言有一条“条件三目运算符(?:)”可以替代“if...else...”结构语句,比如判断随机输入整数是否为正数:可以用条件三目运算符替代:intnum;printf("请输入一个整数:");scanf("%d",&num);if(num>0)printf("输入的数字是正数:-)\n");elseprintf("输入的数字不是正数:-(\n");intnum;printf("请输入一个整数:");scanf("%d",&num);num>0?printf("输入的数字是正数:-)\n"):printf("输入的数字不是正数:-(\n");(2)switch开关语句switch开关语句的通用格式为:switch语句的流程图:switch(表达式){case常量表达式1:语句1;break;case常量表达式2:语句2;break;……case常量表达式n:语句n;break;default:语句n+1;}例如,随机输入数字0~9,输出与其对应的英文翻译:charnum;printf("输入数字0~9:");scanf("%d",&num);switch(num){case0:printf("Zero\n");break;case1:printf("One\n");break;case2:printf("Two\n");break;case3:printf("Three\n");break;case4:printf("Four\n");break;case5:printf("Five\n");break;case6:printf("Six\n");break;case7:printf("Seven\n");break;case8:printf("Eight\n");break;case9:printf("Nine\n");break;default:printf("输入数字超限!\n");}
运行结果:任务要求:
任务A:输入年份,判断该年份是否为闰年。
任务B:某商场举办优惠购物活动,购物满5000元打8折,购物满2000元,不满5000元打8.5折,购物满1000元,不满2000元打9折,其余不打折,输入购物金额数,自动计算折后价。2.2.3任务程序的编写任务A:闰年是公历中的概念,分为普通闰年和世纪闰年两种,所谓普通闰年指的是年份数是4的倍数但不是100的倍数的年份,比如2020年,所谓世纪闰年指的是年份数是400的倍数的年份,比如2000年。(现场操作演示...)任务B:(现场操作演示...)Tobecontinued...2.3C语言循环结构能力目标:
理解数组的概念,掌握一维数组的定义及使用方法,能利用while语句、do…while语句、for语句实现循环结构程序。任务要求:任务A:随机输入5个正整数,找出其中的最大值、最小值。任务B:随机输入2个正整数,求出它们的最大公约数、最小公倍数。2.3.1数组数组是同类型数据的有序集合(1)一维整型数组一维数组的定义:类型说明符数组名[整型常量表达式];其中,类型说明符就是组成数组的各个元素的数据类型,数组名类似于变量名,即用于表达数组的标识符,方括号中的整型常量表达式表示数组元素的个数,或者说数组的长度。一维数组定义之后即可使用其元素,元素格式为:数组名[下标]。
比如:注意:如果数组长度为N,则数组元素的下标取值范围为0~N-1inta[5];a[0]=12,a[1]=23,a[2]=34,a[3]=45,a[4]=56;数组在定义的时候也可以同时直接初始化初值,比如:一维数组在初始化的时候,甚至可以不必指定数组长度,编译器在编译的时候,能根据初始化元素的个数自动判断数组长度,比如:(2)一维浮点型数组浮点型数组的定义及使用与整型数组类似,可以先定义再赋值,比如:也可以定义的同时进行初始化初值,比如:inta[5]={12,23,34,45,56};inta[]={12,23,34,45,56};floata[5];a[0]=1.2,a[1]=2.3,a[2]=3.4,a[3]=4.5,a[4]=5.6;floata[5]={1.2,2.3,3.4,4.5,5.6};(3)一维字符型数组字符型数组的定义和使用除了与整型数组、浮点型数组类似之外,也有自己的特点。可以先定义再赋值,比如:以上程序定义了一个长度为6的字符型数组并赋值“Hello”字符串,注意最后一个字符“\0”是字符串结束标志。也可以定义的同时进行初始化初值,比如:
也可以在初始化的时候直接赋予字符串,比如:chara[6];a[0]=’H’,a[1]=’e’,a[2]=’l’,a[3]=’l’,a[4]=’o’,a[5]=’\0’;chara[6]={‘H’,’e’,’l’,’l’,’o’,’\0’};chara[6]=”Hello”;//尾部会自动添加“\0”2.3.2循环语句循环结构又称重复结构,可以完成重复性、规律性的操作,比如求若干数的和、迭代求根等等。(1)while语句通用格式:循环语句若由多条语句构成,必须以大括号“{”、“}”括起来构成复合语句。while(条件表达式)循环语句;例如,计算1+2+3+…+100=?运行结果:unsignedintsum=0,i=1;while(i<=100){ sum+=i; i++;}printf("1+2+3+...+100=%d\n",sum);(2)do…while语句
通用格式:同样,1+2+3+…+100=?运行结果:do循环语句while(条件表达式);unsignedintsum=0,i=1;do{ sum+=i; i++;}while(i<=100);printf("1+2+3+...+100=%d\n",sum);(3)for语句
通用格式:for语句的执行过程:for(表达式1;表达式2;表达式3)循环语句实际使用的时候,for语句的常用格式:同样,1+2+3+…+100=?运行结果:for(循环变量赋初值;循环条件;循环变量增/减值)循环语句unsignedintsum=0,i;for(i=1;i<=100;i++)sum+=i;printf("1+2+3+...+100=%d\n",sum);
(4)continue语句与break语句
●continue语句的作用是提前结束当次循环进行下一次循环。举例说明:运行结果:inti=1;while(i<10){ if(i==5) { i++; continue; } printf("第%d次循环\n",i); i++;}
●break语句的作用则是直接跳出循环
举例说明:运行结果:inti=1;while(i<10){ if(i==5) { i++; break; } printf("第%d次循环\n",i); i++;}2.3.3任务程序的编写
任务A:
以找出五个随机正整数中的最大值为例,先假定第一个数就是最大值,然后跟第二个数比较,若假定的最大值比第二个数小,则将第二个数替换为假定的最大值,否则什么也不做。以此类推,接着将假定的最大值与第三个、第四个、第五个数比较,最后假定最大值必然为五个数中真实的最大值。找出五个随机正整数中的最小值也是采用类似方法。(现场操作演示...)任务B:两个正整数的最大公约数未必存在,比如两个质数就不存在最大公约数,但最小公倍数是必然存在的,比如两个质数的乘积就是两者的最小公倍数。以求解两个随机正整数的最大公约数为例,先假定较小的数字就是两者的最大公约数,将两数同时除以假定最大公约数,若能整除则假定最大公约数就是两者实际的最大公约数,结束求解过程,若不能整除,则将假定最大公约数递减一次,再将两数同时除以假定最大公约数,依次类推,直到求得最大公约数。对于两个质数而言,依照此流程最后求得的结果是1,但显然1不能作为两个正整数的最大公约数。求解两个随机正整数的最小公倍数也是采用类似的方法,但假定的最小公倍数是较大的数字。(现场操作演示...)Tobecontinued...2.4模块化程序的设计能力目标:
简单了解结构体、指针的相关基础知识,重点理解并掌握C语言函数的概念及使用方法。任务要求:随机输入五个正整数,将五个数字按从小到大的顺序进行排列。2.4.1结构体认知
●数组是同种类型数据的组合。
●结构体是不同类型数据的组合。在STM32的HAL/LL库中大量使用了结构体,用于对片内外设的一组不同的参数进行设定,但这部分主要是一些自动生成代码,读者仅仅需要了解即可。结构体的使用可分为如下三步:构造结构体类型→定义结构体变量→结构体变量赋值。①首先是构造结构体类型的一般形式:struct结构体名{ 类型名1成员名1; 类型名2成员名2; …… 类型名3成员名3;};比如构造一个名为“Student”的结构体,用来记录学生的基本信息:②然后是定义结构体变量的一般形式:比如定义一个“Student”型的结构体变量“student1”:structStudent{ unsignedintNo;//学号 charName[10];//姓名 charSex;//性别};struct结构名
变量名列表;structStudentstudent1;③最后是使用这个结构体变量,包括赋值和读取它的值。可以在定义的同时进行初始化,比如:也可以在定义完成后进行赋值,比如:structStudentstudent1={325,"张三",'M'};structStudentstudent1;student1.No=325;strcpy(student1.Name,"张三");//字符串赋值函数,需要包含头文件“string.h”student1.Sex='M';2.4.2指针认知指针就是用于指向变量内存单元的变量,或者说在指针变量中存储了其指向变量的内存地址。
指针在STM32单片机程序的开发中,主要是调用HAL/LL库API函数时进行实参的地址引用,这里仅对①指针指向基本变量、②指针指向一维数组的使用方法进行扼要介绍,在2.4.3中也会简单介绍③指针变量作为函数参数的使用方法。(1)指针指向基本变量首先是指针变量的定义,定义格式为:类型说明符*变量名;这里,“*”表示这是一个指针变量,类型说明符指的是指针所指向变量的数据类型。比如:int*p;表示定义了一个指针变量p,他可以指向一个整型变量,但具体指向哪一个整型变量,需要对指针变量赋值,指针变量的赋值格式:变量1=&变量2;
这里,“&”是取地址运算符,表示获取变量2的地址,注意到这是一个单目运算符,与位运算符中的位与运算符“&”不是一个功能,比如:
也可以定义的同时直接做初始化:利用指针引用变量,比如:
在利用指针引用变量时,“*p”表示指针变量“p”指向变量的值。运行结果:inta,*p;p=&a;inta,*p=&a;inta=56,*p=&a;printf("%d",*p);(2)指针指向一维数组数组在计算机内存中的地址是连续的,一般我们可以将指针指向数组的第一个元素的地址,在遍历数组中每一个元素时,只需要将指针不断往后偏移即可。比如定义一个指针并指向整型一维数组的第一个元素:也可以:
即“&a[0]”和“a”都可以表示数组a的首地址。int*p,a[5]={12,23,34,45,56};p=&a[0];int*p,a[5]={12,23,34,45,56};p=a;利用指针遍历一维数组,比如:
这里的“*p++”,“++”优先级别比“*”高,等价于“*(p++)”。
运行结果:int*p,a[5]={12,23,34,45,56},i;p=a;for(i=0;i<5;i++){ printf("%d",*p++);}2.4.3函数与模块化程序设计C语言程序一般是由一个主函数(即main函数)加若干其他函数构成,主函数是整个程序执行的入口,不可或缺。将一段具有特定功能的代码封装成函数,既方便程序员在后续的开发中直接调用,也提高了代码的可维护性,可谓一举两得。由于每一个函数也是一个独立的功能模块,因此C语言也被称为模块化程序设计语言。函数的使用一般分三步进行:定义、声明、调用。定义的一般形式:函数类型函数名(形式参数表){函数体语句}第一行构成函数的首部,大括号中的内容构成函数的函数体。其中,形式参数简称“形参”,即函数的输入值,函数的形参可以有多个,也可以只有一个,甚至于没有形参;函数类型也叫函数的返回值类型,即函数的输出值类型,函数的返回值最多只能有一个,当函数没有返回值时,函数类型必须写上“void”。声明的一般形式:一般直接将函数的首部复制并粘贴到主函数之前,加上分号“;”即可。调用的一般形式:函数类型函数名(形式参数表);函数名(实际参数表);调用函数时,必须将形参全部替换为实际参数(简称“实参”)。函数的定义可以理解为是定义了一种运算关系,形参可以理解为自变量,返回值可以理解为因变量;函数的调用可以理解为将常量代入这种运算关系从而得出运算结果;函数的声明,这与编译器的编译顺序有关,比如定义的函数在主函数之后,而主函数调用了该函数,如果不提前声明,编译器会认为该函数不存在从而终止编译。
比如,圆面积的计算:#include<stdio.h>constfloatpi=3.141592;//“const关键字说明“pi”是一个常量main(){ floatr,s; printf("请输入半径:"); scanf("%f",&r); s=pi*r*r; printf("圆面积:%f\n",s);}将圆面积的计算公式封装成独立函数:#include<stdio.h>constfloatpi=3.141592;//“const”关键字说明“pi”是一个常量floatsquare(floatr);//函数的声明main(){ floatr,s; printf("请输入半径:"); scanf("%f",&r); s=square(r);//函数的调用 printf("圆面积:%f\n",s);}//函数的定义floatsquare(floatr){ returnpi*r*r;//由“return”语句返回运算结果}
圆面积计算函数中,形参只有半径“r”,返回值类型为浮点型,由于这不是一个void型函数,因此调用时可以将函数返回值赋值给变量“s”。
运行结果:
值得注意的是,在main函数和square函数中都有变量“r”,但这两个变量“r”没有任何关系,他们分属于两个不同函数的“局部变量”,其作用域仅限于各自所在的函数内部;变量“pi”定义的位置在所有函数之前,这属于“全局变量”,其作用域可达整个程序的任何位置,如果当全局变量与局部变量同名时,局部变量会在其作用域内自动屏蔽同名全局变量。接下来比较一下形参分别为变量和指针时的区别:#include<stdio.h>voidf1(inta);voidf2(int*p);main(){ inta=0; f1(a); printf("a=%d\n",a); f2(&a); printf("a=%d\n",a);}voidf1(inta){ a++;}voidf2(int*p){ (*p)++;}
运行结果:f1函数采用的是“值传递”的参数传递方式,函数执行完毕后,不会影响到原变量的值,而f2函数采用的是“地址传递”的参数传递方式,函数在执行过程中,直接改变了指针指向的变量值,所以函数执行完毕后,原变量的值自然发生了变化。2.4.4任务程序的编写显然,本次任务必须借助于数组,在定义排序函数的时候,可以利用指针指向数组的首地址,在调用排序函数之后,数组中的元素即完成从小到大的排序。排序策略为:先将数组第一个元素依次与后面的四个比较,在比较过程中,只要发现第一个元素比某一个元素大,就交换两个元素的位置,确保最小的元素排在数组的第一位,然后将数组的第二个元素与后面的三个比较……以此类推。
(现场操作演示...)Tobecontinued...3.1LED单灯闪烁之软件延时能力目标:
理解单片机GPIO两种主要的输出类型,初步掌握使用STM32CubeIDE开发单片机应用程序的方法,掌握通过ISP下载程序并通过实物验证的方法。任务要求:电路如图所示,要求通过单片机PC0引脚控制LED0以1秒周期闪烁。3.1.1STM32的GPIO及其输出类型STM32F103R6具有51个GPIO(General-purposeinput/output,通用输入输出)引脚,每个引脚都具备如图所示结构。GPIO的八种工作模式:
本次课着重讲其中的⑴⑵两种工作模式。⑴推挽输出⑵开漏输出⑶复用推挽输出⑷复用开漏输出⑸模拟量输入⑹浮空输入⑺下拉输入⑻上拉输入⑴推挽输出
此时P-MOS管与N-MOS管发挥作用:
①当控制输出1时,P-MOS管闭合、N-MOS管断开,引脚输出电源电压(+3.3V);
②当控制输出0时,P-MOS管断开、N-MOS管闭合,引脚输出GND。
推挽输出模式一般应用在输出电平为0和+3.3V而且需要高速切换开关状态的场合。在STM32的应用中,除了必须用开漏模式的场合,我们都习惯使用推挽输出模式。
值得注意的是,当引脚直接接地的时候,切不可推挽输出高电平,否则电源将被直接短路!⑵开漏输出此时P-MOS管始终断开,仅N-MOS管发挥作用:
①当控制输出1时,N-MOS管断开,引脚悬空;
②当控制输出0时,N-MOS管闭合,引脚输出GND。
开漏输出一般应用在①I2C、SMBUS通讯等需要“线与”功能的总线电路中。除此之外,②还用在电平不匹配的场合,如需要输出5伏的高电平,就可以在外部接一个上拉电阻,上拉电源为5V,并且把引脚设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5V电平,如右图所示。3.1.2STM32CubeIDE的使用STM32CubeMX的作用是通过图形化配置完成STM32的工程目录的建立与初始化代码的生成。下面是操作步骤。
(1)在桌面上找到并双击程序图标,打开程序主界面。
(2)点击菜单“File=>NewProject”新建工程,在搜索栏中输入单片机型号“STM32F103R6”,出现两种封装的搜索结果。
(3)在搜索结果中选择LQFP64封装,双击打开左图配置界面。
(4)在右图“Pinout&Configuration”界面上将引脚PC0修改为“GPIO_Output”模式。
(5)在左图“ProjectManager”界面上对工程命名,制定工程目录,指定集成开发环境为“TrueSTUDIO”后点击“DeviceConfigurationToolCodeGeneration”按钮
生成单片机程序工程目录。
本案例没有对时钟树进行设定,采用了默认的内部RC振荡源。
接下来就是继续完成程序代码的编写。
本次任务需要用到两个API函数(API函数来源于“UM1850_DescriptionofSTM32F1HALandLow-layerdrivers.PDF”文档):①引脚输出状态翻转函数HAL_GPIO_TogglePin
例程:HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//将PC0引脚输出状态取反②延时函数HAL_Delay
例程:下面是操作步骤。HAL_Delay(500);//延时500ms(即0.5s)
(1)在左侧“Src”目录中找到main.c文件,双击打开。(5)值得注意的是,由于STM32CubeIDE默认不生成HEX文件,需要人为设置:在IDE主界面菜单栏中选择“Project(工程)”→“Properties(属性)”打开如图3-12所示属性对话框,选择“C/C++Build(C/C++生成)”→“Settings(设置)”→“ToolSettings(工具设置)”→“MCUPostbuildoutputs(单片机编译后输出)”,在“ConverttoIntelHexfile(-Oihex)(转换为英特尔HEX文件)”项目打钩并保存,回到IDE主界面后再按下生成按钮,即可在源代码编译成功后输出HEX文件。3.1.3使用ISP方式下载程序
程序编写完毕,生成HEX文件以后,通过ISP工具下载到单片机电路运行验证。特别注意的是,接线的时候请断电。
步骤:
①将开发板上核心板的PC0引脚与LED模块LED0的引出端用杜邦线连接;②将开发板USB通信口与计算机USB口通过USB线连接;③接通电源;④将核心板拨动开关拨到“ISP”位置,按下“RST”复位按钮;⑤通过ISP工具“FlashLoaderDemonstrator”读取工程目录下“.../Debug/2.1.Hex”文档中的机器码,并将机器码下载至单片机Flash,操作步骤请见后页。
ISP工具桌面图标是。⑥程序下载完毕后,将核心板拨动开关拨回到“Run”位置,再次按下复位按钮“RST”,单片机将按照设定程序运行。具体的代码另外给出。技能训练(选做):
修改电路,改由PC1驱动LED1作单灯闪烁,闪烁周期改为2s。Tobecontinued...3.2按钮输入能力目标:
理解并掌握单片机GPIO三种主要的输入类型,掌握使用Proteus仿真单片机电路的方法。任务要求:电路如图所示,要求通过按钮BTN0控制LED0的亮灭(LED0接PC0,BTN0接PC1)。3.2.1GPIO的输入类型STM32F103R6具有51个GPIO(General-purposeinput/output,通用输入输出)引脚,每个引脚都具备如图所示结构。GPIO的八种工作模式:
本次课着重讲其中的⑺⑻两种工作模式。⑴推挽输出⑵开漏输出⑶复用推挽输出⑷复用开漏输出⑸模拟量输入⑹浮空输入⑺下拉输入⑻上拉输入⑴当图中上拉电阻、下拉电阻均未接入时输入模式为浮空输入,此时若输入信号断开,则引脚输入状态不定(不常用);
⑵当图中上拉电阻接入时输入模式为上拉输入,此时若输入信号断开,则引脚输入为高电平;(常用)
⑶当图中下拉电阻接入时输入模式为下拉输入,此时若输入信号断开,则引脚输入为低电平。(常用)
典型按钮电路如图:
左图引脚PC1配置为上拉输入时,若松开按钮,引脚默认输入高电平,若按下按钮,引脚输入低电平;右图引脚PC1配置为下拉输入时,若松开按钮,引脚默认输入低电平,若按下按钮,引脚输入高电平;
如果选择浮空输入模式,则按钮上拉或下拉电阻必须外接,比如本项目仿真电路。3.2.2电路仿真
电路仿真采用Proteus,操作步骤:
(1)在桌面上找到并双击程序图标,打开左图主界面,选择“NewProject”新建工程(如右图),过程中除了路径之外,其余均采用缺省设定。(2)拾取元件。左图中在左侧工具栏中按下(ComponentMode)按钮进入元器件拾取模块,接着按下右侧的(PickDevice)按钮打开中图元器件拾取对话框。在中图“Keywords”搜索栏内依次输入本次课题所需元器件名称,在右图“Results”结果栏内选中并双击所需元器件将其拾取到主界面元器件中,完成后关闭对话框。(3)放置元件并更改元器件参数。在主界面元件池中依次选择所需元件将其摆放到主界面中心图纸上。依次选中图纸上的元件,在鼠标右键弹出的快捷菜单内选择“EditProperties”打开右图所示编辑属性对话框,修改参数后点“OK”按钮保存退出。(4)电路连线。在左侧工具栏中按下(TerminalsMode)终端模式按钮,在终端列表中分别选择电源终端POWER、接地终端GROUND并添加到图纸中,完成电路连线。(5)设定电源正负极参数。在主界面中选择菜单栏“Design=>ConfigurePowerRails...”打开电源轨配置对话框如左图所示,需要设定的是:①将电源正极由5V改为3.3V;②将模拟量电源正负极VDDA与VSSA分别添加到VCC/VDD网络与GND网络,否则单片机将无法仿真,添加结果如中图与右图所示。(6)指定HEX文件路径。回到主界面,选择原理图中的单片机并在右键快捷菜单中选择“EditProperties”打开如图所示编辑属性对话框,在对话框中点击按钮,选择HEX文件并确认保存。(7)运行仿真。按下左下角运行按钮即可开始仿真。注意:Proteus8.8和8.9仿真模型中上拉模式不可用,必须外接上拉电阻。3.2.3任务程序的编写
本次内容需要用到的新的API函数是:
引脚输入函数HAL_GPIO_ReadPin
例程:
(现场操作演示...)GPIO_PinStatex=HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_1);//读取PC1输入状态技能训练(选做):通过两只按钮控制一个LED的亮灭,要求两个按钮一个采用上拉输入模式,另一个采用下拉输入模式。参考电路如下图所示。Tobecontinued...3.3流水灯之软件延时能力目标:理解并掌握通过改进算法提高编程效率的方法。任务要求:
电路如图所示,要求实现流水灯效果,即按LED0~LED7的顺序依次点亮,每次仅限一只LED发光,周期4秒。3.3.1程序算法
算法(Algorithm)是指解决方案准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。首先人们自然会想到“位操作法”,但这种算法编程效率太低,下面介绍两种比较好的算法:⑴查表法
即将8个状态,定义为8个字节,每隔一段时间,按先后顺序查表并将8个状态量赋值给单片机的规定输出口,状态表如下。序号状态字节(二进制)状态字节(十六进制)序号状态字节(二进制)状态字节(十六进制)11111,1110FE51110,1111EF21111,1101FD61101,1111DF31111,1011FB71011,1111BF41111,0111F780111,11117F⑵移位法所谓移位法,就是利用C语言的移位运算符“<<”、“>>”实现状态字节的循环移位。但由于C语言的移位运算符只能实现单向移位,因此必须通过一定的算法来间接实现,具体的做法是:假设M位数据A需要循环左移N位(M>N),先将A左移N位得到B,再将A右移(M-N)位得到C,最后将A、B按位求或运算即可获得最终结果。比如,8位二进制数,各位均用字母表示为“ABCDEFGH”,需要循环左移3位,可先将原数左移3位,得到“DEFGH000”,再将原数右移5位,得到“00000ABC”,最后将两数按位或即可得到循环左移3位的结果“DEFGHABC”,示意如下。①ABCDEFGH<<3→DEFGH000②ABCDEFGH>>5→00000ABC③DEFGH000|00000ABC
→DEFGHABC3.3.2任务程序的编写
本次任务程序将根据位操作法、查表法与移位法三种方法编写,需要用到的新的API函数:
①引脚输出函数HAL_GPIO_WritePin
新版HAL库改为:GPIO_PIN_RESETGPIO_PIN_SET
例程:今天我们要对若干个引脚一起输出相同的电平值,比如
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET);//PC0输出低电平HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_S
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 北海模拟考试数学试卷
- 2024年航空公司与机场间航空燃油代购合同
- 八年级期未数学试卷
- 平面四杆机构的运动仿真模型分析
- 2024版塑钢门窗购销合同范本
- 2024版夫妻离婚合同协议书
- 油气田开发定额计价施工合同
- 酒类仓储卫生管理规定
- 广东建筑工程劳务施工分包合同范文
- 多媒体使用培训
- 事故隐患报告和举报奖励制度
- 腹部外伤门诊病历
- 品质异常处理及要求培训
- 模具部年终总结--ppt课件
- 立式热虹吸再沸器机械设计说明书
- 国家开放大学电大《生产与运作管理》2025-2026期末试题及答案
- 质量保证大纲(共14页)
- 关于欧盟新版EMC标准EN55032的解析
- 木材材积表0.1-10米.xls
- 轻质隔墙板安装合同协议书范本标准版
- 车辆管理各岗位绩效考核量表
评论
0/150
提交评论