‘壹’ 单片机8051报警器程序设计
唉,现在啊都是一群来混积分的家伙,可你知道你们那样是赚不到分的吗?像上面叫老水说的"比较简单的问题.可是程序写好了之后给你,你不会用怎么办?"说这什么话啊,既然你都说了是简单的问题,那你干吗不直接给人家程序啊,你以为你为了不起吗?你以为你那样能赚到分吗?看我的,这一百分我拿定了,只要提问人是有情有义的人.
start:MOV A,#FE (74)(FE)
loop:MOV P1,A (F5)(90)
MOV R1,#10 ;延时
DEL1:MOV R2,#00 (7A)(C8)
DEL2:MOV R3,#126 (7B)(7E)
DEL3:DJNZ R3,DEL3 (DB)(FE)
DJNZ R2,DEL2 (DA)(FA)
DJNZ R1,DEL1 (D9)(F6)
RL A (23)
LJMP LOOP (02)(40)(40)
END
‘贰’ 8051单片机编程
C语言程序员如下:
TMOD=0x01;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
TR0=1;
while(1)
{ if(TF0==1)
{
TF0=0;
P2^0=!P2^0;
TH0=(65536-500)/256;
TL0=(65536-500)%256;
}
}
‘叁’ 8051单片机数字温度计单片机的设计
-55~125度,你自己修改:
;***************WAVE-E6000/T**********************
;*MCU: AT892051 *
;*MCU-crystal: 12M *
;*Version: 01 *
;*Last Updata: 2007-5-27 *
;*Author: zhaojun *
;*Description: *
;DS18B20的读写程序,数据脚P3.4 *
;温度传感器18B20汇编程序,采用器件默认的12位转化 *
;最大转化时间750微秒,显示温度-55到+125度,显示精度*
;为0.1度,显示采用4位LED共阳显示测温值 *
;*************************************************
;单片机内存分配申明!
;*************************************************
TEMPER_L EQU 40H ;用于保存读出温度的低8位
TEMPER_H EQU 41H ;用于保存读出温度的高8位
FLAG1 EQU 38H ;是否检测到DS18B20标志位
SEC EQU 20H ;数码管个位数存放内存位置
MIN EQU 21H ;数码管十位数存放内存位置
TEMPL EQU 30H ;用于保存读出温度的低8位
TEMPH EQU 31H ;用于保存读出温度的高8位
TEMPHC EQU 32H ;温度转换寄存器低8位
TEMPLC EQU 33H ;温度转换寄存器高8位
BUF1 EQU 34H ;显示缓冲寄存器小数位
BUF2 EQU 35H ;显示缓冲寄存器个数位
BUF3 EQU 36H ;显示缓冲寄存器十数位
BUF4 EQU 37H ;显示缓冲寄存器百数位
TEMPDIN BIT P3.4 ;数据脚定义
DIN BIT P1.7 ;小数点控制
;**********************************************
ORG 0000H ;主程序入口地址
AJMP MAIN ;转主程序
ORG 0003H ;外中断0中断入口
DB 00H,00H,00H,00H,00H,00H,00H;
RETI ;跳至INTEX0执行中断服务程序
ORG 000BH ;定时器T0中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至定时器T0执行中断服务程序
ORG 0013H ;外中断1中断入口
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;跳至INTEX1执行中断服务程序
ORG 001BH ;定时器T1中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中断返回(不开中断)
ORG 0023H ;串行口中断入口地址
DB 00H,00H,00H,00H,00H,00H,00H ;
RETI ;中断返回(不开中断)
;**********************************************
;两位数码管来显示温度,显示范围00到99度,显示精度为1度
;因为12位转化时每一位的精度为0.0625度,我们不要求显示小数所以可以抛弃29H的低4位
;将28H中的低4位移入29H中的高4位,这样获得一个新字节,这个字节就是实际测量获得的温度
;无需乘于0.0625系数
;**********************************************
MAIN:
MOV SP, #50H ;
MOV P1, #0FFH ;
LPTEMP:
LCALL GET_TEMPER ;调用读温度子程序
LCALL CONVTEMP ;温度BCD码计算处理子程序
LCALL DISPBCD ;显示区BCD码温度值刷新子程序
;*************************************
LCALL DISPLAY ;调用数码管显示子程序
;*************************************
;CPL P3.0 ;
AJMP LPTEMP ;
;*************************************
; 这是DS18B20复位初始化子程序
;*************************************
INIT_1820:
SETB TEMPDIN
NOP
CLR TEMPDIN ;主机发出延时537微秒的复位低脉冲
MOV R1,#3
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB TEMPDIN ;然后拉高数据线
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB TEMPDIN,TSR3 ;等待DS18B20回应
DJNZ R0,TSR2
LJMP TSR4 ;延时
TSR3:
SETB FLAG1 ;置标志位,表示DS1820存在
;CLR P3.7 ;检查到DS18B20就点亮P3.7LED
LJMP TSR5
TSR4:
CLR FLAG1 ;清标志位,表示DS1820不存在
;CLR P3.1
LJMP TSR7
TSR5: MOV R0,#117
TSR6: DJNZ R0,TSR6 ;时序要求延时一段时间
TSR7: SETB TEMPDIN ;
RET
;****************************************
; 读出转换后的温度值
;****************************************
GET_TEMPER:
SETB TEMPDIN ;
LCALL INIT_1820 ;先复位DS18B20
JB FLAG1,TSS2
RET ;判断DS1820是否存在?若DS18B20不存在则返回
TSS2:
;CLR P3.3 ;DS18B20已经被检测到!!
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#44H ;发出温度转换命令
LCALL WRITE_1820
;*****************************************
;这里通过调用显示子程序实现延时一段时间,等待AD转换结束,12位的话750微秒
;*****************************************
LCALL DISPLAY
;*****************************************
LCALL INIT_1820 ;准备读温度前先复位
MOV A,#0CCH ;跳过ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;发出读温度命令
LCALL WRITE_1820
LCALL READ_18200 ;将读出的温度数据保存到35H/36H
RET
;*******************************************
;写DS18B20的子程序(有具体的时序要求)
;*******************************************
WRITE_1820:
MOV R2,#8 ;一共8位数据
CLR C ;
WR1:
CLR TEMPDIN ;
MOV R3,#6
DJNZ R3,$
RRC A
MOV TEMPDIN,C ;
MOV R3,#23
DJNZ R3,$
SETB TEMPDIN ;
NOP
DJNZ R2,WR1 ;
SETB TEMPDIN ;
RET
;*************************************
;处理温度BCD码子程序
;*************************************
CONVTEMP: MOV A,TEMPH ;
ANL A,#80H ;
JZ TEMPC1 ; 判断温度是否在零下?
CLR C ; 温度值补码 变成原码
MOV A,TEMPL ;
CPL A
ADD A,#01H ;
MOV TEMPL,A ;
MOV A, TEMPH ; -
CPL A ;
ADDC A,#00H ;
MOV TEMPH,A ; TEMPHC HI=符号位
MOV TEMPHC,#0BH ; 置"-"标志
SJMP TEMPC11 ;
TEMPC1: MOV TEMPHC,#0AH ; 置"+"标志
;**************************************
TEMPC11: MOV A,TEMPHC ; 计算小数位温度BCD值
SWAP A
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ; 乘0.0625
MOV DPTR,#TEMPDOTTAB ;
MOVC A,@A+DPTR ;
MOV TEMPLC,A ; TEMPLC LOW= 小数部分 BCD
;**************************************
MOV A,TEMPL ; 计算整数位温度BCD值
ANL A,#0F0H ;
SWAP A ;
MOV TEMPL,A ;
MOV A,TEMPH ;
ANL A,#0FH ;
SWAP A ;
ORL A,TEMPL ;
MOV TEMPER_L ,A ;
LCALL HEX2BCD1 ; 调用单字节十六进制转BCD子程序
;************************************
MOV TEMPL,A ;
ANL A,#0F0H ;
SWAP A ;
ORL A,TEMPHC ; TEMPHC LOW = 十位数 BCD
MOV TEMPHC,A ;
MOV A,TEMPL ;
ANL A,#0FH ;
SWAP A ; TEMPLC HI = 个位数 BCD
ORL A,TEMPLC ;
MOV TEMPLC,A ;
MOV A,R7 ;
JZ TEMPOUT ;
ANL A,#0FH ;
SWAP A ;
MOV R7,A ;
MOV A,TEMPHC ; TEMPHC HI = 百位数 BCD
ANL A,#0FH ;
ORL A,R7 ;
MOV TEMPHC,A ;
TEMPOUT: RET ;
;**************************************
;小数部分分码表
;**************************************
TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H
DB 06H,07H,08H,08H,09H,09H ;
;**************************************
;显示区 BCD 码温度值刷新子程序
;**************************************
DISPBCD: MOV A,TEMPLC ; 温度数据移入显示寄存器
ANL A,#0FH ;
MOV BUF1,A ; 显示小数
MOV A,TEMPLC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF2,A ; 显示个位
MOV A,TEMPHC ;
ANL A,#0FH ;
MOV BUF3,A ; 显示十位
MOV A,TEMPHC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF4,A ; 显示百位
MOV A,TEMPHC ;
ANL A,#0F0H ;
CJNE A,#10H,DISPBCD0 ; 百位数=0?
SJMP DISPOUT ;
DISPBCD0:
MOV A, TEMPHC ;
ANL A, #0FH ;
JNZ DISPOUT ; 十位数是0?
MOV A,TEMPHC ;
SWAP A ;
ANL A,#0FH ;
MOV BUF4,0AH ; 符号位不显示
MOV BUF3,A ; 十位数显示符号
DISPOUT: RET ;
;*************************************
;单字节十六进制转BCD
;*************************************
HEX2BCD1:MOV B,#64H ; 十六进制 ->BCD
DIV AB ; B=A%100
MOV R7,A ; R7=百位数
MOV A,#0AH ;
XCH A,B ;
DIV AB ; B=A%B
SWAP A ;
ORL A,B ;
RET ;
;*************************************
; Calculate CRC-8 Values, Uses The
;CCITT-8 Polynomial,Expressed As
; X^8+X^5+X^4+1
;*************************************
CRC8CAL: PUSH ACC ;
MOV R7,#08H ; Number Bits Byte
CRC8LOOP1:
XRL A,B ; Calculate CRC
RRC A ; Move T0 Carry
MOV A,B ; Get The Last CRC Value
JNC CRC8LOOP2 ; Skip If Data==0
XRL A,#18H ; Update The CRC Value
CRC8LOOP2:
RRC A ; Position The New CRC
MOV B,A ; Store The New CRC
POP ACC ; Get The Remaining Bits
RR A ; Possition The Next Bit
PUSH ACC ; Save The Remaining Bits
DJNZ R7,CRC8LOOP1 ; Repeat For 9 Bits
POP ACC ;
RET ;
;******************************************
;读DS18B20的程序,从DS18B20中读出9个字节数据
;开始的两个字节为温度数据
;******************************************
READ_18200:
MOV R4,#9 ; 将温度高位和低位从DS18B20中读出
MOV R1,#TEMPER_L ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
MOV B, #00H ;
;************************************
RE00:
MOV R2,#8 ; 数据一共有8位
RE01:
CLR C
SETB TEMPDIN ;
NOP
NOP
CLR TEMPDIN ;
NOP
NOP
NOP
SETB TEMPDIN ;
MOV R3,#9
RE10:
DJNZ R3,RE10 ;
MOV C,TEMPDIN ;
MOV R3,#23
RE20:
DJNZ R3,RE20 ;
RRC A
DJNZ R2,RE01 ;
;************************************
MOV @R1,A ;
INC R1 ;
LCALL CRC8CAL ;
DJNZ R4,RE00 ;
MOV A,B ;
JNZ READ_OUT ;
MOV TEMPL,TEMPER_L ;
MOV TEMPH,TEMPER_H ;
READ_OUT: RET
;*****************************************
;显示子程序
;*****************************************
DISPLAY:
MOV DPTR,#NUMTAB ; 指定查表启始地址
MOV R0,#4
DP11: MOV R1,#250 ; 显示1000次
DPLP: SETB P1.7
MOV A,BUF1 ; 取小位数
MOVC A,@A+DPTR ; 查小位数的7段代码
MOV P1,A ; 送出小位的7段代码
CLR P3.0 ; 开小位显示
ACALL DL1ms ; 显示1ms
SETB P3.0 ;
MOV A,BUF2 ; 取个位数
MOVC A,@A+DPTR ; 查个位数的7段代码
MOV P1,A ; 送出个位的7段代码
CLR P1.7
CLR P3.1 ; 开个位显示
ACALL DL1ms ; 显示1ms
SETB P3.1 ;
SETB P1.7
MOV A,BUF3 ; 取十位数
MOVC A,@A+DPTR ; 查十位数的7段代码
MOV P1,A ; 送出十位的7段代码
CLR P3.2 ; 开十位显示
ACALL DL1ms ; 显示1ms
SETB P3.2 ;
SETB P1.7
MOV A,BUF4 ; 取百位数
MOVC A,@A+DPTR ; 查百位数的7段代码
MOV P1,A ; 送出百位的7段代码
CLR P3.3 ; 开百位显示
ACALL DL1ms ; 显示1ms
SETB P3.3 ;
DJNZ R1,DPLP ; 250次没完循环
DJNZ R0,DP11 ; 4个100次没完循环
RET
;****************************************
;0.2MS延时(按12MHZ算)
;****************************************
DL1MS: MOV R7,#100
DJNZ R7,$
RET
;****************************************
;7段数码管0~9数字的共阳显示代码
;****************************************
NUMTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH ;
; "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-"
;****************************************
END
‘肆’ 简述8051单片机定时计数器编程的基本步骤
设置定时计数器的工作方式。
给定时器赋初始值:THx 和TLx;
允许定时器中断;
允许全局中断;
启动定制器;
中断函数编写(这个是目的,定时计数最终要干什么?)
‘伍’ 单片机设计技巧:如何实现8051模块化编程
最佳答案第一阶段:是先浏览教科书里的硬件部分,大至了解单片机的硬件结构。如ROM、RAM、地址、I/O口等,以及看一些厂家的MCU资料(Data Sheet),来加强MCU所提供各项资源的印象。呵呵,还是得先看书。看不懂的就问老师,问知道的人。可以理解,我以前在学校也是对单片机一点儿也不理解,其实简单点的说单片机就是一块集成芯片,但是不同的地方就是可以通过编程来改变其引脚的电平高低。大二学了数电没有?学过数点你就会理解高低电平的含义。另外,大一的时候学过计算机基础了吧。你可以用计算机的原理来理解单片机。比如说 ROM 其实就像计算机的硬盘一样,是用来装东西的,装你运行的程序。
第二阶段:就是了解二进位数字、十六进位数和软件方面的内容。尽管有很多高级语言可用于单片机的编程,但我觉得初学还是以汇编语言为好,更有利于和硬件结合,掌握硬件结构。知道汇编语言、机器语言、指令、 程序等概念后,从MOV指令开始,学习汇编语言和编程,在此如51的MCU汇编语言系统有11条指令,简单又好理解它们怎样和硬件联系,更有助于一般学习单片机的指令整合与运用.因此其方法可先了 解几条基本的MOV指令和它的机器语言,大致建立起单片机的硬件和软件概念,来知道单片机的硬件是由指令控制指挥的。
第三阶段按照编程环境的使用手册,熟悉使用编程环境。现在的编程环境一般都和电脑相连,只要具备基本电脑知识的人都可很快掌握操作步骤。
第四阶段是依靠实验板,学习掌握单片机的汇编语言指令系统和简单编程。同时和前面所学硬件知识结合组装,起到主学软件,巩固硬件的双重作用。
开始 时可用别人编的简单程式在实验板上进行验证、分析,主要是熟悉该学习方法,在应用方面主要针对单片机I/O各项接口的使用,如A/D,D/A,PWM输出的应用,LCD与VFD的控制,以及如何规范各项串行输出入口的通讯协定等,对其所控制的各项元器件须先分析驱动能力,如电流电压问题等。
汇编语言熟悉后,建议尽快学习C语言的编程,毕竟C语言有功能丰富的库函数、运算速度快、编译效率高、有良好的可移植性,而且可以直接实现对系统硬件的控制。C语言是一种结构化程序设计语言,它支持当前程序设计中广泛采用的由顶向下结构化程序设计技术。此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化 程序设计方法提供了有力的保障。因此,使用C语言进行程序设计已成为软件 开发的一个主流。用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充,从而研制出规模更大、性能更完备的系统。
另外,我觉得一开始很多的概念可能你都不怎么理解的,光看书也难理解,还得多问人,还有找一样好的仿真软件,一定要会用。在学指令的时候一条一条的验证,那样才会理解。
就比如一个非常简单的 REG 0000H
AJMP 30H
MOV 20H #05H
END
看看仿真软件的寄存器,内部数据存储器里面的数据有什么改变。当你看到20H单元上的值变成了5,你就知道 MOV 20H #05H 的含义。但是光看书,可能就理解不出来。
‘陆’ 已知8051单片机的fosc=12MHz,用T1 定时,试编程由P1.2 和P1.3 引脚分别输出周期为2ms 和500μs 的方波
定时器T1定时250μs,工作方式设置为方式2,用TL1作为8位定时器,产生250μs的定时,定时初值X为:X=2^8-(12* 10^6* 250 * 10^(-6))/12=6
TH1=TL1=6H,TMOD=20H
源代码如下:
MOV TMOD,#20H
MOVTH1,#06H
MOVTL1,#06H
SETB TR1
DS1_RPTA:
MOVR2,#04H
DS1_RPTB:
JNB TF1,$
CLR TF1
CPL P1.3
DJNZ R2,DS1_RPTB
CPL P1.2
LJMP DS1_RPTA
51单片机中有两个定时器T0和T1,分别是由两个8位的专用寄存器组成,即定时/计数器T0由TH0和TL0组成,T1由TH1和TL1组成。单片机中的定时器溢出时申请的中断,达到计时或计数的目的。并使用定时控制寄存器控制它。其中的:
TF1:定时器1溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除。或用软件清除。
TF0:定时器0溢出标志。定时/计数器溢出时由硬件置位。中断处理时由硬件清除,或用软件清除。
(6)8051单片机程序设计扩展阅读
定时器工作的流程:
以51为例用定时器0方式一产生50毫秒的定时:
1、确定使用哪个定时器,使用哪种方式,通过TMOD设置,TMOD的低四位是设置定时器0的,高四位是用来设置定时器1的,其中的M0,M1是用来设置定时器工作在哪种方式,GATE一般用不要设置,C/T是选择计数模式还是定时模式的,如:TMOD = 0X01,就说明定时器0工作在方式1。
2、设置定时的时间,用定时器定时,如:50毫秒,可以用这种方式TH0 = (65535 - 50000) / 256,TL0 = (65535 - 50000) % 256;可以这样理解:因为这是定时器的初值,也就是说计数脉冲就是在这个数的基础上向上递增,到达65535后就溢出产生中断。
3、打开中断,使用IE寄存器,首先打开总中断EA = 1,这一步是所有中断所必须的,然后打开定时器0中断,ET0 =1。
4、这时准备工作结束,启动定时器,使用TCON寄存器,TR0 = 1,实现了一个50毫秒的定时。
‘柒’ 单片机8051基础编程
51程序库
http://www.programfan.com/blog/article.asp?id=19116
http://workingon.bokee.com/viewdiary.12218674.html
MCS-51单片机实用子程序库
http://blog.tom.com/fangqidong/article/416.html
‘捌’ 8051单片机程序设计求助!在线等。。。。
anykey:
mov r0,a
cjne r0,#00h,next
ret
next : cjne r0,#40h,next1
mov a,th0
add a,#5
mov th0,a
ret
next1: cjne r0,#80h,next2
mov a,th0
subb a,#5
mov th0,a
ret
main: mov tmod ,#02h
mov ie ,#82h
mov th0, #(256-125)
mov tl0, #(256-125)
setb tr0
loop: lcall anykey
ajmp loop
‘玖’ 8051单片机汇编程序请教
你的第二次修改,还有一处不足:
……
;CLR C
MOV DPTR,#TABLE
LOOP:
CLR A ;这里少了一句,下面每次读出的,
;就不知道是什么了
MOVC A,@A+DPTR
JNZ CONT_P
INC R2
SJMP NEXT
……
可以正常计数的程序如下。
;=========================================
ORG 0H
MOV A,#00H
MOV R2,A
MOV R3,A
MOV R4,A
MOV R6,A
MOV R5,#40
;CLR C
MOV DPTR,#TABLE
LOOP:
CLR A
MOVC A,@A+DPTR
JNZ CONT_P
; CJNE A,#00H,CONT_P
INC R2
SJMP NEXT
CONT_P:
JB ACC.7, CONT_N
INC R3
SJMP NEXT
CONT_N:
INC R4
NEXT:
INC DPTR
DJNZ R5, LOOP
MOV P0,R4
SJMP $
; 实际个数 保存单元 统计个数
;零个数 14 R2 21
;正数个数 19 R3 19
;负数个数: 7 R4 0
;其实是零和负数没有分开统计,请高手指教一下,谢谢!
ORG 400H
TABLE:
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 01H, 15H, 22H,0FFH, 00H, 02H, 09H,0F9H, 00H, 00H
DB 02H, 05H, 00H,0FFH, 26H, 34H, 00H, 00H, 00H, 00H
END