打印
[STM32F1]

STM32+DX-BT04蓝牙应用

[复制链接]
3198|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 hanzhen654 于 2017-10-28 11:43 编辑

程序下载进去后可以使用模块提供的安卓APK应用连接蓝牙模块BT05,连接好后指示灯D3亮,LCD显示连接,否则灭,LCD显示未连接。通过提供的APK软件进行发送和接收测试手机测试软件在String上会显示hello world也可以使用串口调试助手观察测试。

实验效果.jpg (106.74 KB )

实验效果.jpg

DX-BT05 AT指令使用方法.pdf

678.73 KB

DX-BT05 4.0插针模块使用方法.pdf

352 KB

DX-BT05 4.0蓝牙模块AT指令集v2.0.pdf

252.22 KB

DX-BT05 4.0蓝牙模块技术手册.pdf

326.72 KB

DX-BT05 4.0蓝牙手机操作指南.pdf

1.08 MB

沙发
hanzhen654|  楼主 | 2017-10-28 11:43 | 只看该作者
需要用到的头文件
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd_driver.h"
#include "gui.h"

使用特权

评论回复
板凳
hanzhen654|  楼主 | 2017-10-28 11:50 | 只看该作者
主函数部分
int main(void)
{       
        u8 t=0,k=0;
        delay_init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        uart_init(9600);         //比特率使用9600
        led_init();
        TFT_Init();
        lcd_display();
        led1=0;
        while(1)
        {       
                if(GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_1))         //判断是否和手机蓝牙连接  连接成功D3指示灯亮 否则灭
                {
                        led2=0;
                        GUI_Show12ASCII(10,110,"DX-BT05 Connect...",RED,BLACK);
                }
                else
                {
                        led2=1;
                        GUI_Show12ASCII(10,110,"DX-BT05 Disconnect ",RED,BLACK);
                }
                t++;
                if(t==15)
                {
                        t=0;
                        k++;
                        led0=~led0;
                        GUI_Show12ASCII(10,140,"hello world",RED,BLACK);
                        printf("hello world\r\n");         //BT05蓝牙模块一直发送数据
                        if(k==5)
                        {
                                k=0;
                                GUI_Show12ASCII(10,140,"             ",RED,BLACK);       
                        }
                }
                delay_ms(10);                                       
        }       
}


使用特权

评论回复
地板
hanzhen654|  楼主 | 2017-10-28 11:50 | 只看该作者
LCD初始化显示
void lcd_display()          
{
        TFT_ClearScreen(BLACK);
        GUI_Show12ASCII(10,10,"PRECHIN",GREEN,BLACK);
        GUI_Show12ASCII(10,30,"www.prechin.com",GREEN,BLACK);
        GUI_Show12ASCII(10,50,"DX-BT05 Test",GREEN,BLACK);
        GUI_Show12ASCII(10,70,"2015-12-05",GREEN,BLACK);       
}

使用特权

评论回复
5
hanzhen654|  楼主 | 2017-10-28 12:10 | 只看该作者
在延时函数部分包括了以下函数
01.延时US级别的
void delay_us(u32 i)
{
        u32 temp;
        SysTick->LOAD=9*i;                 //设置重装数值, 72MHZ时
        SysTick->CTRL=0X01;                 //使能,减到零是无动作,采用外部时钟源
        SysTick->VAL=0;                            //清零计数器
        do
        {
                temp=SysTick->CTRL;                   //读取当前倒计数值
        }
        while((temp&0x01)&&(!(temp&(1<<16))));         //等待时间到达
        SysTick->CTRL=0;        //关闭计数器
        SysTick->VAL=0;                //清空计数器
}
02.延时毫秒级别的。
void delay_ms(u32 i)
{
        u32 temp;
        SysTick->LOAD=9000*i;          //设置重装数值, 72MHZ时
        SysTick->CTRL=0X01;                //使能,减到零是无动作,采用外部时钟源
        SysTick->VAL=0;                        //清零计数器
        do
        {
                temp=SysTick->CTRL;           //读取当前倒计数值
        }
        while((temp&0x01)&&(!(temp&(1<<16))));        //等待时间到达
        SysTick->CTRL=0;        //关闭计数器
        SysTick->VAL=0;                //清空计数器
}

使用特权

评论回复
6
hanzhen654|  楼主 | 2017-10-28 21:00 | 只看该作者
在led文件里面 led引脚初始化  led跑马灯的方向
void led_init()
{
        GPIO_InitTypeDef  GPIO_InitStructure;
         
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);            //使能PC端口时钟
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;                          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
        GPIO_Init(GPIOC, &GPIO_InitStructure);                             
        GPIO_SetBits(GPIOC,GPIO_Pin_All);
}

void led_run(u8 fx,u16 time)          
{
        static u8 i;
        if(fx==0)        //向右跑
        {
                GPIO_Write(GPIOC,~(0x01<<i++));
                delay_ms(time);
                if(i==8)i=0;               
        }
        else          //向左跑
        {
                GPIO_Write(GPIOC,~(0x80>>i++));
                delay_ms(time);
                if(i==8)i=0;       
        }       
}

使用特权

评论回复
7
hanzhen654|  楼主 | 2017-10-28 21:02 | 只看该作者
LCD驱动中,初始化TFT的IO口
void TFT_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        /* 打开时钟使能 */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE  
                              | RCC_APB2Periph_GPIOG, ENABLE);

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_12;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        /* FSMC_A10(G12) 和RS(G0)*/
        GPIO_Init(GPIOG, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4
                                      | GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_8
                                                                  | GPIO_Pin_9 | GPIO_Pin_10 |GPIO_Pin_11
                                                                  | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14
                                                                  | GPIO_Pin_15 );

        GPIO_Init(GPIOD, &GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9
                                       | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12
                                                                   | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);

        GPIO_Init(GPIOE, &GPIO_InitStructure);
}

使用特权

评论回复
8
hanzhen654|  楼主 | 2017-10-28 21:04 | 只看该作者
初始化FSMC
void TFT_FSMC_Config(void)
{
        /* 初始化函数 */
        FSMC_NORSRAMInitTypeDef        FSMC_NORSRAMInitStructure;
        FSMC_NORSRAMTimingInitTypeDef  FSMC_NORSRAMTiming;

        /* 设置读写时序,给FSMC_NORSRAMInitStructure调用 */
        /* 地址建立时间,3个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_AddressSetupTime = 0x02;

        /* 地址保持时间,1个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_AddressHoldTime = 0x00;

        /* 数据建立时间,6个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_DataSetupTime = 0x05;

        /* 数据保持时间,1个HCLK周期 */
        FSMC_NORSRAMTiming.FSMC_DataLatency = 0x00;

        /* 总线恢复时间设置 */
        FSMC_NORSRAMTiming.FSMC_BusTurnAroundDuration = 0x00;
       
        /* 时钟分频设置 */
        FSMC_NORSRAMTiming.FSMC_CLKDivision = 0x01;

        /* 设置模式,如果在地址/数据不复用时,ABCD模式都区别不大 */
        FSMC_NORSRAMTiming.FSMC_AccessMode = FSMC_AccessMode_B;

        /*设置FSMC_NORSRAMInitStructure的数据*/
        /* FSMC有四个存储块(bank),我们使用第一个(bank1) */
        /* 同时我们使用的是bank里面的第 4个RAM区 */
        FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;

        /* 这里我们使用SRAM模式 */
        FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;

        /* 使用的数据宽度为16位 */
        FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;

        /* 设置写使能打开 */
        FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;

        /* 选择拓展模式使能,即设置读和写用不同的时序 */
        FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Enable;
       
        /* 设置地址和数据复用使能不打开 */
        FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;
       
        /* 设置读写时序 */
        FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &FSMC_NORSRAMTiming;
       
        /* 设置写时序 */
        FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &FSMC_NORSRAMTiming;

        /* 打开FSMC的时钟 */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);
         
        FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

        /*!< Enable FSMC Bank1_SRAM Bank */
        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);       
}

使用特权

评论回复
9
junpeng324| | 2017-10-28 21:12 | 只看该作者
APP不错,感谢分享。

使用特权

评论回复
10
zhuomuniao110| | 2017-10-28 22:23 | 只看该作者
太给力了,以前不知道蓝牙可以这么玩的容易。。

使用特权

评论回复
11
hanzhen654|  楼主 | 2017-10-29 21:37 | 只看该作者
LCD写入命令
void TFT_WriteCmd(uint16_t cmd)
{
        TFT->TFT_CMD = cmd<<8 ;
}

使用特权

评论回复
12
hanzhen654|  楼主 | 2017-10-29 21:38 | 只看该作者
LCD写入数据
void TFT_WriteData(u16 dat)
{
        TFT->TFT_DATA = dat<<8;
}


void TFT_WriteData_Color(u16 color)
{
        TFT->TFT_DATA = color&0xff00;
        TFT->TFT_DATA = color<<8;
}

使用特权

评论回复
13
hanzhen654|  楼主 | 2017-10-30 15:32 | 只看该作者
初始化LCD屏
void TFT_Init(void)
{
        uint16_t i;


        TFT_GPIO_Config();
        TFT_FSMC_Config();


        //************* Start Initial Sequence **********//       
        TFT_WriteCmd(0xCB);  
        TFT_WriteData(0x39);
        TFT_WriteData(0x2C);
        TFT_WriteData(0x00);
        TFT_WriteData(0x34);  
        TFT_WriteData(0x02);   


        TFT_WriteCmd(0xCF);  
        TFT_WriteData (0x00);
        TFT_WriteData (0xa2); //c1
        TFT_WriteData (0Xf0);  //30
         
        TFT_WriteCmd(0xE8);  
        TFT_WriteData (0x84);          //85
        TFT_WriteData (0x11);          //00
        TFT_WriteData (0x7a);          //79
       
       
        TFT_WriteCmd(0xEA);  
        TFT_WriteData (0x66);  //00
        TFT_WriteData (0x00);
       
        TFT_WriteCmd(0xED);  
        TFT_WriteData (0x55);         //64
        TFT_WriteData (0x01);         //03
        TFT_WriteData (0X23);         //12
        TFT_WriteData (0X01);         //81
         
        TFT_WriteCmd(0xF7);  
        TFT_WriteData (0x20);         //20
       
       
        TFT_WriteCmd(0xC0);    //Power control
        TFT_WriteData (0x1c);   //VRH[5:0]         //1c
         
        TFT_WriteCmd(0xC1);    //Power control
        TFT_WriteData (0x13);   //SAP[2:0];BT[3:0]         //13
         
        TFT_WriteCmd(0xC5);    //VCM control
        TFT_WriteData (0x23);
        TFT_WriteData (0x3F);
         
        TFT_WriteCmd(0xC7);    //VCM control2
        TFT_WriteData(0xA5);
       
        TFT_WriteCmd(0xB1);  
        TFT_WriteData (0x00);
        TFT_WriteData (0x17);
       
        TFT_WriteCmd(0x3A);  
        TFT_WriteData (0x55);
       
        TFT_WriteCmd(0xB6);  
        TFT_WriteData (0x0A);
        TFT_WriteData (0xa2);  //a2
        TFT_WriteData (0x27);
        TFT_WriteData (0x00);
         
        TFT_WriteCmd(0x36);    // Memory Access Control
        TFT_WriteData (0x08);           //08        BGR
         
        TFT_WriteCmd(0xF2);    // 3Gamma Function Disable
        TFT_WriteData (0x02);         //00
         
        TFT_WriteCmd(0x26);    //Gamma curve selected
        TFT_WriteData (0x01);
         
        TFT_WriteCmd(0xE0);    //Set Gamma
        TFT_WriteData (0x0F);
        TFT_WriteData (0x14);
        TFT_WriteData (0x13);
        TFT_WriteData (0x0C);
        TFT_WriteData (0x0E);
        TFT_WriteData (0x05);
        TFT_WriteData (0x45);
        TFT_WriteData (0x85);
        TFT_WriteData (0x36);
        TFT_WriteData (0x09);
        TFT_WriteData (0x14);
        TFT_WriteData (0x05);
        TFT_WriteData (0x09);
        TFT_WriteData (0x03);
        TFT_WriteData (0x00);
         
        TFT_WriteCmd(0XE1);    //Set Gamma
        TFT_WriteData (0x00);
        TFT_WriteData (0x24);
        TFT_WriteData (0x26);
        TFT_WriteData (0x03);
        TFT_WriteData (0x0F);
        TFT_WriteData (0x04);
        TFT_WriteData (0x3F);
        TFT_WriteData (0x14);
        TFT_WriteData (0x52);
        TFT_WriteData (0x04);
        TFT_WriteData (0x10);
        TFT_WriteData (0x0E);
        TFT_WriteData (0x38);
        TFT_WriteData (0x39);
        TFT_WriteData (0x0F);


        TFT_WriteCmd(0x2A );
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0xEF);


        TFT_WriteCmd(0x2B );
        TFT_WriteData(0x00);
        TFT_WriteData(0x00);
        TFT_WriteData(0x01);
        TFT_WriteData(0x3F);
         
        TFT_WriteCmd(0x11);    //Exit Sleep
        for(i=50000; i>0; i--);         //延时
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        for(i=50000; i>0; i--);
        TFT_WriteCmd(0x29);    //Display on


}

使用特权

评论回复
14
hanzhen654|  楼主 | 2017-10-30 15:35 | 只看该作者
设置要操作的窗口范围
void TFT_SetWindow(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd)
{
        TFT_WriteCmd(0x2A);

    TFT_WriteData(xStart/256);
    TFT_WriteData(xStart%256);
    TFT_WriteData(xEnd/256);
    TFT_WriteData(xEnd%256);

    TFT_WriteCmd(0x2b);
    TFT_WriteData(yStart/256);
    TFT_WriteData(yStart%256);
    TFT_WriteData(yEnd/256);
    TFT_WriteData(yEnd%256);
    TFT_WriteCmd(0x2c);
}

使用特权

评论回复
15
hanzhen654|  楼主 | 2017-10-30 15:36 | 只看该作者
将LCD清屏成相应的颜色
void TFT_ClearScreen(uint16_t color)
{
        uint16_t i, j ;

        TFT_SetWindow(0, 0, TFT_XMAX, TFT_YMAX);         //作用区域
          for(i=0; i<TFT_XMAX+1; i++)
        {
                for (j=0; j<TFT_YMAX+1; j++)
                {
                        TFT_WriteData_Color(color);
                }
        }
}


使用特权

评论回复
16
hanzhen654|  楼主 | 2017-10-30 16:55 | 只看该作者
TIM5通道1输入捕获
void tim5_input2_init(u32 arr,u32 pre)       
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;
        GPIO_InitTypeDef  GPIO_InitStructure;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);  //使能TIM5时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //浮空输入模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
        GPIO_Init(GPIOA, &GPIO_InitStructure);                                  // PA0


        TIM_TimeBaseStructure.TIM_Period= arr;  //设置了在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler= pre;//设置了用来作为 TIMx 时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1; //设置了时钟分割 如果不是0那么时钟就是72M,否则就是36M
        TIM_TimeBaseStructure.TIM_CounterMode= TIM_CounterMode_Up; //选择了计数器模式 向上计数
        TIM_TimeBaseInit(TIM5, & TIM_TimeBaseStructure);  //初始化TIM5
       
        TIM_ICInitStructure.TIM_Channel=TIM_Channel_1; //TIM5通道1
        TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising; // 上升沿捕获
        TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;//选择IC1映射TI1上
        TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;//设置输入捕获预分频器
        TIM_ICInitStructure.TIM_ICFilter=0x03;//使用滤波器 8个定时器时钟周期滤波
        TIM_ICInit(TIM5,&TIM_ICInitStructure);


        TIM_Cmd(TIM5,ENABLE);         //使能TIM5外设               
}

使用特权

评论回复
17
hanzhen654|  楼主 | 2017-10-30 20:48 | 只看该作者
触摸按键复位,配置输入口PA0为输出模式,使电容放电
void tpad_reset()
{
        GPIO_InitTypeDef  GPIO_InitStructure;


        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);


        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                          
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出模式
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为50MHz
        GPIO_Init(GPIOA, &GPIO_InitStructure);                                  // PA0
        GPIO_ResetBits(GPIOA,GPIO_Pin_0);


        delay_ms(5);   //延时5ms
        TIM_SetCounter(TIM5,0);         //对TIM5计数器清零
        TIM_ClearITPendingBit(TIM5,TIM_IT_CC1|TIM_IT_Update);  //清除中断标志
       
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;          //浮空输入模式       
        GPIO_Init(GPIOA, &GPIO_InitStructure);                                  // PA0       
}

使用特权

评论回复
18
hanzhen654|  楼主 | 2017-10-30 20:49 | 只看该作者
得到定时器捕获值,如果超时直接返回定时器计数值
u16 tpad_get_val()       
{
        tpad_reset(); //复位tpad进行放电完全
        while(TIM_GetITStatus(TIM5,TIM_IT_CC1)!=RESET)         //等待溢出
        {
                if(TIM_GetCounter(TIM5)>tpad_arr_max_val-500)  //如果定时器超时,直接返回定时器计数器值
                {
                        return TIM_GetCounter(TIM5); //返回TIM5的CNT值       
                }                       
        }
        return TIM_GetCapture1(TIM5);  //返回TIM5通道1的捕获值               
}

使用特权

评论回复
19
hanzhen654|  楼主 | 2017-10-30 20:50 | 只看该作者
初始化 返回0:初始化成功,返回1:初始化失败
u8 tpad_init(u32 psc)
{
        u8 i,j;
        u16 buf[10],temp;
        tim5_input2_init(tpad_arr_max_val,psc-1); //以1M频率计数
        for(i=0;i<10;i++)                 //连续读取10次捕获值
        {
                buf=tpad_get_val();
                delay_ms(10);               
        }
        for(i=0;i<9;i++)   //从小到大排序
        {
                for(j=i+1;j<10;j++)       
                {
                        if(buf>buf[j])
                        {
                                temp=buf;
                                buf=buf[j];
                                buf[j]=temp;               
                        }
                }
        }
        temp=0;
        for(i=2;i<8;i++)        //取中间6个数据的平均数
        {
                temp+=buf;       
        }
        tpad_default_val=temp/6;
        printf("tpad_default_val= %d\r\n",tpad_default_val); //输出打印默认的捕获时间值
        if(tpad_default_val>tpad_arr_max_val/2)return 1;
        return 0;               
}

使用特权

评论回复
20
hanzhen654|  楼主 | 2017-10-30 20:51 | 只看该作者
读取n次,取最大值
u16 tpad_get_maxval(u8 n)
{
        u16 temp=0;
        u16 res=0;
        while(n--)
        {
                temp=tpad_get_val();
                if(temp>res)
                {
                        res=temp;
                }
        }
        return res;               
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

73

主题

1766

帖子

2

粉丝