第1章 学会阅读Datasheet 2
如何阅读PDF文件,如何获得Datasheet文件 3
Datasheet告诉我们些什么 4
如何看懂AVR的Datasheet 8
如何得到帮助 9
汇编语言执行时间的计算方法 9
ATmega48/88/168常用熔丝的作用及其配置方法 11
对误烧写为外部时钟模式的解锁方法 13
实例1阅读74HC595 Datasheet 13
第2章 深入开发环境 16
认识ICC编译环境 17
事半功倍的代码生成器 20
ICC之不得不说的故事 21
AVR最小系统和下载线DIY 30
实例2 AVR最小系统DIY 31
第3章 从跑马灯开始 52
输入/输出界面 53
单片机的输入/输出设备——引脚 53
“芯”里有数——数码管显示 54
单片机的输入/输出设备——从按键到键盘 58
用ATmega48/88/168单片机端口驱动数码管 60
操纵ATmega48/88/168单片机端口 60
端口内建上拉电阻的使用 62
端口位操作 62
实例3跑马灯 65
实例4 数码管的显示(上) 69
实例5 数码管的显示(下) 74
实例6 矩阵键盘 78
第4章 对不起接个电话 84
十万火急——中断 85
中断的特性 85
使用中断时的注意事项 90
ATmega48/88/168单片机有哪些中断源 90
如何编写一个中断的服务程序代码 91
ATmega48/88/168单片机中断的开关控制 93
ATmega48/88/168中断标志位 93
ATmega48/88/168中断优先级 94
ATmega48/88/168单片机中断向量 94
中断与查询之争 95
用查询方式响应外设中断 97
中断误触发 97
前后台与原子操作 100
实例7中断唤醒的键盘扫描 103
实例8旋转编码器 109
第5章 一秒究竟有多长 119
单片机与时间 120
软件延时 124
不需要加载的“自由计时器” 125
通过重加载控制定时中断周期 126
使用代码生成器生成定时器1初始化代码 127
定时器的其他工作模式 130
PWM波及其应用简介 130
人类能看懂的电子时钟——实时时钟简介 131
实例9闪烁的灯 132
实例10渐明渐暗的灯 137
实例11复杂闪烁控制 145
第6章 电量低 156
从猜数游戏到A/D转换器 157
ATmega48/88/168的A/D转换器 158
ATmega48/88/168单片机中与A/D相关的引脚 161
ATmega48/88/168单片机中与A/D相关的寄存器 161
使用A/D时需要注意些什么 161
怎样知道A/D转换完成 163
读取A/D的转换结果 164
使用代码生成器生成ADC初始化代码 165
书写具有工程结构的初始化代码 167
电量计原理概述 169
转换结果读取方式的比较 170
ADC噪声抑制模式 173
A/1D的软件滤波技术 174
软件实现的施密特触发器 186
实例12电量计 187
第7章 正在过收费站 192
从并行通信到串行通信 193
这个世界上我们都被“缓冲”着 194
将串行进行到底 194
串行外设接口SPI 195
都是环形队列惹的祸 196
使用代码生成器生成SPI初始化代码 197
SPI通信缓冲的C语言实现 201
缓冲区的刷新算法 203
79中断的同步 204
建立SPI总线 205
SPI环路总线的优化 210
实例13端口扩展 212
实例14键盘显示模块 221
第8章 包装的学问 232
从邮递员的包裹说起 233
心有灵犀的异步通信 234
数据的包裹——帧 235
应用的包裹——数据包 237
解剖串口模块 238
使用代码生成器生成USART初始化代码 239
9位数据帧的发送和接收 240
建立串行通信缓冲区 241
9数据位模式下的多机通信 247
多机通信的C语言实现 248
初识状态机 250
单字节一应一答式通信 253
多字节通信协议 258
简单定长数据包通信协议 259
变长数据包通信协议 263
实例15数字电压表 265
第9章 傻孩子求职记 273
TWI:一根时钟线、一根信号线 274
半双工通信 275
求职者模型 276
TWI的总线仲裁 277
贼老大的计划 279
TWI总线协议状态机 281
TWI通信状态机带来的麻烦 282
Datasheet寄存器查阅导读 283
使用代码生成器生成TWI初始化代码 284
书写具有工程结构的C语言代码 286
TWI通信状态机的建立 289
轻松设计TWI通信状态机 298
实例16存储器24C01的读写 299
实例17 I 2C抢答器 309
第10章 MISSION UPDATE 316
展望UPDATE 317
ISP和IAP 318
IAP的要点、难点与风险 319
ATmega48/88/168的FLASH分区 323
程序锁定熔丝的设置 325
操纵程序存储器 327
把IAP程序放进BOOT区 329
小试牛刀 330
C语言与汇编语言之争 331
用汇编语言操作FLASH存储器 332
实例18 ATmega48在线程序更新 333
第11章 朝花夕拾 346
一个位运算的例子 347
文如其形的移位运算 347
颠倒黑白的“取反”运算 351
一票否决的“与”运算 351
一票通过的“或”操作 353
求同存异的“异或”运算 353
位运算和逻辑运算的区别 354
为什么要使用宏定义 355
宏定义的基本形式 356
“参数宏”由便利带来的麻烦 358
方便的条件编译 360
从结构体到位段 362
“别动我的奶酪!” 365
居安思危的volatile 369
“你不知道我知道” 372
实例19编写我们的第一个头文件 375
第12章 指针都是纸老虎 378
存储器是一个大数组 379
“指鹿为马”说指针 379
空指针(void*) 381
变量、指针变量、指针常量与“不应该被修改的指针变量” 382
数组、指针数组、数组指针 384
多维数组 386
指向指针的指针 389
地址绑定与“偷天换日” 390
大端对齐与小端对齐 391
内存入侵 392
extern:“在想你的三百六十五天……” 397
人去楼空的“野指针” 399
分支程序 400
消息地图与函数指针 400
态内存分配ABC 404
实例20端口位操作的实现 407
第13章 来自身边的启示 413
超市储藏箱模型 414
由数数引起的思考 417
学习数据结构的本质障碍 418
先来后到说队列 422
队列的简单空间映射 423
环形队列 425
滑动窗口 430
从爬楼梯想到后入先出 431
栈的简单空间映射 432
软件堆栈和硬件堆栈 434
内存垃圾 439
被遗忘的奶酪 440
垃圾的预防 441
实例21贪食蛇 442
第14章 初识嵌入式系统 450
初学者眼中的嵌入式 451
从黑盒子谈起 452
理想黑盒子 452
使用黑盒子的好处、必然性和代价 453
从黑盒子到模块化 454
什么是黑盒子哲学 455
源文件和头文件的分工 458
为什么不能在头文件中放置函数和变量的实体 461
循环包含的麻烦 462
模块分层结构下的头文件包含 466
硬件无关性与硬件抽象层 468
从编码习惯到编码规范 472
网文《请不要做浮躁的嵌入式工程师》 474
“足够好原则”与“即时上市” 475
附录A ATmega48/88/168简介 477
附录B ICC环境下的汇编 479
附录C ICC环境下的存储器结构 484
附录D ASCII码表 489
附录E ATmega48/88/168指令集概述 490
附录F ATmega48/88/168寄存器概述 494
附录G 常见的错误代码及其解释 497
附录H ATmega48/88/168端口封装图 501
附录I ATmega48/88/168开发实验工具 503
附录J AT JTAGICE mkll AVR仿真器介绍 507
参考文献和相关网站 509