STM32(三十)蓝牙通信

一、蓝牙模块参数简介

  • 蓝牙模块:汇承HC05蓝牙串口通信模块。
  • 蓝牙协议:Bluetooth Specification V2.0带EDR蓝牙协议。
  • 无线工作频段为2.4GHz ISM。
  • 调制方式是GFSK。
  • 模块最大发射功率为4dBm。
  • 接收灵敏度-85dBm。
  • 板载PCB天线,可以实现10米距离通信。
  • 自带LED灯,可直观判断蓝牙的连接状态。
  • 模块采用CSR的BC417芯片,支持AT 指令。
  • 用户可根据需要更改角色(主、从模式)以及串口波特率、设备名称等参数,使用灵活。

二、系列产品

 

 三、工作原理简介

1、工作原理

  如上图所示,HC-05 模块用于代替全双工通信时的物理连线。左边的设备向模块发送串口数据,模块的 RXD 端口收到串口数据后,自动将数据以无线电波的方式发送到空中。右边的模块能自动接收到,并从 TXD 还原最初左边设备所发的串口数据。从右到左也是一样的。 

2、模块与单片机 MCU 等设备的连接

 

:模块与供电系统为 3.3V 的 MCU 连接时,串口交叉连接即可(模块的 RX 接 MCU 的 TX、模块的 TX 接 MCU
的 RX)
:模块与供电系统为 5V 的 MCU 连接时,可在模块的 RX 端串接一个 220R~1K 电阻再接 MCU 的 TX,模块的
TX 直接接 MCU 的 RX,无需串接电阻。(注:请先确认所使用的 MCU 把 3.0V 或以上电压认定为高电平,否则需
加上 3.3V/5V 电平转换电路)
注:模块的电源为 3.3V,不能接 5V, 5V 的电源必须通过 LDO 降压到 3.3V 后再给模块供电。

四、蓝牙模式及AT指令

1、AT指令模式

用于设置蓝牙的相关信息(名字,配对密码,波特率(9600))按下模块上的按键,上电,即可进行AT指令模式,led灯慢闪表示进入AT模式,双闪表示蓝牙已连接并打开了端口。

2、数据透传模式

上电后就进入了数据透传模式,此时蓝牙模块led灯快闪连接后led灯双闪。在此模式下连接后可以传输数据。

3、常用的AT指令

①测试:AT\r\n                         返回:OK     (即通信成功)

②设置蓝牙名称:AT+NAME=PDD\r\n      返回:OK

③查询蓝牙名称:AT+NAME?\r\n          返回:+NAME=PDD   OK

④设置配对密码:AT+PSWD=1234\r\n      返回:OK

⑤查询配对密码:AT+PSWD?\r\n          返回:+PSWD=1234   OK

⑥查询设备mac地址:AT+ADDR?\r\n      返回:+ADDR:21:13:52b9b   OK

五、蓝牙调试

  手机可以下载蓝牙调试器或者关注蓝牙调试公众号,蓝牙模块在数据透传模式可以用来连接蓝牙模块,并且给蓝牙模块发送数据,也可以通过编辑按钮,按按钮发送数据给蓝牙模块,蓝牙模块收到数据后通过串口发给MCU,从而控制MCU的一些外设

 

六、STM32F407ZET6与蓝牙模块连接

 

 

 

 

 如上图U转UART1的RXD和TXD通过CH340芯片连接USB,可以通过USB连接电脑,用串口工具给MCU发数据和接收数据,USART1_TX和UASRT1_RX是和主芯片连着,调帽跳到1-3、2-4。如果蓝牙要和MCU通信,则调帽3-5、4-6相连,此时连到P4,将蓝牙模块的RXD和P4的TXD1连接,TXD和P4的RXD1连接,此时蓝牙模块就可以就可以和MCU通信.

实验一:通过手机连接蓝牙控制蜂鸣器的响灭。

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//uart.c文件
#include "uart.h"
 
void Uart_Init(uint32_t band)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    //1、初始化硬件
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    //复用为串口1
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
    USART_InitStruct.USART_BaudRate = band;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件控制流
    USART_InitStruct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx ;
    USART_InitStruct.USART_Parity= USART_Parity_No; //无奇偶校验
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStruct);
    //初始化NVIC
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x1;//抢占优先级   0-3
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x1;//响应占优先级      0-3
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//中断向量号   TIM3   中断向量号位tim3
    NVIC_InitStruct.NVIC_IRQChannelCmd =  ENABLE;//使能
    NVIC_Init(&NVIC_InitStruct);
    //串口中断
    USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
    USART_Cmd(USART1,ENABLE);
}
 
//main函数
#include "stdio.h"
uint16_t uart1_recv_data;
 
//重定向fputc  fputs  fgetc fgets
int fputc(int ch,FILE *f)
{
    USART_SendData(USART1, ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
    return ch;
}
 
 //串口进入中断接收蓝牙发过来的数据
 void USART1_IRQHandler()
 {
     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        //清楚中断标志位   往里面写1   记住一定要清空
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
        uart1_recv_data =  USART_ReceiveData(USART1);
    }
 }
  
 //给蓝牙模块发数据
void USART_SendString(const uint8_t* str)
{
    u8 i = 0;
    while(*(str+i)!='\n')
    {  
    USART_SendData(USART1, *(str+i));
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
        i++;
    }
}
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //给中断优先级分组
    LED_Init();
    Key_Init();
    Beep_Init();
    Uart_Init(9600);  //和蓝牙模块的波特率一致
    printf("hello");
    while(1)
    {
        if(uart1_recv_data == '1')
        {
         
            PFout(8) =1;
        }
        if(uart1_recv_data == '0')
        {
         
            PFout(8) =0;
        }  
        delay_s(1);
    }
    return 0;
}//uart.c文件
#include "uart.h"
 
void Uart_Init(uint32_t band)
{
    GPIO_InitTypeDef  GPIO_InitStruct;
    USART_InitTypeDef USART_InitStruct;
    NVIC_InitTypeDef NVIC_InitStruct;
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
    //1、初始化硬件
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_25MHz;
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOA, &GPIO_InitStruct);
    //复用为串口1
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
    USART_InitStruct.USART_BaudRate = band;
    USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件控制流
    USART_InitStruct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx ;
    USART_InitStruct.USART_Parity= USART_Parity_No; //无奇偶校验
    USART_InitStruct.USART_StopBits = USART_StopBits_1;
    USART_InitStruct.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART1, &USART_InitStruct);
    //初始化NVIC
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x1;//抢占优先级   0-3
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x1;//响应占优先级      0-3
    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;//中断向量号   TIM3   中断向量号位tim3
    NVIC_InitStruct.NVIC_IRQChannelCmd =  ENABLE;//使能
    NVIC_Init(&NVIC_InitStruct);
    //串口中断
    USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);
    USART_Cmd(USART1,ENABLE);
}

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//main函数  ------通过手机连接蓝牙控制蜂鸣器的响灭。
#include "stdio.h"
uint16_t uart1_recv_data;
 
//重定向fputc  fputs  fgetc fgets
int fputc(int ch,FILE *f)
{
    USART_SendData(USART1, ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
    return ch;
}
 
 //串口进入中断接收蓝牙发过来的数据
 void USART1_IRQHandler()
 {
     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
    {
        //清楚中断标志位   往里面写1   记住一定要清空
        USART_ClearITPendingBit(USART1,USART_IT_RXNE);
        uart1_recv_data =  USART_ReceiveData(USART1);
    }
 }
  
 //给蓝牙模块发数据
void USART_SendString(const uint8_t* str)
{
    u8 i = 0;
    while(*(str+i)!='\n')
    {  
    USART_SendData(USART1, *(str+i));
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
        i++;
    }
}
int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);   //给中断优先级分组
    LED_Init();
    Key_Init();
    Beep_Init();
    Uart_Init(9600);  //和蓝牙模块的波特率一致
    printf("hello");
    while(1)
    {
        if(uart1_recv_data == '1')
        {
         
            PFout(8) =1;
        }
        if(uart1_recv_data == '0')
        {
         
            PFout(8) =0;
        }  
        delay_s(1);
    }
    return 0;
}  

实验二、usart1连接电脑串口,usart3连接蓝牙模块,串口调试工具和蓝牙模块通信,串口工具发命令给usart1,usart1发给usart3到蓝牙模块。(注意stm32Fxx.h修改晶振频率为8M

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#include "stm32f4xx.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_usart.h"
#include "stdio.h"
 
static GPIO_InitTypeDef     GPIO_InitStructure;
static USART_InitTypeDef    USART_InitStructure;
static NVIC_InitTypeDef     NVIC_InitStructure;    
 
static  uint8_t g_usart1_recv_buf[128]={0};
static  uint8_t g_usart1_recv_cnt = 0;
 
 
 
//重定义fputc函数
int fputc(int ch, FILE *f)
{  
    USART_SendData(USART1,ch);
    while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); 
     
    return ch;
}  
 
void delay_us(int nus) //微秒
{
     
    //SystemCoreClock
    SysTick->LOAD = (SystemCoreClock/8/1000000) * nus;   //定时时间
                                                 
    SysTick->CTRL |= 1;                         //开启定时器,开始计数
                                                 
    while((SysTick->CTRL & (1<<16)) == 0);      //等待定时时间到
                                                 
    SysTick->CTRL &=~1;                         //关闭定时器
 
}
 
void delay_ms(int nms)   //毫秒
{
    uint32_t m,n;
    m = nms/500;
    n = nms%500;
    while(m--)
    {
        SysTick->LOAD = (SystemCoreClock/8/1000) * 500;      //定时时间
     
        SysTick->CTRL |= 1;                          //开启定时器,开始计数
     
        while((SysTick->CTRL & (1<<16)) == 0);     //等待定时时间到
     
        SysTick->CTRL &=~1;                          //关闭定时器
    }
    if(n)
    {
        SysTick->LOAD = (SystemCoreClock/8/1000) * n;        //定时时间
     
        SysTick->CTRL |= 1;                          //开启定时器,开始计数
     
        while((SysTick->CTRL & (1<<16)) == 0);     //等待定时时间到
     
        SysTick->CTRL &=~1;                          //关闭定时器
    }
     
}
 
void LED_Init(void)
{       
   
    //使能GPIOE,GPIOF时钟
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF, ENABLE);           
 
    //GPIOF9,F10初始化设置
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9 | GPIO_Pin_10;       //LED0和LED1对应IO口
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                  //普通输出模式,
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                  //推挽输出,驱动LED需要电流驱动
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;              //100MHz
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                   //上拉
    GPIO_Init(GPIOF, &GPIO_InitStructure);                          //初始化GPIOF,把配置的数据写入寄存器                     
 
 
    //GPIOE13,PE14初始化设置
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14;      //LED2和LED3对应IO口
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;                  //普通输出模式
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                  //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;              //100MHz
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;                   //上拉
    GPIO_Init(GPIOE, &GPIO_InitStructure);                          //初始化GPIOE,把配置的数据写入寄存器
 
    GPIO_SetBits(GPIOF,GPIO_Pin_9  | GPIO_Pin_10);                  //GPIOF9,PF10设置高,灯灭
    GPIO_SetBits(GPIOE,GPIO_Pin_13 | GPIO_Pin_14);     
}
 
 
void USART1_Init(uint32_t baud)
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);                            //使能GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);                           //使能USART1时钟
  
    //串口1对应引脚复用映射
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);                         //GPIOA9复用为USART1
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);                        //GPIOA10复用为USART1
     
    //USART1端口配置
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;                         //GPIOA9与GPIOA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                                    //复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                               //速度50MHz
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;                                  //推挽复用输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;                                    //上拉
    GPIO_Init(GPIOA,&GPIO_InitStructure);                                           //初始化PA9,PA10
 
    //USART1 初始化设置
    USART_InitStructure.USART_BaudRate = baud;                                      //波特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;                     //字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;                          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;                             //无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                 //收发模式
    USART_Init(USART1, &USART_InitStructure);                                       //初始化串口1
     
    USART_Cmd(USART1, ENABLE);                                                      //使能串口1
     
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                                  //开启相关中断
 
    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;                               //串口1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;                         //抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;                               //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                 //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);                                                 //根据指定的参数初始化VIC寄存器
}
 
void USART3_Init(uint32_t baud)
{
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
 
    /* GPIOB Configuration: PB10 PB11 */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11  ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;       
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
     
    /* Connect USART3_TX pins to PB10 */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
     
    /* Connect USART3_RX pins to PB11 */
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
 
    /* Enable USART3 clock */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
     
    USART_InitStructure.USART_BaudRate = baud;                                 
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;            
    USART_InitStructure.USART_StopBits = USART_StopBits_1;             
    USART_InitStructure.USART_Parity = USART_Parity_No;                    
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;                
    USART_Init(USART3, &USART_InitStructure);
 
      
    /* Enable the USARTx Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
      
    /* Enable USART3 */
    USART_Cmd(USART3, ENABLE);
     
    /* Enable the Rx buffer empty interrupt */
    USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
}
 
void USART1_SendBytes(uint8_t *pbuf,uint32_t len)
{
 
    while(len--)
    {
        USART_SendData(USART1,*pbuf++);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);  
    }
 
}
 
void USART1_SendString(uint8_t *pstr)
{
    while(pstr && *pstr)
    {
        USART_SendData(USART1,*pstr++);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);      
    }
}
 
void USART3_SendBytes(uint8_t *pbuf,uint32_t len)
{
 
    while(len--)
    {
        USART_SendData(USART3,*pbuf++);
        while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);  
    }
 
}
 
void USART3_SendString(uint8_t *pstr)
{
    while(pstr && *pstr)
    {
        USART_SendData(USART3,*pstr++);
        while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);      
    }
}
 
int main(void)
{
     
    LED_Init();    
 
    //系统定时器初始化,时钟源来自HCLK,且进行8分频,
    //系统定时器时钟频率=168MHz/8=21MHz
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
         
    //设置中断优先级分组2
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     
    //串口1,波特率115200bps,开启接收中断
    USART1_Init(115200);
     
    //串口3,波特率9600bps,开启接收中断
    USART3_Init(38400);
 
    while(1)
    {
         
    }
}
 
 
void USART1_IRQHandler(void)                                //串口1中断服务程序
{
    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)   //接收中断
    {
        //从串口1接收数据
        g_usart1_recv_buf[g_usart1_recv_cnt]=USART_ReceiveData(USART1);
        USART_SendData(USART1, g_usart1_recv_buf[g_usart1_recv_cnt]);
         
        //记录多少个数据
        g_usart1_recv_cnt++;
         
        //检测到换行符或接收的数据满的时候则发送数据
        if(g_usart1_recv_buf[g_usart1_recv_cnt-1]=='\n' || g_usart1_recv_cnt>=(sizeof g_usart1_recv_buf)-1)
        {
             
            USART3_SendBytes(g_usart1_recv_buf,g_usart1_recv_cnt);
            USART1_SendBytes(g_usart1_recv_buf,g_usart1_recv_cnt);
             
            g_usart1_recv_cnt = 0;
        }
    }
}
 
 
void USART3_IRQHandler(void)
{
    uint8_t d;
     
    /* USART in Receiver mode */
    if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) 
    {
        d=USART_ReceiveData(USART3);
        USART1_SendBytes(&d,1);
    }
}

 

  

 

posted @   轻轻的吻  阅读(11668)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示