<<**汇编与接口技术>>
基于A/D采集的交互式报警系统**


一、实验目的

(1)考察和培养综合运用学到的接口知识自主设计和完成实验的能力。
(2)培养团队合作的能力。


二、实验内容

基于A/D采集的交互式报警系统
当继电器电压值小于2.5V时,代表着错误的状态,此时应该发出报警信号,为了能够有效对外界进行提醒,此时8X8点阵显示一个“囧”脸形状,扬声器发出报警信号。当电压大于2.5V时,代表着正确的状态,此时不用发出报警信号,8X8点阵显示一个“心”的形状,扬声器不发声。
所需器件: 8X8点阵,扬声器,8255并行接口,8254定时器,ADC0809,电位器,继电器数码管显示所采集的数字量的值。


三、实验设计

实验简述: 我们需要通过ADC0809从电位器读取电平进行AD转换,将模拟信号转化为数字信号,然后读取数字信号并将其显示到LED数码管上,同时,判断该数值的大小是否小于7F也就是电平所对应2.5V分界。如果该读数大于7F,我们就在8X8点阵上显示“心”型,如果小于7F,则在8X8点阵上显示为“囧”,并且使用8054使扬声器发出警告。
实验流程图:
As: 综合研究性实验 - 图1
实验连线图:
As: 综合研究性实验 - 图2

8x8点阵显示原理:
简述: TPC386实验箱中8x8点阵由64个发光二极管组成,64个发光二极管组成8x8矩阵。某行线给出高电平,某列线给出低电平则行线与列线交叉的发光二极管就会被点亮。8x8点阵的点亮是采用扫描式的,8x8点阵一次只能点亮一个耳光二极管。但是两个发光二极管间的点亮间隔很小,人眼无法分辨,所以可以造成视觉差显示某个特定的图案。例如本实验中的“心”形和“囧”形。
连线: 我们将8x8点阵与8255并行接口进行配合使用,该实验中,我们使用PA0-7作为行输入而PB0-7作为列输入以此来操作。8255的PA0-7接8x8点阵的H0-7,PB0-7接V0-7。连线图如下:
As: 综合研究性实验 - 图3
代码实现:** 为了程序的简洁和美观,我们将显示“心”形和“囧”形的功能分别写为两个子函数,在主程序中调用。所以通过模块化思想,我们分别设计两个子程序。error_disp和heart_disp。
As: 综合研究性实验 - 图4
As: 综合研究性实验 - 图5
我们对显示图形的每一行每一列进行程序编写,所以代码很冗杂臃肿,光是显示一个“囧”字就写了超过300行代码。而“心”字比较连续也写了200多行。

LED显示原理:
简述: 在该实验中我们需要将读取到的数值显示到数码管上,跟以往在数码管上显示一位数字不同,这一次需要显示两位16进制数,也就是除了0-9还有A-F。我们的数码管并不能同时显示两位数,所以我们可以用与8x8点阵类似的思想,造成视觉效果,以为同时显示了两位数字。
连线: 直接将220端口与LED数码管相连即可。
代码实现: 我们也将数码管示数写入一个子程序中,disp。采用位屏蔽技术提取高位数字和低位数字分别显示。
As: 综合研究性实验 - 图6
扬声器发声原理:
原理: 我们使用8254定时器和8255 PC2口配合与门使用,我们通过配置8254控制扬声器发声的频率,使用PC2 控制扬声器发声。如果PC2置1,则扬声器发声,置0则不发声。
连线:
As: 综合研究性实验 - 图7
代码实现: 首先对8254进行初始化。如果读取到的数值小于7F,则置PC2为1,否则置为0。
As: 综合研究性实验 - 图8
As: 综合研究性实验 - 图9
ADC0809数模转换:
原理: ADC启动地址转换,通过读取EOC状态判断是否转换完成,然后进行读数操作。
连线:
As: 综合研究性实验 - 图10
代码实现:
As: 综合研究性实验 - 图11


四、实验结果

AD报警系统.mov (25.34MB)


code

  1. .Model small
  2. .386
  3. ad_cs equ 200h
  4. i8254_0 EQU 210H
  5. i8254_1 equ 211h
  6. i8254kz equ 213h
  7. led_cs equ 220h
  8. data segment
  9. ledcode db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,67h,77h,7ch,39h,5eh,79h,71h ;0-F
  10. bit_num db 01h,02h,04h,08h,10h,20h,40h,80h ;led 位置选择码
  11. i8255_a equ 230h
  12. i8255_b equ 231h
  13. i8255kz equ 233h
  14. sum db ?
  15. point dw ?,? ;存放位置选择码指针
  16. data ends
  17. code segment
  18. assume cs:code,ds:data
  19. start: mov ax,data
  20. mov ds,ax
  21. mov dx,i8254kz
  22. mov al,36h ;计数器0方式3BCD码计数
  23. out dx,al
  24. mov ax,400 ;写入循环计数初值1000
  25. mov dx,i8254_0 ;计数器0设置初值
  26. out dx,al ;先写低字节
  27. mov al,ah
  28. out dx,al ;后写高字节
  29. rpt: mov dx,ad_cs ;ADC启动转换地址
  30. out dx,al
  31. mov dx,ad_cs ;获取ADC EOC状态地址
  32. add dx,2
  33. l1: in al,dx
  34. test al,01h ;测试EOC=1?
  35. jz l1
  36. mov dx,ad_cs ;读数据地址
  37. inc dx
  38. in al,dx
  39. mov [sum],al ;读取数据量
  40. ;and sum,0fh
  41. ; 数码管示数
  42. call disp
  43. cmp sum,7fh
  44. jb erro
  45. mov dx,i8255kz
  46. mov al,04h ;置PC21,PC2接扬声器
  47. out dx,al
  48. ;88点阵显示心形
  49. call heart_disp
  50. jmp rpt
  51. erro: ;此处为电压小于2.5V
  52. mov dx,i8255kz
  53. mov al,05h ;置PC20,PC2接扬声器
  54. out dx,al
  55. ;88点阵显示囧字
  56. call error_disp
  57. jmp rpt
  58. error_disp proc
  59. push ax
  60. push bx
  61. push cx
  62. push dx
  63. mov dx,i8255kz ;8255 控制口地址
  64. mov al,80h
  65. out dx,al
  66. kL1:
  67. stc ;置 CF=1,准备形成位置码
  68. mov al,0
  69. lea di,bit_num ;初始位选码指针
  70. mov point,di
  71. kkk:
  72. rcl al,1 ;设置 V0=1
  73. mov bl,al ;保护
  74. mov dx,i8255_a ;8255 端口 A 地址
  75. out dx,al ;选中一行
  76. mov si,point ;取位置表开始地址指针
  77. mov cx,8 ;列循环次数
  78. krow1:
  79. mov al,[si] ;设置 Hx=1
  80. mov dx,i8255_b ;8255 端口 B 地址
  81. out dx,al ;选中一列并显示
  82. ;call delay
  83. inc si ;修改地址
  84. loop krow1
  85. lea di,bit_num
  86. mov point,di ;从位置表首地址开始
  87. mov al,bl
  88. krow2:
  89. rcl al,1 ;设置 V0=2
  90. mov bl,al ;保护
  91. mov dx,i8255_a ;8255 端口 A 地址
  92. out dx,al ;选中一行
  93. mov si,point ;取位置表开始地址指针
  94. mov al,[si] ;设置 Hx=1
  95. mov dx,i8255_b ;8255 端口 B 地址
  96. out dx,al ;选中一列并显示
  97. ;call delay
  98. inc si ;修改地址
  99. inc si
  100. ;mov si,point ;取位置表开始地址指针
  101. mov al,[si] ;设置 Hx=3
  102. mov dx,i8255_b ;8255 端口 B 地址
  103. out dx,al ;选中一列并显示
  104. ;call delay
  105. inc si ;修改地址
  106. inc si
  107. inc si
  108. ;mov si,point ;取位置表开始地址指针
  109. mov al,[si] ;设置 Hx=1
  110. mov dx,i8255_b ;8255 端口 B 地址
  111. out dx,al ;选中一列并显示
  112. ;call delay
  113. inc si ;修改地址
  114. inc si
  115. ;mov si,point ;取位置表开始地址指针
  116. mov al,[si] ;设置 Hx=1
  117. mov dx,i8255_b ;8255 端口 B 地址
  118. out dx,al ;选中一列并显示
  119. ;call delay
  120. inc si ;修改地址
  121. lea di,bit_num
  122. mov point,di ;从位置表首地址开始
  123. mov al,bl
  124. krow3:
  125. rcl al,1 ;设置 V0=2
  126. mov bl,al ;保护
  127. mov dx,i8255_a ;8255 端口 A 地址
  128. out dx,al ;选中一行
  129. mov si,point ;取位置表开始地址指针
  130. mov al,[si] ;设置 Hx=1
  131. mov dx,i8255_b ;8255 端口 B 地址
  132. out dx,al ;选中一列并显示
  133. ;call delay
  134. inc si ;修改地址
  135. ;mov si,point ;取位置表开始地址指针
  136. mov al,[si] ;设置 Hx=3
  137. mov dx,i8255_b ;8255 端口 B 地址
  138. out dx,al ;选中一列并显示
  139. ;call delay
  140. inc si ;修改地址
  141. inc si
  142. inc si
  143. inc si
  144. inc si
  145. ;mov si,point ;取位置表开始地址指针
  146. mov al,[si] ;设置 Hx=1
  147. mov dx,i8255_b ;8255 端口 B 地址
  148. out dx,al ;选中一列并显示
  149. ;call delay
  150. inc si ;修改地址
  151. ;mov si,point ;取位置表开始地址指针
  152. mov al,[si] ;设置 Hx=1
  153. mov dx,i8255_b ;8255 端口 B 地址
  154. out dx,al ;选中一列并显示
  155. ;call delay
  156. inc si ;修改地址
  157. lea di,bit_num
  158. mov point,di ;从位置表首地址开始
  159. mov al,bl
  160. krow4:
  161. rcl al,1 ;设置 V0=2
  162. mov bl,al ;保护
  163. mov dx,i8255_a ;8255 端口 A 地址
  164. out dx,al ;选中一行
  165. mov si,point ;取位置表开始地址指针
  166. mov al,[si] ;设置 Hx=1
  167. mov dx,i8255_b ;8255 端口 B 地址
  168. out dx,al ;选中一列并显示
  169. ;call delay
  170. inc si ;修改地址
  171. inc si
  172. ;mov si,point ;取位置表开始地址指针
  173. mov al,[si] ;设置 Hx=3
  174. mov dx,i8255_b ;8255 端口 B 地址
  175. out dx,al ;选中一列并显示
  176. ;call delay
  177. inc si ;修改地址
  178. mov al,[si] ;设置 Hx=3
  179. mov dx,i8255_b ;8255 端口 B 地址
  180. out dx,al ;选中一列并显示
  181. ;call delay
  182. inc si ;修改地址
  183. mov al,[si] ;设置 Hx=3
  184. mov dx,i8255_b ;8255 端口 B 地址
  185. out dx,al ;选中一列并显示
  186. ;call delay
  187. inc si ;修改地址
  188. ;mov si,point ;取位置表开始地址指针
  189. mov al,[si] ;设置 Hx=1
  190. mov dx,i8255_b ;8255 端口 B 地址
  191. out dx,al ;选中一列并显示
  192. ;call delay
  193. inc si ;修改地址
  194. inc si
  195. ;mov si,point ;取位置表开始地址指针
  196. mov al,[si] ;设置 Hx=1
  197. mov dx,i8255_b ;8255 端口 B 地址
  198. out dx,al ;选中一列并显示
  199. ;call delay
  200. inc si ;修改地址
  201. lea di,bit_num
  202. mov point,di ;从位置表首地址开始
  203. mov al,bl
  204. krow5:
  205. rcl al,1 ;设置 V0=2
  206. mov bl,al ;保护
  207. mov dx,i8255_a ;8255 端口 A 地址
  208. out dx,al ;选中一行
  209. mov si,point ;取位置表开始地址指针
  210. mov al,[si] ;设置 Hx=1
  211. mov dx,i8255_b ;8255 端口 B 地址
  212. out dx,al ;选中一列并显示
  213. ;call delay
  214. inc si ;修改地址
  215. inc si
  216. ;mov si,point ;取位置表开始地址指针
  217. mov al,[si] ;设置 Hx=3
  218. mov dx,i8255_b ;8255 端口 B 地址
  219. out dx,al ;选中一列并显示
  220. ;call delay
  221. inc si ;修改地址
  222. inc si
  223. inc si
  224. ;mov si,point ;取位置表开始地址指针
  225. mov al,[si] ;设置 Hx=1
  226. mov dx,i8255_b ;8255 端口 B 地址
  227. out dx,al ;选中一列并显示
  228. ;call delay
  229. inc si ;修改地址
  230. inc si
  231. ;mov si,point ;取位置表开始地址指针
  232. mov al,[si] ;设置 Hx=1
  233. mov dx,i8255_b ;8255 端口 B 地址
  234. out dx,al ;选中一列并显示
  235. ;call delay
  236. inc si ;修改地址
  237. lea di,bit_num
  238. mov point,di ;从位置表首地址开始
  239. mov al,bl
  240. krow6:
  241. rcl al,1 ;设置 V0=2
  242. mov bl,al ;保护
  243. mov dx,i8255_a ;8255 端口 A 地址
  244. out dx,al ;选中一行
  245. mov si,point ;取位置表开始地址指针
  246. mov al,[si] ;设置 Hx=1
  247. mov dx,i8255_b ;8255 端口 B 地址
  248. out dx,al ;选中一列并显示
  249. ;call delay
  250. inc si ;修改地址
  251. inc si
  252. ;mov si,point ;取位置表开始地址指针
  253. mov al,[si] ;设置 Hx=3
  254. mov dx,i8255_b ;8255 端口 B 地址
  255. out dx,al ;选中一列并显示
  256. ;call delay
  257. inc si ;修改地址
  258. mov al,[si] ;设置 Hx=3
  259. mov dx,i8255_b ;8255 端口 B 地址
  260. out dx,al ;选中一列并显示
  261. ;call delay
  262. inc si
  263. mov al,[si] ;设置 Hx=3
  264. mov dx,i8255_b ;8255 端口 B 地址
  265. out dx,al ;选中一列并显示
  266. ;call delay
  267. inc si
  268. ;mov si,point ;取位置表开始地址指针
  269. mov al,[si] ;设置 Hx=1
  270. mov dx,i8255_b ;8255 端口 B 地址
  271. out dx,al ;选中一列并显示
  272. ;call delay
  273. inc si ;修改地址
  274. inc si
  275. ;mov si,point ;取位置表开始地址指针
  276. mov al,[si] ;设置 Hx=1
  277. mov dx,i8255_b ;8255 端口 B 地址
  278. out dx,al ;选中一列并显示
  279. ;call delay
  280. inc si ;修改地址
  281. lea di,bit_num
  282. mov point,di ;从位置表首地址开始
  283. mov al,bl
  284. krow7:
  285. rcl al,1 ;设置 V0=2
  286. mov bl,al ;保护
  287. mov dx,i8255_a ;8255 端口 A 地址
  288. out dx,al ;选中一行
  289. mov si,point ;取位置表开始地址指针
  290. mov al,[si] ;设置 Hx=1
  291. mov dx,i8255_b ;8255 端口 B 地址
  292. out dx,al ;选中一列并显示
  293. ;call delay
  294. inc si ;修改地址
  295. inc si
  296. inc si ;修改地址
  297. inc si
  298. inc si
  299. inc si ;修改地址
  300. inc si
  301. ;mov si,point ;取位置表开始地址指针
  302. mov al,[si] ;设置 Hx=1
  303. mov dx,i8255_b ;8255 端口 B 地址
  304. out dx,al ;选中一列并显示
  305. ;call delay
  306. inc si ;修改地址
  307. lea di,bit_num
  308. mov point,di ;从位置表首地址开始
  309. mov al,bl
  310. krow8:
  311. rcl al,1 ;设置 V0=1
  312. mov bl,al ;保护
  313. mov dx,i8255_a ;8255 端口 A 地址
  314. out dx,al ;选中一行
  315. mov si,point ;取位置表开始地址指针
  316. mov cx,8 ;列循环次数
  317. krow88:
  318. mov al,[si] ;设置 Hx=1
  319. mov dx,i8255_b ;8255 端口 B 地址
  320. out dx,al ;选中一列并显示
  321. ;call delay
  322. inc si ;修改地址
  323. loop krow88
  324. lea di,bit_num
  325. mov point,di ;从位置表首地址开始
  326. mov al,bl
  327. pop dx
  328. pop cx
  329. pop bx
  330. pop ax
  331. ret
  332. error_disp endp
  333. heart_disp proc
  334. push ax
  335. push bx
  336. push cx
  337. push dx
  338. mov dx,i8255kz ;8255 控制口地址
  339. mov al,80h
  340. out dx,al
  341. stc ;置 CF=1,准备形成位置码
  342. mov al,0
  343. lea di,bit_num ;初始位选码指针
  344. mov point,di
  345. row2: rcl al,1
  346. rcl al,1 ;设置 V0=1
  347. mov bl,al ;保护
  348. mov dx,i8255_a ;8255 端口 A 地址
  349. out dx,al ;选中一行
  350. mov si,point ;取位置表开始地址指针
  351. inc si
  352. mov al,[si] ;设置 Hx=1
  353. mov dx,i8255_b ;8255 端口 B 地址
  354. out dx,al ;选中一列并显示
  355. ;call delay
  356. inc si ;修改地址
  357. ;mov si,point ;取位置表开始地址指针
  358. mov al,[si] ;设置 Hx=3
  359. mov dx,i8255_b ;8255 端口 B 地址
  360. out dx,al ;选中一列并显示
  361. ;call delay
  362. inc si ;修改地址
  363. inc si
  364. inc si
  365. ;mov si,point ;取位置表开始地址指针
  366. mov al,[si] ;设置 Hx=1
  367. mov dx,i8255_b ;8255 端口 B 地址
  368. out dx,al ;选中一列并显示
  369. ;call delay
  370. inc si ;修改地址
  371. mov al,[si] ;设置 Hx=1
  372. mov dx,i8255_b ;8255 端口 B 地址
  373. out dx,al ;选中一列并显示
  374. inc si
  375. lea di,bit_num
  376. mov point,di ;从位置表首地址开始
  377. mov al,bl
  378. row3:
  379. rcl al,1 ;设置 V0=1
  380. mov bl,al ;保护
  381. mov dx,i8255_a ;8255 端口 A 地址
  382. out dx,al ;选中一行
  383. mov si,point ;取位置表开始地址指针
  384. mov cx,8 ;列循环次数
  385. row33:
  386. mov al,[si] ;设置 Hx=1
  387. mov dx,i8255_b ;8255 端口 B 地址
  388. out dx,al ;选中一列并显示
  389. ;call delay
  390. inc si ;修改地址
  391. loop row33
  392. lea di,bit_num
  393. mov point,di ;从位置表首地址开始
  394. mov al,bl
  395. row4:
  396. rcl al,1 ;设置 V0=1
  397. mov bl,al ;保护
  398. mov dx,i8255_a ;8255 端口 A 地址
  399. out dx,al ;选中一行
  400. mov si,point ;取位置表开始地址指针
  401. mov cx,8 ;列循环次数
  402. row44:
  403. mov al,[si] ;设置 Hx=1
  404. mov dx,i8255_b ;8255 端口 B 地址
  405. out dx,al ;选中一列并显示
  406. ;call delay
  407. inc si ;修改地址
  408. loop row44
  409. lea di,bit_num
  410. mov point,di ;从位置表首地址开始
  411. mov al,bl
  412. row5:
  413. rcl al,1 ;设置 V0=1
  414. mov bl,al ;保护
  415. mov dx,i8255_a ;8255 端口 A 地址
  416. out dx,al ;选中一行
  417. mov si,point ;取位置表开始地址指针
  418. mov cx,5 ;列循环次数
  419. inc si
  420. row55:
  421. mov al,[si] ;设置 Hx=1
  422. mov dx,i8255_b ;8255 端口 B 地址
  423. out dx,al
  424. inc si ;选中一列并显示
  425. loop row55
  426. lea di,bit_num
  427. mov point,di ;从位置表首地址开始
  428. mov al,bl
  429. row6:
  430. rcl al,1 ;设置 V0=1
  431. mov bl,al ;保护
  432. mov dx,i8255_a ;8255 端口 A 地址
  433. out dx,al ;选中一行
  434. mov si,point ;取位置表开始地址指针
  435. mov cx,3 ;列循环次数
  436. inc si
  437. inc si
  438. row66:
  439. mov al,[si] ;设置 Hx=1
  440. mov dx,i8255_b ;8255 端口 B 地址
  441. out dx,al ;选中一列并显示
  442. ;call delay
  443. inc si ;修改地址
  444. loop row66
  445. lea di,bit_num
  446. mov point,di ;从位置表首地址开始
  447. mov al,bl
  448. row7:
  449. rcl al,1 ;设置 V0=1
  450. mov bl,al ;保护
  451. mov dx,i8255_a ;8255 端口 A 地址
  452. out dx,al ;选中一行
  453. mov si,point ;取位置表开始地址指针
  454. mov cx,1 ;列循环次数
  455. inc si
  456. inc si
  457. inc si
  458. row77:
  459. mov al,[si] ;设置 Hx=1
  460. mov dx,i8255_b ;8255 端口 B 地址
  461. out dx,al ;选中一列并显示
  462. ;call delay
  463. inc si ;修改地址
  464. loop row77
  465. lea di,bit_num
  466. mov point,di ;从位置表首地址开始
  467. mov al,bl
  468. pop dx
  469. pop cx
  470. pop bx
  471. pop ax
  472. ret
  473. heart_disp endp
  474. disp proc
  475. mov si,offset ledcode
  476. mov bx,si
  477. mov ch,al
  478. mov cl,4
  479. ror al,cl ;截取AL高四位并转换。
  480. and al,0fh
  481. mov ah,0
  482. add bx,ax
  483. mov al,[bx] ;获取LED显示编码
  484. mov dx,led_cs
  485. out dx,al
  486. mov al,02h
  487. inc dx
  488. nop
  489. out dx,al ;显示
  490. call delay
  491. mov al,ch
  492. and al,0fh ;截取低四位,并转换
  493. mov ah,0
  494. add si,ax
  495. mov al,[si]
  496. mov dx,led_cs
  497. out dx,al
  498. mov al,01h
  499. inc dx
  500. out dx,al ;显示
  501. call delay
  502. ret
  503. disp endp
  504. delay proc
  505. push cx
  506. mov cx,50h
  507. x1: loop x1
  508. pop cx
  509. ret
  510. delay endp
  511. code ends
  512. end start