找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4656|回复: 9
收起左侧

制作一个蓝牙模块设置器 附单片机代码

  [复制链接]
ID:283954 发表于 2020-11-5 00:08 | 显示全部楼层 |阅读模式
从开始学单片机到现在,我买了整十种蓝牙模块来试,开始的HC-05算是入门,其设置非常麻烦,配对要很多过程,而且传送距离很短,后来还买了JDY-08,配对是比较简单了,但发现配对后发出的数据若含有“AT”会被吃掉,显然是蓝牙内部软件有虫,接着还买了很多其他款来试,才发现有些只有从机,没有主机,而其他型号的主机不能与之配对,折腾了好久这才找到一款小公司生产的,从机和主机是分开的,而且能一键配对,非常满意,价钱稍贵无所谓,但担心有一天他们忽然说不卖了,那麻烦就大了,得找个后备轮胎,找呀找就意外找到了一款很普通的JDY-18,是主从一体机,在其说明书里有说能一键配对,但必须先设定参数,买回来后经过手工设定还行,但每次要设定一个模块都要再翻看说明书,很麻烦花时间,于是就想用单片制作一个设定器,把设置命令都写在里面,把模块插上主板后一开电,就自动设置好了。

刚好我的有十来片废弃不用的STC12LE5A60S2板子,有UART1和UART2的插座,非常合用,于是这事就搞成了:

bt.jpg

软件是从已有的MIDI发送软件简化而来,把所有没用到的程序全部删除,没有用到的寄存器全部删除,向量表只留下需要用的,这下软件变得干净,力求做到上面没有一条命令是多余的。

接着是添加新的代码,通过串口2向蓝牙模块发生命令后,模块会有响应的字符,必须把字符放在缓冲区再发送到串口1,用STC ISP观看,这事花了不少时间,因为以前未曾做过。开发过程中发现必须关闭串口1的接收功能,否则向串口2发送字符后也能让串口1产生接收中断,在同样的缓冲区留下字符,但只在每一次发送第一串字符后,接下来就不会了,原因不明,也没时间去追究,能用就好。

JDY-18这个一键配对并绑定是能用的,但设置完毕后并不能即刻配对,必须拔进拔出几次开机等好几秒才能与从机配对,而且接通后会产生一堆提示的字符,你的应用软件必须能够不受这些字符的干扰,那款较贵的,一按配对钮,不到一秒就通了,而且完全静默,真是一分钱一分货呀,但作为备用轮胎还是行的。

单片机汇编语言代码:


;JDY-18一键绑定连接最近的从机蓝牙
;起始串口波特率9600  测试模块: AT+RESET,响应:OK
;第一步配置主机:AT+ROLE1  响应:+ROLE=1 OK
;第二步配置类型:AT+CLSSF0 响应:+CLSS=F0 OK
;第三步设波特率:AT+BAUD6  响应:+BAUD=6 OK(1-1200 2=2400 3=4800 4=9600 5=19200 6=38400 7=57600 8=115200 9=230400)
;第三步模块重启:AT+RESET  响应:OK

;将JDY-18第18脚IO3连接MCU引脚上(P1.4),给一个下降沿信号,模块将主动搜索附近最近从机BLE蓝牙,
;并自动绑定连接信号最强的BLE设备,下次重新上电,模块会自动与之前已经连接的从自动连接,
;如需要重新连接新的BLE从机,通过重复以上步骤即可

HEADBUFFER EQU 80H
LASTBUFFER EQU 0FFH
BRT EQU 09CH      
S2CON EQU 9AH          ;S2SM0, S2SM1, S2SM2, S2REN, S2TB8, S2RB8, S2TI, S2RI
IE2 EQU 0AFH           ;X, X, X, X, X, X, ESPI, ES2
IP2 EQU 0B5H           ;X,X,X,X,X,X,PSPS,PS2 PSPI=PARITY OF SPI
S2BUF EQU 9BH
P4 EQU 0C0H
P5 EQU 0C8H
AUXR EQU 8EH
AUXR2 EQU 0A2H

ORG 0000H      ;中断向量表
LJMP MAIN
ORG 0023H
LJMP UART1     ;UART1 RECEIVED INTERRUPT
ORG 0043H
LJMP UART2     ;UART2 RECEIVED INTERRUPT

ORG 0100H     

MAIN:

MOV AUXR, #11111100B ;T0X12,T1X12,UART_M0X6,BRTRUN,S2SMOD,BRTX12,EXTRAM,S1BRS(IF 0 USE T1. 1=USE BRT)
MOV TMOD, #00100010B ;TIMER0, TIMER1 AS MOD2(8 BYTE AUTO RELOAD TIMER)
                     ;GATE, C/T,M1,M0(T1) GATE, C/T,M1,MO(T0
MOV PCON, #10000000B ;THIS DOUBLE THE BRT AND T0 T1 RATE

LCALL INITIAL_UART1  ;USE T1 AS SERIAL BAUD GENERATE FOR UART1
LCALL INITIAL_UART2  ;USE BRT AS SERIAL BAUD GENERATE FOR UART2
SETB EA

TEST:
MOV R0, #HEADBUFFER
MOV R1, #HEADBUFFER

TEST1:
LCALL DELAY2         ;DELAY FOR JDY INIT
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2

CLR P2.5             ;LED ON
LCALL RESET
LCALL DELAY2
LCALL VERSION
LCALL DELAY2
LCALL STAT
LCALL DELAY2
LCALL ROLE1
LCALL DELAY2
LCALL CLSSF0
LCALL DELAY2
LCALL BAUD6
LCALL DELAY2         
LCALL INITIAL_UART2_38400
LCALL DELAY2
LCALL RESET
LCALL DELAY2         
LCALL PAIR
LCALL DELAY2

LED:
MOV A, R0
XRL A, R1
JZ LED2  

LEDDO:            ;   START DOING JOB HERE
MOVX A, @R0
LCALL SENTONEBYTE1
CJNE R0, #LASTBUFFER, NEXTSENT1
MOV R0, #HEADBUFFER
JMP NEXTSENT2
NEXTSENT1:
INC R0  ;POINT TO NEXT BUFFER
NEXTSENT2:
JMP LED

LED2:
;LCALL MARKZZ
LED3:
LCALL  DELAY2
JMP LED3

INITIAL_UART1:  
MOV SCON, #01000000B   ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK SM0,SM1,SM2,REN,TB8,RB8,TI,RI
MOV TL1, #136          ;219(18M= 2usx16=32US) 226=38400 196=19200 136=9600
MOV TH1, #136
SETB TR1               ;RUN TIMER_1
;SETB PS               ;SERIAL PORT PRORITY HIGH
SETB ES                ;ENABLE UART1 INTERRUPT
RET

INITIAL_UART2:         
MOV S2CON, #01010000B  ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI
MOV BRT, #136          ;226=38400 136=9600
;MOV IP2, #01H          ;UART INTERUUPT PARITY HIGH
MOV IE2, #01H          ;ENABLE UART2 INTERRUPT
RET

INITIAL_UART2_38400:         
MOV S2CON, #01010000B  ;SET AS BAUD VERIABLE, NO ODD/EVEN CHECK S2SM0,S2SM1,S2SM2,S2REN,S2TB8,S2RB8,S2TI,S2RI
MOV BRT, #226          ;226=38400 136=9600
;MOV IP2, #01H          ;UART INTERUUPT PARITY HIGH
MOV IE2, #01H          ;ENABLE UART2 INTERRUPT
RET

SENTONEBYTE1:              
PUSH ACC
PUSH PSW
CHECKBUSY1:
JB 40H, CHECKBUSY1
SETB 40H                        ;MARK BUSY BIT
MOV SBUF, A
POP PSW
POP ACC
RET

SENTONEBYTE2:           
PUSH ACC
PUSH PSW
CHECKBUSY2:
JB 41H, CHECKBUSY2
SETB 41H                     ;MARK BUSY BIT
MOV S2BUF, A
POP PSW
POP ACC
RET

UART1:
;/*----------------------------
;UART1 INTERRUPT SERVICE ROUTINE
;----------------------------*/
PUSH ACC
PUSH PSW
JNB RI, UART1CHECKTI
MOV A, SBUF                     ;READ THE CHARACTER FROM THE SERIAL PORT
MOVX @R1, A
CJNE R1, #LASTBUFFER, NEXTB1
MOV R1, #HEADBUFFER
JMP NEXTB1A
NEXTB1:
INC R1
NEXTB1A:
CLR RI                          ;CLEAR RI BIT
JMP UART1EXIT
UART1CHECKTI:
CLR TI                          ;CLEAR TI BIT
CLR 40H                         ;CLEAR BUSY BIT
UART1EXIT:
POP PSW
POP ACC
RETI

UART2:               
;/*----------------------------
;UART2 INTERRUPT SERVICE ROUTINE
;----------------------------*/
PUSH ACC
PUSH PSW
MOV A, S2CON                ;READ UART2 CONTROL REGISTER
ANL A, #00000001B           ;ANL, IF S2RI=0 THEN 0
JZ UART2CHECKTI
MOV A, S2BUF   
MOVX @R1, A
CJNE R1, #LASTBUFFER, NEXTB2
MOV R1, #HEADBUFFER
JMP NEXTB2A
NEXTB2:
INC R1
NEXTB2A:
ANL S2CON, #11111110B         ;CLEAR S2RI BIT
JMP UART2EXIT
UART2CHECKTI:               
ANL S2CON, #11111101B         ;CLEAR S2TI BIT
CLR 41H                       ;CLEAR BUSY BIT
UART2EXIT:
POP    PSW
POP    ACC
RETI


DELAY2:
MOV 72H, #255 ;
SLOWDOWN0:
MOV 71H, #255
SLOWDOWN:
MOV 73H, #11   ;
SLOWDOWN2:
DJNZ 73H, SLOWDOWN2
DJNZ 71H, SLOWDOWN
DJNZ 72H, SLOWDOWN0
RET

RESET:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"R"
LCALL SENTONEBYTE2
MOV A ,#"E"
LCALL SENTONEBYTE2
MOV A ,#"S"
LCALL SENTONEBYTE2
MOV A ,#"E"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

ROLE1:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"R"
LCALL SENTONEBYTE2
MOV A ,#"O"
LCALL SENTONEBYTE2
MOV A ,#"L"
LCALL SENTONEBYTE2
MOV A ,#"E"
LCALL SENTONEBYTE2
MOV A ,#"1"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

CLSSF0:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"C"
LCALL SENTONEBYTE2
MOV A ,#"L"
LCALL SENTONEBYTE2
MOV A ,#"S"
LCALL SENTONEBYTE2
MOV A ,#"S"
LCALL SENTONEBYTE2
MOV A ,#"F"
LCALL SENTONEBYTE2
MOV A ,#"0"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

BAUD6:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"B"
LCALL SENTONEBYTE2
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"U"
LCALL SENTONEBYTE2
MOV A ,#"D"
LCALL SENTONEBYTE2
MOV A ,#"6"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

CONN1:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"C"
LCALL SENTONEBYTE2
MOV A ,#"0"
LCALL SENTONEBYTE2
MOV A ,#"N"
LCALL SENTONEBYTE2
MOV A ,#"N"
LCALL SENTONEBYTE2
MOV A ,#"1"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

STAT:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"S"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

VERSION:
MOV A ,#"A"
LCALL SENTONEBYTE2
MOV A ,#"T"
LCALL SENTONEBYTE2
MOV A ,#"+"
LCALL SENTONEBYTE2
MOV A ,#"V"
LCALL SENTONEBYTE2
MOV A ,#"E"
LCALL SENTONEBYTE2
MOV A ,#"R"
LCALL SENTONEBYTE2
MOV A ,#"S"
LCALL SENTONEBYTE2
MOV A ,#"I"
LCALL SENTONEBYTE2
MOV A ,#"O"
LCALL SENTONEBYTE2
MOV A ,#"N"
LCALL SENTONEBYTE2
MOV A ,#13
LCALL SENTONEBYTE2
MOV A ,#10
LCALL SENTONEBYTE2
RET

PAIR:
CLR P1.4
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
LCALL DELAY2
SETB P1.4
LCALL DELAY2
RET

END




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2020-11-5 17:14 | 显示全部楼层
好资料,51黑有你更精彩!!!
回复

使用道具 举报

ID:283954 发表于 2020-11-13 01:02 | 显示全部楼层
除了蓝牙模块之外,我也买过2.4G的无线模块来玩,2.4G的模块的老祖宗是一块叫NRF24L01的晶片,原厂家是挪威公司,价钱很高,后来被仿制,价钱掉了10倍,也因此获得普及,其内部原理之一是收到信号后会回应ACK,若CRC有错会要求重发,重发的次数还可以设定,这就保证了信号的可靠性,但其收发流程非常复杂,非一般初学者能掌握,两三年前才有国内公司配上一个MCU把这一过程简化成串口界面的模块,用起来很简单,销售量很不错,我也买了50片支持一下,再后来又出现了内部集成了NRF24L01和MCU的单个晶片,价钱掉到5人民币,代表模块是LC-12S,我也买了50片来储存,并做过测试,用来传送MIDI信号,相当可靠。最近上网一看,已经有很多公司在售卖类似LC-12S的模块,一款叫JDY-40的才卖3人民币,不能再低了!效果如何得测试一下,我因为已经有了蓝牙模块设置器,稍微更改软件就很容易用来设定LC-12S和JDY-40.

LC-12S的设定是发一组18字节的码,一次过设定所有参数:
主机发送:AA5A22331122000000040064000000120006 ;RF发射功率:12dbm;串口速率:9600bps;RF信道:100;模块ID:0x2233;和校验字节:06

如果参数有效,校验字节也对,模块就会回应:

返回数据:AA5B22331122000000040064000000120007
说真的,这样的设定方式不好用,但用单片机程序来设定还是可行。

JDY-40的设定是AT式的,AT其实是ATTENTION的意思,就是注意啦!命令有:
AT+BAUD,AT+CLSS,AT+RFC等等,都写了副程式,LCALL一下都能响应,不过每个命令之间要DELAY一下,让模块有时间回应。
说明书有注明BAUD波特率有1-7,BAUD6是19200BPS,但BAUD7没有注明,推测应该是38400,因为LC-12S有38400,这模块也应该有,于是就向模块发出AT+BAUD7,看看有什么回应,哈!无回应,再发出其他AT命令,哑巴了!关电再试也无反应。很不甘心,焊多一片再试,所有命令都正常回应,直到发出AT+BAUD7, 模块就一命呜呼了。还好我有第三片JDY-40,不然我的编程工作就停止了。

JDY40-2A.jpg
JDY40.jpg


2.4G模块便宜,但选用前要小心测试哈。







回复

使用道具 举报

ID:283954 发表于 2020-11-16 03:20 | 显示全部楼层
前文说有两片JDY-40已经阵亡了,后来想起过去玩过一些模块的经验,有的模块设定新的波特率后,设定的串口必须即刻转去新的波特率,否则就失联了,可能这JDY-40也是如此。经过试验,果然如此。问题在于说明书没有提到这点。而LC-12S就清楚说,设定时波特率一定是9600。

这两个模式是那一种好呢?显然是LC-12S固定的波特率好,就如这次经验,JDY-40会失联,那么JDY-40有没有38400的波特率呢?没有,最高是19200,同样的芯片为何LC-12S能做到38400呢?显然是原创者的功力略胜一筹。

接下来是进行传输试验。LC-12S在38400下隔着两道墙还能可靠传输,显然是物有所值。

2.4G模块与蓝牙相比,好处是传输延时很短,在1-2MS之间,而蓝牙的延时是30MS上下,用来传输MIDI信号,从弹奏到听到声音的时间延迟,比较优秀的演奏者都能听出来。但蓝牙的配对功能是很出色的,有没有可能让2.4G的模块也能自动配对呢?现在很通用的无线老鼠和键盘也是2.4G,一旦接收器丢了,就全部不能用了。

看看LC-12S的发射到接收的延迟图:


lc-12s-delay.jpg


回复

使用道具 举报

ID:219315 发表于 2020-11-16 12:21 | 显示全部楼层
现在还有人在用汇编编程,真是稀有啊!
回复

使用道具 举报

ID:311846 发表于 2020-11-16 13:54 | 显示全部楼层
汇编大佬上线,很少遇到了
回复

使用道具 举报

ID:283954 发表于 2020-12-4 02:53 | 显示全部楼层
XG-LE.jpg xg-le2.jpg


这是我从许多蓝牙模块中,选到最适合我用的型号,模块分为主模块与从模块,外形一模一样,要是搞混了就无法知道是主是从了,主模块无需AT指令设定波特率,而是用接脚接地来选择,从模块则使用AT设定,由于没有针孔,必须自己设计转接板将需要的接脚引出,自己焊接后10片有1片会失败,但无所谓,主从配对非常容易,在主模块按下钮马上连上,所以是我最喜欢的模块,但每次设定总就是无法记得命令的格式,也需要制作一个专门的蓝牙设置器。

AT指令说明:
AT指令必须在蓝牙模块未连接的状态下才有用,在未连接状态下,带有AT开头的数据包会被默认为AT指令并被解析,返回处理结果;连接上之后,只会做数据转发,不解析数据。

1、测试命令命令格式:
AT\r返回值:OK\r内容:发送AT测试指令,返回值OK表示模块AT指令测试成功。

3、串口通讯波特率操作命令命令格式:
AT+BAUD=19200\r返回值:OK\rERROR\r内容:重新修改模块通讯的串口波特率为19200bps,返回OK提示已经修改成功,返回ERROR则表示新串口波特率修改失败,原因可能是设定值格式不对或者不支持该波特率。命令格式:AT+BAUD?\r返回值:19200\r内容:查询当前模块的串口通讯波特率,模块返回当前设置的波特率19200bps。

注:模块默认串口波特率为9600bps。每次设定新波特率后必须跟着改变串口的波特率,否则失联。从模块的S接脚使用时必须接高电位,空置偶尔会失效。

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:853787 发表于 2020-12-4 10:18 | 显示全部楼层
我要学习汇编
回复

使用道具 举报

ID:200118 发表于 2021-2-14 23:46 | 显示全部楼层
汇编语言也不错。。。
回复

使用道具 举报

ID:611078 发表于 2021-2-15 18:28 | 显示全部楼层
本人刚学单片机,也是从汇编开始的,后来学了C以后,再看汇编,就变成看天书了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表