⑴ PIC单片机宏定义的用法,请教
pic单片机的端口方向是由相应的trisx寄存器决定的,其中x为a,b,c...
如果相应的trisx的位为0表示为输出,这个很容易记住,output的第一个字母o和数字0相象。
如果相应的trisx的位为1表示为输入,这个很容易记住,input的第一个字母i和数字1相象。
如:
trisb=0b11001010;
则表示rb7,rb6,rb3,rb1为输入,其余(rb5,rb4,rb2,rb0)为输出。
至于数字的格式,你爱怎么写就怎么写,上面的例子还可以写为:
trisb=0xca;
trisb=202;
以上的二句与trisb=0b11001010;都是完全一样的结果,只是数字的格式不同罢了。
显然,虽然几种格式结果是一样的,但在这里,用二进制表示是最直观的。
顺便说一下,pic默认时,引脚是输入的,即默认时,trisx=0xff.
⑵ 单片机中的宏定义
我试过ATmega16的可以通过(codevisionavr环境)、看你现在用哪款AVR单片机,你这里是乘法乘的过程出现了溢出
⑶ 单片机汇编语言 宏定义 问题
如果,两个18B20共存,可以:
ds18b20_2 equ p1.2
hbit_2 equ 05h
lbit_2 equ 06h
即可。
⑷ 单片机中宏定义与重新定义数据类型(typedef)区别,并且各自的优势(初学单片机)
1) #define宏定义有一个特别的长处:可以使用 #ifdef ,#ifndef等来进行逻辑判断,还可以使用#undef来取消定义。
2) typedef也有一个特别的长处:它符合范围规则,使用typedef定义的变量类型其作用范围限制在所定义的函数或者文件内(取决于此变量定义的位置),而宏定义则没有这种特性。
3)typedef比#define更安全。举个例子:
typedef char* pStr1;
#define pStr2 char *
pStr1 s1, s2;
pStr2 s3, s4;
在上述的变量定义中,s1、s2、s3都被定义为char *,而s4则定义成了char,不是我们所预期的指针变量,根本原因就在于#define只是简单的字符串替换而typedef则是为一个类型起新名字。
⑸ 单片机原理及接口技术的人民邮电最新出版
书名单片机原理及接口技术(C51编程)
丛 书 名21世纪高等学校计算机规划教材——名家系列
标准书号ISBN 978-7-115-25665-2
编目分类TP368.1
作者张毅刚 主编
出版社 人民邮电出版社
责任编辑武恩玉
开本16 开
印张18
字数474 千字
页数280 页
装帧平装
版次第1版第1次
初版时间2011年8月
本 印 次2011年8月
定价34.00 元 《单片机原理及接口技术(C51编程)》详细介绍了美国ATMEL公司的AT89S51单片机的硬件结构和片内外围部件的工作原理,Keil C51编程基础知识,并从应用设计的角度介绍AT89S51单片机的各种常用的硬件接口设计,以及相应的Keil C51接口驱动程序设计。本书最后介绍了AT89S51单片机应用系统设计以及一些典型应用举例。
《单片机原理及接口技术(C51编程)》可作为各类工科院校、职业技术学院电子技术、计算机、工业自动化、自动控制、智能仪器仪表、电气工程、机电一体化等专业单片机课程教材,也可供从事单片机应用设计的工程技术人员参考。 第1章单片机概述1
1.1什么是单片机1
1.2单片机的发展历史2
1.3单片机的特点2
1.4单片机的应用3
1.5单片机的发展趋势4
1.6MCS-51系列与AT89S5x系列单片机5
1.6.1MCS-51系列单片机5
1.6.2AT89系列单片机6
1.6.3AT89系列单片机的型号说明7
1.7各种衍生品种的51单片机8
1.7.1STC系列单片机9
1.7.2C8051F×××单片机10
1.7.3ADμC812单片机10
1.7.4华邦W77系列、W78系列单片机10
1.8PIC系列单片机与AVR系列单片机10
1.8.1PIC系列单片机11
1.8.2AVR系列单片机12
1.9其他的嵌入式处理器简介12
1.9.1嵌入式DSP处理器13
1.9.2嵌入式微处理器13
思考题及习题14
第2章AT89S51单片机硬件结构15
2.1AT89S51单片机的硬件组成15
2.2AT89S51的引脚功能17
2.2.1电源及时钟引脚17
2.2.2控制引脚18
2.2.3并行I/O口引脚18
2.3AT89S51的CPU19
2.3.1运算器19
2.3.2控制器21
2.4AT89S51单片机存储器的结构21
2.4.1程序存储器空间22
2.4.2数据存储器空间23
2.4.3特殊功能寄存器23
2.4.4位地址空间26
2.5AT89S51单片机的并行I/O端口27
2.6时钟电路与时序29
2.6.1时钟电路设计29
2.6.2机器周期、指令周期与指令时序30
2.7复位操作和复位电路31
2.7.1复位操作31
2.7.2复位电路设计31
2.8低功耗节电模式33
2.8.1空闲模式33
2.8.2掉电运行模式34
2.8.3掉电和空闲模式下的WDT34
思考题及习题35
第3章C51语言编程基础37
3.1编程语言Keil C51简介37
3.1.1Keil C51简介37
3.1.2C51与标准C的比较38
3.2Keil C51的开发工具39
3.2.1集成开发环境Keil μVision3简介39
3.2.2Keil μVision3软件的安装、启动和运行40
3.3C51语言程序设计基础40
3.3.1C51语言中的数据类型与存储类型41
3.3.2C51语言的特殊功能寄存器及位变量定义45
3.3.3C51语言的绝对地址访问47
3.3.4C51的基本运算48
3.3.5C51的分支与循环程序结构50
3.3.6C51的数组57
3.3.7C51的指针58
3.4C51语言的函数60
3.4.1函数的分类60
3.4.2函数的参数与返回值61
3.4.3函数的调用62
3.4.4中断服务函数63
3.4.5变量及存储方式63
3.4.6宏定义与文件包含64
3.4.7库函数65
3.5软件仿真开发工具Proteus与Keil μVision3的联调65
3.5.1软件仿真开发工具Proteus简介65
3.5.2Proteus与Keil μVision3的联调66
思考题及习题67
第4章AT89S51片内并行端口的原理及编程68
4.1AT89S51的并行I/O端口的结构及工作原理68
4.1.1P0口68
4.1.2P1口70
4.1.3P2口70
4.1.4P3口71
4.1.5P1~P3口驱动LED发光二极管的问题72
4.2并行I/O端口的C51编程举例73
4.2.1从左到右的流水灯的制作73
4.2.2左右来回循环的流水灯的制作73
4.2.3开关量检测指示器176
4.2.4开关量检测指示器276
思考题及习题77
第5章AT89S51单片机的中断系统79
5.1AT89S51中断技术概述79
5.2AT89S51中断系统结构79
5.2.1中断请求源80
5.2.2中断请求标志寄存器80
5.3中断允许与中断优先级的控制81
5.3.1中断允许寄存器IE82
5.3.2中断优先级寄存器IP82
5.4响应中断请求的条件84
5.5外部中断的响应时间85
5.6外部中断的触发方式选择86
5.6.1电平触发方式86
5.6.2跳沿触发方式86
5.7中断请求的撤销86
5.8中断函数87
5.9C51编程举例88
5.9.1单一外中断的应用88
5.9.2两个外中断的应用89
5.9.3中断嵌套91
5.9.4多外部中断源系统设计92
思考题及习题93
第6章AT89S51单片机的定时器/计数器95
6.1定时器/计数器的结构95
6.1.1工作方式控制寄存器TMOD96
6.1.2定时器/计数器控制寄存器TCON96
6.2定时器/计数器的4种工作方式97
6.2.1方式097
6.2.2方式198
6.2.3方式298
6.2.4方式399
6.3对外部输入的计数信号的要求100
6.4定时器/计数器的编程和应用101
6.4.1P1口外接的8只LED每0.5s闪亮一次101
6.4.2计数器的应用102
6.4.3扩展一个外部中断源103
6.4.4P1.0上产生周期为2ms的方波104
6.4.5P1.1上产生周期为1s的方波104
6.4.6T1控制发出1kHz的音频信号105
6.4.7测量脉冲宽度——门控位GATEx的应用106
6.4.8实时时钟的设计107
思考题及习题108
第7章AT89S51单片机的串行口110
7.1串行口的结构110
7.1.1串行口控制寄存器SCON110
7.1.2特殊功能寄存器PCON112
7.2串行口的4种工作方式112
7.2.1方式0112
7.2.2方式1116
7.2.3方式2117
7.2.4方式3118
7.3多机通信119
7.4波特率的制定方法120
7.4.1波特率的定义120
7.4.2定时器T1产生波特率的计算120
7.5串行通信的应用设计122
7.5.1各种串行通信接口标准122
7.5.2方式1的应用124
7.5.3方式2和方式3的应用127
7.5.4主从式多机通信的应用129
7.5.5单片机与PC的串行通信133
7.5.6PC与单片机或与多个单片机的串行通信接口设计135
思考题及习题136
第8章AT89S51单片机外部存储器的扩展138
8.1系统扩展结构138
8.2地址空间分配和外部地址锁存器139
8.2.1存储器地址空间分配139
8.2.2外部地址锁存器142
8.3程序存储器EPROM的扩展144
8.3.1常用的EPROM芯片144
8.3.2程序存储器的操作时序146
8.3.3AT89S51单片机与EPROM的接口电路设计148
8.4静态数据存储器RAM的扩展149
8.4.1常用的静态RAM(SRAM)芯片149
8.4.2外扩数据存储器的读写操作时序150
8.4.3AT89S51单片机与RAM的接口电路设计151
8.5EPROM和RAM的综合扩展153
8.5.1综合扩展的硬件接口电路153
8.5.2外扩存储器电路的编程155
8.6片内Flash存储器的编程155
8.6.1通用编程器编程157
8.6.2ISP编程157
思考题及习题158
第9章AT89S51单片机的I/O扩展160
9.1I/O接口扩展概述160
9.1.1扩展的I/O接口功能160
9.1.2I/O端口的编址160
9.1.3I/O数据的传送方式161
9.1.4I/O接口电路161
9.2AT89S51扩展I/O接口芯片82C55的设计162
9.2.182C55芯片简介162
9.2.2工作方式选择控制字及端口PC置位/复位控制字163
9.2.382C55的3种工作方式165
9.2.4AT89S51单片机与82C55的接口设计169
9.3利用74LSTTL电路扩展并行I/O口171
9.4用AT89S51单片机的串行口扩展并行口172
9.4.1用74LS165扩展并行输入口172
9.4.2用74LS164扩展并行输出口173
9.5用I/O口控制的声音报警接口174
9.5.1扬声器报警接口174
9.5.2音乐报警接口176
思考题及习题176
第10章AT89S51单片机与输入/输出外设的接口178
10.1LED数码管显示器的接口设计178
10.1.1LED数码管的工作原理178
10.1.2LED数码管显示器接口设计举例179
10.2键盘的接口设计183
10.2.1键盘接口应解决的问题183
10.2.2键盘接口设计举例184
10.2.3键盘扫描方式的选取188
10.3键盘/显示器接口的设计实例188
10.3.1利用并行I/O芯片82C55实现键盘/显示器接口188
10.3.2利用串行口实现的键盘/显示器接口191
10.3.3专用接口芯片HD7279实现的键盘/显示器控制193
10.4AT89S51单片机与液晶显示器的接口204
10.4.1LCD显示器的分类204
10.4.2点阵字符型液晶显示模块介绍204
10.4.3AT89S51单片机与LCD的接口及软件编程208
10.5AT89S51单片机与微型打印机TP(P-40A/16A的接口211
10.6AT89S51单片机与BCD码拨盘的接口设计215
思考题及习题216
第11章AT89S51单片机与D/A、A/D转换器的接口217
11.1AT89S51单片机与DAC的接口217
11.1.1D/A转换器简介217
11.1.2AT89S51单片机与8位D/A转换器0832的接口设计218
11.2AT89S51单片机与ADC的接口225
11.2.1A/D转换器简介225
11.2.2AT89S51与逐次比较型8位A/D转换器ADC0809的接口226
11.2.3AT89S51与逐次比较型12位A/D转换器AD1674的接口230
11.3AT89S51单片机与V/F转换器的接口234
11.3.1用V/F转换器实现A/D转换的原理235
11.3.2常用V/F转换器LMX31简介235
11.3.3V/F转换器与MCS-51单片机接口236
11.3.4LM331应用举例237
思考题及习题238
第12章单片机的串行扩展技术239
12.1单总线串行扩展239
12.2SPI总线串行扩展240
12.2.1SPI总线的扩展结构241
12.2.2扩展带SPI串口的A/D转换器TLC2543242
12.3I2C总线的串行扩展243
12.3.1I2C串行总线系统的基本结构244
12.3.2I2C总线的数据传送规定244
12.3.3AT89S51的I2C总线扩展系统247
12.3.4I2C总线数据传送的模拟248
12.3.5I2C总线在IC卡中的应用251
思考题及习题255
第13章AT89S51单片机的应用设计与调试256
13.1单片机应用系统的设计步骤256
13.2单片机应用系统设计257
13.2.1硬件设计应考虑的问题257
13.2.2典型的单片机应用系统258
13.2.3系统设计中的地址空间分配与总线驱动259
13.2.4应用设计例1——最小应用系统设计261
13.2.5应用设计例2——数字电压表的设计262
13.2.6应用设计例3——带有报警功能的温度测量仪的设计264
13.3单片机应用系统的仿真开发与调试266
13.3.1仿真开发系统的种类与基本功能267
13.3.2仿真开发系统简介267
13.3.3用户样机的仿真调试270
13.4单片机应用系统的抗干扰与可靠性设计272
13.4.1AT89S51片内看门狗定时器的使用273
13.4.2软件滤波273
13.4.3开关量输入/输出软件抗干扰设计274
13.4.4过程通道干扰的抑制措施——隔离275
13.4.5印刷电路板抗干扰布线的基本原则276
思考题及习题278
参考文献280
⑹ 单片机c语言宏定义有几种
宏定义
宏定义是C提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译
编辑本段1.不带参数的宏定义:
宏定义又称为宏代换、宏替换,简称“宏”。
格式:
#define 标识符 字符串
其中的标识符就是所谓的符号常量,也称为“宏名”。
预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。
掌握"宏"概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。
即在对相关命令或语句的含义和功能作具体分析之前就要换:
例:
#define PI 3.1415926
把程序中出现的PI全部换成3.1415926
说明:
(1)宏名一般用大写
(2)使用宏可提高程序的通用性和易读性,减少不一致性,减少输入错误和便于修改。例如:数组大小常用宏定义
(3)预处理是在编译之前的处理,而编译工作的任务之一就是语法检查,预处理不做语法检查。
(4)宏定义末尾不加分号;
(5)宏定义写在函数的花括号外边,作用域为其后的程序,通常在文件的最开头。
(6)可以用#undef命令终止宏定义的作用域
(7)宏定义可以嵌套
(8)字符串" "中永远不包含宏
(9)宏定义不分配内存,变量定义分配内存。
编辑本段2.带参数的宏定义:
除了一般的字符串替换,还要做参数代换
格式:
#define 宏名(参数表) 字符串
例如:#define S(a,b) a*b
area=S(3,2);第一步被换为area=a*b; ,第二步被换为area=3*2;
类似于函数调用,有一个哑实结合的过程:
(1)实参如果是表达式容易出问题
#define S(r) r*r
area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b;
正确的宏定义是#define S(r) ((r)*(r))
(2)宏名和参数的括号间不能有空格
(3)宏替换只作替换,不做计算,不做表达式求解
(4)函数调用在编译后程序运行时进行,并且分配内存。宏替换在编译前进行,不分配内存
(5)宏的哑实结合不存在类型,也没有类型转换。
(6)函数只有一个返回值,利用宏则可以设法得到多个值
(7)宏展开使源程序变长,函数调用不会
(8)宏展开不占运行时间,只占编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值
C语言宏定义技巧(常用宏定义)
写好C语言,漂亮的宏定义很重要,使用宏定义可以防止出错,提高可移植性,可读性,方便性 等等。
下面列举一些成熟软件中常用得宏定义:
1,防止一个头文件被重复包含
#ifndef COMDEF_H
#define COMDEF_H
//头文件内容
#endif
2,重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
typedef unsigned char boolean; /* Boolean value type. */
typedef unsigned long int uint32; /* Unsigned 32 bit value */
typedef unsigned short uint16; /* Unsigned 16 bit value */
typedef unsigned char uint8; /* Unsigned 8 bit value */
typedef signed long int int32; /* Signed 32 bit value */
typedef signed short int16; /* Signed 16 bit value */
typedef signed char int8; /* Signed 8 bit value */
3,得到指定地址上的一个字节或字
#define MEM_B( x ) ( *( (byte *) (x) ) )
#define MEM_W( x ) ( *( (word *) (x) ) )
4,求最大值和最小值
#define MAX( x, y ) ( ((x) > (y)) ? (x) : (y) )
#define MIN( x, y ) ( ((x) < (y)) ? (x) : (y) )
5,得到一个field在结构体(struct)中的偏移量
#define FPOS( type, field ) \
/*lint -e545 */ ( (dword) &(( type *) 0)-> field ) /*lint +e545 */
6,得到一个结构体中field所占用的字节数
#define FSIZ( type, field ) sizeof( ((type *) 0)->field )
7,按照LSB格式把两个字节转化为一个Word
#define FLIPW( ray ) ( (((word) (ray)[0]) * 256) + (ray)[1] )
8,按照LSB格式把一个Word转化为两个字节
#define FLOPW( ray, val ) \
(ray)[0] = ((val) / 256); \
(ray)[1] = ((val) & 0xFF)
9,得到一个变量的地址(word宽度)
#define B_PTR( var ) ( (byte *) (void *) &(var) )
#define W_PTR( var ) ( (word *) (void *) &(var) )
10,得到一个字的高位和低位字节
#define WORD_LO(xxx) ((byte) ((word)(xxx) & 255))
#define WORD_HI(xxx) ((byte) ((word)(xxx) >> 8))
11,返回一个比X大的最接近的8的倍数
#define RND8( x ) ((((x) + 7) / 8 ) * 8 )
12,将一个字母转换为大写
#define UPCASE( c ) ( ((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c) )
13,判断字符是不是10进值的数字
#define DECCHK( c ) ((c) >= '0' && (c) <= '9')
14,判断字符是不是16进值的数字
#define HEXCHK( c ) ( ((c) >= '0' && (c) <= '9') ||\
((c) >= 'A' && (c) <= 'F') ||\
((c) >= 'a' && (c) <= 'f') )
15,防止溢出的一个方法
#define INC_SAT( val ) (val = ((val)+1 > (val)) ? (val)+1 : (val))
16,返回数组元素的个数
#define ARR_SIZE( a ) ( sizeof( (a) ) / sizeof( (a[0]) ) )
17,返回一个无符号数n尾的值MOD_BY_Power_OF_TWO(X,n)=X%(2^n)
#define MOD_BY_POWER_OF_TWO( val, mod_by ) \
( (dword)(val) & (dword)((mod_by)-1) )
18,对于IO空间映射在存储空间的结构,输入输出处理
#define inp(port) (*((volatile byte *) (port)))
#define inpw(port) (*((volatile word *) (port)))
#define inpdw(port) (*((volatile dword *)(port)))
#define outp(port, val) (*((volatile byte *) (port)) = ((byte) (val)))
#define outpw(port, val) (*((volatile word *) (port)) = ((word) (val)))
#define outpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))
[2005-9-9添加]
19,使用一些宏跟踪调试
A N S I标准说明了五个预定义的宏名。它们是:
_ L I N E _
_ F I L E _
_ D A T E _
_ T I M E _
_ S T D C _
如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序
也许还提供其它预定义的宏名。
_ L I N E _及_ F I L E _宏指令在有关# l i n e的部分中已讨论,这里讨论其余的宏名。
_ D AT E _宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。
源代码翻译到目标代码的时间作为串包含在_ T I M E _中。串形式为时:分:秒。
如果实现是标准的,则宏_ S T D C _含有十进制常量1。如果它含有任何其它数,则实现是
非标准的。
可以定义宏,例如:
当定义了_DEBUG,输出数据信息和所在文件所在行
#ifdef _DEBUG
#define DEBUGMSG(msg,date) printf(msg);printf(“%d%d%d”,date,_LINE_,_FILE_)
#else
#define DEBUGMSG(msg,date)
#endif
20,宏定义防止使用是错误
用小括号包含。
例如:#define ADD(a,b) (a+b)
用do{}while(0)语句包含多语句防止错误
例如:#difne DO(a,b) a+b;\
a++;
应用时:if(….)
DO(a,b); //产生错误
else
解决方法: #difne DO(a,b) do{a+b;\
a++;}while(0)
宏中"#"和"##"的用法
一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#include<cstdio>
#include<climits>
using namespace std;
#define STR(s) #s
#define CONS(a,b) int(a##e##b)
int main()
{
printf(STR(vck)); // 输出字符串"vck"
printf("%d
", CONS(2,3)); // 2e3 输出:2000
return 0;
}
⑺ 单片机C语言的宏定义有什么作用!!
跟单片机没关系,这是C语言的东西
-------------
#是C语言里的预处理命令,编译器在编译代码之前,会预先处理这部分内容,#define 就是宏定义,对于 #define 的内容是怎样处理的呢?看下面的代码
#define MAX 128
void main()
{
int max=MAX;
}
编译器处理时,会直接把 int max=MAX;替换成 int max=128; 注意,是文本替换,而不是变量赋值,程序中自始至终都不存在MAX这个变量,相当于是用“查找-替换”功能一样,查找 MAX ,替换成 128 。
如果程序中有多个地方要用到同一个值、代码块,我们都可以定义成一个宏,如果这些值或代码块要改动,只需改下宏定义就行了,不用从代码中一处一处的改,很方便,而且不会因为漏掉某个地方而导致程序出错。
⑻ 单片机c语言 宏定义 什么意思
为了程序员的方便理解、调试。比如你在程序里要用圆周率3.14,你可以写上3.14,可是别人看了3.14不知道你说的是圆周率呀,所以你用宏定义弄个PI=3.14放在开头,后面注释圆周率,下来的代码里需要用圆周率的地方就用写成PI,大家就理解了。而且呢,如果3.14精度不够,你想用3.1415926,直接改宏定义PI,改成3.1415926就行了,要不然你用数字的话,就得把程序里所有用到圆周率的地方都改一遍,多麻烦呀,万一漏一个不就错了么。
⑼ 单片机C语言宏定义问题
宏定义:
sfr WORKPD = 0x80;
#define work 0x00
#define k_add 0x01
#define k_sub 0x02
#define k_stop 0x03
void main()
{
while(1) {
//位操作指令:
WORKPD |= (1 << k_add); //置一 WORKPD.1
WORKPD &= ~(1 << k_sub); //清零 WORKPD.2
WORKPD &= (1 << k_stop); //保留 WORKPD.3,清除其它位
……
⑽ 单片机 C语言中的 宏定义
#define LED P1 试试