Tag Archives: 单片机

蓝牙技术文档

BC04蓝牙模块

产品描述

    采用世界领先的蓝牙芯片供应商CSR的BlueCore4-Ext芯片,完全兼容蓝牙2.0规范,支持数据和语音传输,最高可支持3M调制模式。


型号:BTM0604C2P


型号:BTM0504C2X

应用

•PC、PDA

•计算机附件(CF卡、USB适配器、PCMCIA、RS232适配器等)

•鼠标、键盘、操作杆

•无绳电话

•传真、打印机适配器

•数码相机

•蓝牙网关

•GPS

特点

•工作频段2.40GHz~2.48GHz

•完全兼容蓝牙2.0规范

•支持EDR(增强速率),2M/3M调制模式。

•2级功率输出

•支持软件升级

•支持微微网,最多可同时连接7个从设备

•支持散射网(Scatternet)

•USB2.0及UART主机界面

•PCM音频界面

•电压范围:2.7V-3.6V

•正常供电电压:3.3V

•内置8兆Flash Memory

•支持Park,Sniff,Hold及深度休眠模式 .

•尺寸:27.0×14.5×1.8mm (不带天线)

金瓯BC04蓝牙模块使用手册 下载

 

单片机做的计算器完成了!

这次用的是单片机的实验板做的。
一些设备介绍:
[HR][/HR]
单片机:AT89S52
键盘:4×4键盘,一个中断按键,一个复位按键。
显示:4位LED数码管显示。
声音:普通蜂鸣器。
[HR][/HR]
程序主要思想:
用有限的按键显示16进制的简单计算器,实现16位的16进制数的加减乘除计算。要求可以连续计算,把结果做为下一次计算的初值。
要点:
键盘:线反转法键盘扫描,并用查表法获取对应键值。
显示:用多位循环显示来完成多位LED的显示。
声音主要用来做操作提示用。
[HR][/HR]
程序详解:
加法子程序:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ADD16:
;16位加法,在本例里,全部的加法都用16位加法完成,超过16位的进位直接丢弃
MOV A,NUM2
ADD A,NUM4
MOV RES2,A ;低位相加
;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1
ADDC A,NUM3
MOV RES1,A ;高位相加
RET

减法子程序:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB16:
;16位减法

MOV A,NUM2 ;被减数低位
CLR C ;清借位位
SUBB A,NUM4 ;低位相减
MOV RES2,A ;结果高位
;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1
SUBB A,NUM3
MOV RES1,A ;结果低位

RET

乘法子程序:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MUL16:
;16位乘法。注:这里要用大数乘以小数!也就是如果有16位的数出现时,用8×16位,不能用16×8位

MOV A,NUM2 ;16位数的低8位
MOV B,NUM4 ;乘数
MUL AB
MOV R1,A ;积的低8位
MOV R2,B ;积的高8位
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1 ;16位数的高8位
MOV B,NUM4 ;乘数
MUL AB
MOV R3,A ;LOW
MOV R4,B ;HIGHT
;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R2
ADD A,R3 ;
MOV RES1,A ;结果高位
MOV RES2,R1 ;结果低位

RET

除法子程序:
(十六位除以八位的)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIV16:
;八位八位的来(NUM1 NUM2)除(NUM4)
;先高八位除
MOV A,NUM1
MOV B,NUM4
DIV AB
MOV R1,A ;1
;;;;;;;;;;;;;;;;;;
MOV A,#0F0H
ANL A,NUM2 ;取高四位
ORL A,B ;余数与低八位的高四位合并
SWAP A
MOV R6,A
;;;;;;;;;;;;;;;;;;
MOV A,R6
MOV B,NUM4
DIV AB
MOV R2,A ;2
;;;;;;;;;;;;;;;;;;;
MOV A,#0FH
ANL A,NUM2 ;取低四位
SWAP A
ORL A,B ;余数与低八位的低四位再合并!
SWAP A
MOV R7,A
;;;;;;;;;;;;;;;;;;;
MOV A,R7
MOV B,NUM4
DIV AB
MOV R3,A ;3
;;;;;;;;;;;;;;;;;;;;;;
MOV A,R2
SWAP A
ORL A,R3
;;;;;;;;;;;;;;;;;;;;;;;;
MOV RES1,R1 ;商的高八位
MOV RES2,A ;商的低八位
RET

(十六位除以十位的)

DIV16:
MOV A,R5
JNZ BEGIN
MOV A,R4
JZ OVER

BEGIN: MOV A,R7
JNZ BEGIN1
MOV A,R6
JNZ BEGIN1
RET
BEGIN1: CLR A
MOV R2,A
MOV R3,A
MOV R1,#10H
DIV1: CLR C
MOV A,R6
RLC A
MOV R6,A
MOV A,R7
RLC A
MOV R7,A
MOV A,R2
RLC A
MOV R2,A
MOV A,R3
RLC A
MOV R3,A
DIV2: MOV A,R2
SUBB A,R4
MOV R0,A
MOV A,R3
SUBB A,R5
JC NEXT
INC R6
MOV R3,A
MOV A,R0
MOV R2,A
NEXT: DJNZ R1,DIV1
AJMP NOOVER
ADD1: MOV A,R6
ADD A,#01H
MOV R6,A
MOV A,R7
ADDC A,#00H
MOV R7,A
NOOVER: MOV OVER,#00H
RET
OVER: MOV OVER,#0FFH
RET

显示:

DISPLAY: MOV R0,IS_OP
CJNE R0,#0H,BACK
MOV A,LED1 ;函数功能: 显示一位
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.7
ACALL DLMS
SETB P2.7
;
MOV A,LED2
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.6
ACALL DLMS
SETB P2.6
;
MOV A,LED3
ACALL GETLED_CODE
MOV P0,A
CLR P2.5
ACALL DLMS
SETB P2.5
;
MOV A,LED4
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.4
ACALL DLMS
SETB P2.4
RET

键盘检测:

KEY_DT: ACALL DISPLAY
ACALL SC_L ;开始列扫描
CJNE A,#0FH,KEY_01 ;如果有按键跳到KEY_01
AJMP KEY_DT
KEY_01: MOV R6,#0AH
KEY_02: ACALL DISPLAY
DJNZ R6,KEY_02
ACALL SC_L
CJNE A,#0FH,KEY_03
AJMP KEY_DT
KEY_03: MOV B,A
ACALL SC_H
ADD A,B
MOV KEY1,A
ACALL K_CODE
ACALL K_DSPL
MOV TEMP_KEY,A
MOV R6,#0AH
KEY_04: ACALL DISPLAY
DJNZ R6,KEY_04
MOV A,TEMP_KEY
BACK: RET
SC_L: MOV A,#0FH
MOV P1,A
MOV A,P1
ANL A,#0FH
RET
SC_H: MOV A,#0F0H
MOV P1,A
MOV A,P1
ANL A,#0F0H
RET
K_CODE: MOV A,#00H
MOV DPTR,#KCODE
K_CD0: MOV B,A
MOVC A,@A+DPTR
CJNE A,KEY1,K_CD1
AJMP K_CD2
K_CD1: MOV A,B
INC ACC
CJNE A,#10H,K_CD0
K_CD2: MOV A,B
RET
K_DSPL: CJNE A,#10H,K_DSP1
AJMP K_BACK
K_DSP1: MOV LED1,LED2
MOV LED2,LED3
MOV LED3,LED4
MOV LED4,A

K_BACK: RET
KCODE: DB 0E7H ,0D7H ,0B7H ,077H
DB 0EBH ,0DBH ,0BBH ,07BH
DB 0EDH ,0DDH ,0BDH ,07DH
DB 0EEH ,0DEH ,0BEH ,07EH

GETLED_CODE: MOV DPTR ,#LED_CODE
MOVC A ,@A+DPTR
RET

LED_CODE: DB 0D7H, 14H ,0CDH ; 0 1 2
DB 5DH, 1EH , 5BH ; 3 4 5
DB 0DBH , 15H,0DFH ; 6 7 8
DB 5FH , 9FH,0DAH ; 9 A B
DB 0C3H,0DCH, 0CBH ; C D E
DB 8BH,98H,8FH ; F N P
DB 0D6H,00H ; V NONE

GETCODE: MOV DPTR,#LED_CODE
MOVC A,@A+DPTR
RET

完整的程序:

;定义一些程序保留的内存地址
NUM1 EQU 30H ;高
NUM2 EQU 31H ;低
NUM3 EQU 32H ;高
NUM4 EQU 33H ;低
;;;;;;;;;;;;;;;
RES1 EQU 34H
RES2 EQU 35H
;;;;;;;;;;;;;;;
DISP1 EQU 36H
DISP2 EQU 37H
;;;;;;;;;;;;;;;
KEY1 EQU 38H
KEY2 EQU 39H
KEY3 EQU 40H
KEY4 EQU 41H
;;;;;;;;;;;;;;;;;;;
LED1 EQU 42H
LED2 EQU 43H
LED3 EQU 44H
LED4 EQU 45H
;;;;;;;;;;;;;;;;;;;;;;
TEMP_KEY EQU 46H
OP EQU 47H
IS_OP EQU 48H

;AJMP F
ACALL CLEAR
AJMP CALC
;需要的子程序

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ADD16:
;16位加法,在本例里,全部的加法都用16位加法完成,超过16位的进位直接丢弃
MOV A,NUM2
ADD A,NUM4
MOV RES2,A ;低位相加
;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1
ADDC A,NUM3
MOV RES1,A ;高位相加
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
SUB16:
;16位减法

MOV A,NUM2 ;被减数低位
CLR C ;清借位位
SUBB A,NUM4 ;低位相减
MOV RES2,A ;结果高位
;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1
SUBB A,NUM3
MOV RES1,A ;结果低位

RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MUL16:
;16位乘法。注:这里要用大数乘以小数!也就是如果有16位的数出现时,用8×16位,不能用16×8位

MOV A,NUM2 ;16位数的低8位
MOV B,NUM4 ;乘数
MUL AB
MOV R1,A ;积的低8位
MOV R2,B ;积的高8位
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,NUM1 ;16位数的高8位
MOV B,NUM4 ;乘数
MUL AB
MOV R3,A ;LOW
MOV R4,B ;HIGHT
;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOV A,R2
ADD A,R3 ;
MOV RES1,A ;结果高位
MOV RES2,R1 ;结果低位

RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DIV16:
; 八位八位的来(NUM1 NUM2)除(NUM4)
; 先高八位除
; MOV A,NUM1
; MOV B,NUM4
; DIV AB
; MOV R1,A ;1
;;;;;;;;;;;;;;;;;;;
; MOV A,#0F0H
; ANL A,NUM2 ;取高四位
; ORL A,B ;余数与低八位的高四位合并
; SWAP A
; MOV R6,A
;;;;;;;;;;;;;;;;;;;
; MOV A,R6
; MOV B,NUM4
; DIV AB
; MOV R2,A ;2
;;;;;;;;;;;;;;;;;;;;
; MOV A,#0FH
; ANL A,NUM2 ;取低四位
; SWAP A
; ORL A,B ;余数与低八位的低四位再合并!
; SWAP A
; MOV R7,A
;;;;;;;;;;;;;;;;;;;;
; MOV A,R7
; MOV B,NUM4
; DIV AB
; MOV R3,A ;3
;;;;;;;;;;;;;;;;;;;;;;;
; MOV A,R2
; SWAP A
; ORL A,R3
;;;;;;;;;;;;;;;;;;;;;;;;;
; MOV RES1,R1 ;商的高八位
; MOV RES2,A ;商的低八位
; RET
DIV16:
MOV A,R5
JNZ BEGIN
MOV A,R4
JZ OVER

BEGIN: MOV A,R7
JNZ BEGIN1
MOV A,R6
JNZ BEGIN1
RET
BEGIN1: CLR A
MOV R2,A
MOV R3,A
MOV R1,#10H
DIV1: CLR C
MOV A,R6
RLC A
MOV R6,A
MOV A,R7
RLC A
MOV R7,A
MOV A,R2
RLC A
MOV R2,A
MOV A,R3
RLC A
MOV R3,A
DIV2: MOV A,R2
SUBB A,R4
MOV R0,A
MOV A,R3
SUBB A,R5
JC NEXT
INC R6
MOV R3,A
MOV A,R0
MOV R2,A
NEXT: DJNZ R1,DIV1
AJMP NOOVER
ADD1: MOV A,R6
ADD A,#01H
MOV R6,A
MOV A,R7
ADDC A,#00H
MOV R7,A
NOOVER: MOV OVER,#00H
RET
OVER: MOV OVER,#0FFH
RET

DISPSUB: ACALL KEY_DT
DJNZ R3,DISPSUB ; 限制输入4个,多余的不接受

AJMP WAIT_OP
DISPLAY: MOV R0,IS_OP
CJNE R0,#0H,BACK
MOV A,LED1 ;函数功能: 显示一位
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.7
ACALL DLMS
SETB P2.7
;
MOV A,LED2
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.6
ACALL DLMS
SETB P2.6
;
MOV A,LED3
ACALL GETLED_CODE
MOV P0,A
CLR P2.5
ACALL DLMS
SETB P2.5
;
MOV A,LED4
ACALL GETLED_CODE
MOV P0 ,A
CLR P2.4
ACALL DLMS
SETB P2.4
RET

KEY_DT: ACALL DISPLAY
ACALL SC_L ;开始列扫描
CJNE A,#0FH,KEY_01 ;如果有按键跳到KEY_01
AJMP KEY_DT
KEY_01: MOV R6,#0AH
KEY_02: ACALL DISPLAY
DJNZ R6,KEY_02
ACALL SC_L
CJNE A,#0FH,KEY_03
AJMP KEY_DT
KEY_03: MOV B,A
ACALL SC_H
ADD A,B
MOV KEY1,A
ACALL K_CODE
ACALL K_DSPL
MOV TEMP_KEY,A
MOV R6,#0AH
KEY_04: ACALL DISPLAY
DJNZ R6,KEY_04
MOV A,TEMP_KEY
BACK: RET
SC_L: MOV A,#0FH
MOV P1,A
MOV A,P1
ANL A,#0FH
RET
SC_H: MOV A,#0F0H
MOV P1,A
MOV A,P1
ANL A,#0F0H
RET
K_CODE: MOV A,#00H
MOV DPTR,#KCODE
K_CD0: MOV B,A
MOVC A,@A+DPTR
CJNE A,KEY1,K_CD1
AJMP K_CD2
K_CD1: MOV A,B
INC ACC
CJNE A,#10H,K_CD0
K_CD2: MOV A,B
RET
K_DSPL: CJNE A,#10H,K_DSP1
AJMP K_BACK
K_DSP1: MOV LED1,LED2
MOV LED2,LED3
MOV LED3,LED4
MOV LED4,A

K_BACK: RET
KCODE: DB 0E7H ,0D7H ,0B7H ,077H
DB 0EBH ,0DBH ,0BBH ,07BH
DB 0EDH ,0DDH ,0BDH ,07DH
DB 0EEH ,0DEH ,0BEH ,07EH

GETLED_CODE: MOV DPTR ,#LED_CODE
MOVC A ,@A+DPTR
RET

LED_CODE: DB 0D7H, 14H ,0CDH ; 0 1 2
DB 5DH, 1EH , 5BH ; 3 4 5
DB 0DBH , 15H,0DFH ; 6 7 8
DB 5FH , 9FH,0DAH ; 9 A B
DB 0C3H,0DCH, 0CBH ; C D E
DB 8BH,98H,8FH ; F N P
DB 0D6H,00H ; V NONE

GETCODE: MOV DPTR,#LED_CODE
MOVC A,@A+DPTR
RET

CLEAR:
MOV LED1,#13H
MOV LED2,#13H
MOV LED3,#13H
MOV LED4,#13H
ACALL DISPLAY
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;延时
DLMS: MOV R5,#4
DL01: MOV R7,#250
DL02: DJNZ R7,DL02
DJNZ R5,DL01
RET
;;;延时255ms
DL255MS: MOV R6,#0FFH
ACALL DLMS
DJNZ R6,DL255MS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
READ_NUM_KEY:
;读取一次数字输入,必须输入四个
;ACALL CLEAR
ACALL KEY_DT
MOV R1,A
ACALL KEY_DT
MOV R2,A
ACALL KEY_DT
MOV R3,A
ACALL KEY_DT
MOV R4,A
RET
;;;;;;;;;;;;;;;
WAIT_OP:
ACALL KEY_DT
MOV OP,A
OP0:
CJNE A,#0,OP1 ;+
ACALL BELL
RET
OP1:
CJNE A,#1,OP2 ;-
ACALL BELL
RET
OP2:
CJNE A,#2,OP3 ;*
ACALL BELL
RET
OP3:
CJNE A,#3,NONE ;/
ACALL BELL
RET
NONE:
AJMP WAIT_OP
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;响铃
BELL:
CLR P3.7
MOV R3,#02FH
BELL_DL:ACALL DLMS
DJNZ R3,BELL_DL
SETB P3.7
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;转换成数值
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;开始计算
DO_CALC:
MOV A,OP
CALC0:
CJNE A,#0h,CALC1 ;+
ACALL ADD16
RET
CALC1:
CJNE A,#1h,CALC2 ;-
ACALL SUB16
RET
CALC2:
CJNE A,#2h,CALC3 ;*
ACALL MUL16
RET
CALC3:
;/

MOV R7,NUM1
MOV R6,NUM2
MOV R5,NUM3
MOV R4,NUM4
ACALL DIV16

MOV RES1,R7
MOV RES2,R6
RET
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 显示结果
ECHO_RES:
;MOV RES1,#67H
;MOV RES2,#89H
MOV A,RES1
SWAP A ;高低位交换
ANL A,#0FH ;取低位,就是刚才的高4位
MOV LED1,A
MOV A,RES1
ANL A,#0FH
MOV LED2,A
;
MOV A,RES2
SWAP A
ANL A,#0FH
MOV LED3,A
MOV A,RES2
ANL A,#0FH
MOV LED4,A
ACALL DISPLAY
;AJMP ECHO_RES
RET
CALC:
; testing.!
ACALL READ_NUM_KEY
MOV A,R1
SWAP A
ORL A,R2
MOV NUM1,A ;第一个数
MOV A,R3
SWAP A
ORL A,R4
MOV NUM2,A ;第二个数
;;;;;;;;;;;;;;;;;;;;;;;;

;
CONTINUE:
ACALL WAIT_OP
ACALL CLEAR
ACALL BELL
ACALL READ_NUM_KEY
MOV R4,A
MOV A,R1
SWAP A
ORL A,R2
MOV NUM3,A ;第三个数
MOV A,R3
SWAP A
ORL A,R4
MOV NUM4,A ;第四个数

ACALL DO_CALC ;!!!开始计算

ACALL KEY_DT
ACALL BELL
ACALL ECHO_RES
ACALL KEY_DT
ACALL CLEAR
MOV NUM1,RES1
MOV NUM2,RES2
AJMP CONTINUE
RET

[URL=http://blog.eaxi.com/upload/最终程序.rar]最终程序.rar[/URL]