📄 bluetooth_hci.c
字号:
#include<iom16v.h>
#include<macros.h>
#pragma interrupt_handler UART_transmit_isr:14
#pragma interrupt_handler UART_receive_isr:12
int tqcntr,tsndcntr,cnt;
char tqueue[50];
int rqcntr,rsndcntr;
char rqueue[50];
char handle[2];
char handle2_a[2];//连接句柄
void Uart_Transmit(char *s,int j) //j为发送字符的个数
{
tqcntr=0; //设置索引
tsndcntr=1; //设置为1,因为第一个字符准备发送
while(tqcntr<j)
tqueue[tqcntr++]=*s++; //把字符放进队列
/* 等待发送缓冲器为空*/
while (!(UCSRA&(1<<UDRE)))
;
/* 将数据放入缓冲器,发送数据*/
UDR=tqueue[0]; //发送第一个字符
}
void UART_transmit_isr(void)
{
if(tqcntr!=tsndcntr)
UDR=tqueue[tsndcntr++]; //发送第二个字符,并且索引加1
}
/*以上为UART发送字符串的函数*/
void Uart_Receive(int j) //j表示要接收的字符的个数
{
UCSRB=0xD8; //11011000接收结束中断使能、发送接收使能
rqcntr=j; //设置索引
rsndcntr=0; //设置为0,因为第一个字符准备接收
}
void UART_receive_isr(void)
{
if(rqcntr!=rsndcntr)
/*从缓冲器中获取数据,放入队列*/
rqueue[rsndcntr++]=UDR;
}
void delay()
{ unsigned int i,j;
for(i=1;i<600;i++)
{ for(j=1;j<1500;j++)
;
}
}
void initialize(void) //蓝牙设备初始化
{
char reset[4]={0x01, 0x03, 0x0C, 0x00};
char Write_Page_Scan_Activity[8]={0x01, 0x1C, 0x0C, 0x04, 0x40, 0x00, 0x20, 0x00};
char Write_Inquiry_Scan_Activity[8]={0x01, 0x1E, 0x0C, 0x04, 0x40, 0x00, 0x20, 0x00};
char Write_Scan_Enable[5]={0x01, 0x1A, 0x0C, 0x01, 0x03};
char Write_Authentication_Enable[5]={0x01, 0x20, 0x0C, 0x01, 0x00};
char Set_Event_Filter[7]={0x01, 0x05, 0x0C, 0x03, 0x02, 0x00, 0x02};
char Write_Connection_Accept_Timeout[6]={0x01, 0x16, 0x0C, 0x02, 0x00, 0x20};
char Write_Page_Timeout[6]={0x01, 0x18, 0x0C, 0x02, 0x00, 0x30};
Uart_Transmit(reset,4);
delay();
Uart_Transmit(Write_Page_Scan_Activity,8);
delay();
Uart_Transmit(Write_Inquiry_Scan_Activity,8);
delay();
Uart_Transmit(Write_Scan_Enable,5);
delay();
Uart_Transmit(Write_Authentication_Enable,5);
delay();
Uart_Transmit(Set_Event_Filter,7);
delay();
Uart_Transmit(Write_Connection_Accept_Timeout,6);
delay();
Uart_Transmit(Write_Page_Timeout,6);
delay();
}
void c_cnct(char addr) //主设备建立连接,addr为主设备的地址号:01,02,03...
{
char Create_Connection[]={0x01, 0x05, 0x04, 0x0D, 0xA5, 0xA5, 0x00, 0x5B,
0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
char Max_Slots_Change_Event[]={0x04, 0x1B, 0x03, 0x29, 0x00, 0x05};
int i=0;
Create_Connection[8]=addr;
Uart_Receive(37);
Uart_Transmit(Create_Connection,17);
delay();
Uart_Transmit(rqueue,37);
delay();
/*Uart_Receive(14);
delay();
Uart_Transmit(rqueue,14);
delay();*/
if(rqueue[10]==0x00) PORTB&=0xFB; //11111011,PB2=0,DS3亮
else if(rqueue[10]==0x01)
PORTB&=0xF7; //11110111,PB3=0,DS2亮
/*Uart_Receive(10);
delay();
Uart_Transmit(rqueue,10);
delay();
Uart_Receive(6);
delay();
Uart_Transmit(rqueue,6);
delay();*/
handle[0]=rqueue[34]; //从返回事件中取连接句柄
handle[1]=rqueue[35];
Uart_Transmit(handle,2);
delay();
/*判断建立连接是否正确,只判断最后收到的一组事件是不是和Max _Slots _Change _Event
相同,如果相同则亮一个显示灯。如果连接不正确,亮另一个显示灯
while (i<6)
{
if (rqueue[i]=Max_Slots_Change_Event[i])
i++;
else
i=7;
}
if(i=6) PORTB&=0xEF ; //11101111,PB4=0,DS1亮
else PORTB&=0xF4; //11110100,PB2=0,DS3亮 */
}
void Send_ACL_data(char x) //发送ACL数据
{
char ACL_data[]={0x02, 0x29, 0x20, 0x01, 0x00, 0x21};
//因为本项目中数据都是一个字节,所以ACL数据的长度设定都一样
char handle_a;
handle_a=handle[1]&0x20;
ACL_data[1]=handle[0]; //以下两句设置句柄
ACL_data[2]=handle_a;
ACL_data[5]=x; //数据
Uart_Receive(8);
Uart_Transmit(ACL_data,6);
delay();
Uart_Transmit(rqueue,8);
}
void Disconnection(void) //断开连接
{
char Disconnect[]={0x01, 0x06, 0x04, 0x03, 0x29, 0x00, 0x13};
Disconnect[4]=handle[0];
Disconnect[5]=handle[1];
Uart_Transmit(Disconnect,7);
Uart_Receive(8);
}
void main(void)
{
PORTA=0xff;
DDRA=0xe7;
PORTB=0xff;
DDRB=0xff;
PORTC=0x00;
DDRC=0xff;
PORTD=0x30;
DDRD=0xf3;
UCSRA=0x00; //普通模式
UCSRB=0x48; //01001000接收中断禁止、发送结束中断允许、发送使能、禁止接收
UCSRC=0x86; //选择异步传输模式,设置数据长度8位,1位停止位
UBRRH=0x00; //初始化串口9600,f=8m,注意:此处设为0x34才能保证波特率准确
UBRRL=0x34;
MCUCSR=0x00;
TWCR=0x00;
GICR=0x00;
ASSR=0x00; //由内部I/O时钟驱动
TIMSK=0x40; //定时器溢出中断使能
TCNT2=0x00; //定时器2初值
TCCR2=0x07; //选择1024分频
SREG=0x80; //全局中断使能
ACSR=0x81;
ADCSRA&=~(1<<ADEN);//关闭ADC
initialize();
c_cnct(0x02);
Send_ACL_data(0x22);
while(1);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -