只需將藍(lán)牙連到單片機(jī)上,使用usart3(PB10、PB11)作為藍(lán)牙和單片機(jī)的數(shù)據(jù)傳輸,而電腦的收發(fā)數(shù)據(jù)要是用usart1(PA9、PA10),將數(shù)據(jù)存入數(shù)組中,從而在串口助手中打印值
?1.下面是usart.c文件,將io口和串口初始化,并且加入中斷(其中電腦發(fā)送時,所用的中斷需要回車換行,正常情況下,直接數(shù)據(jù)存入寄存器,將數(shù)據(jù)存放在數(shù)組中(參考下面usart3的中斷))
#include "sys.h"
#include "usart.h"?? ? ?
//加入以下代碼,支持printf函數(shù),而不需要選擇use MicroLIB?? ? ?
#if 1
#pragma import(__use_no_semihosting) ? ? ? ? ? ??
//標(biāo)準(zhǔn)庫需要的支持函數(shù) ? ? ? ? ? ? ? ??
struct __FILE?
{?
?? ?int handle;?
};?
FILE __stdout; ? ? ??
//定義_sys_exit()以避免使用半主機(jī)模式 ? ?
void _sys_exit(int x)?
{?
?? ?x = x;?
}?
//重定義fputc函數(shù)?
int fputc(int ch, FILE *f)
{ ? ? ?
?? ?while((USART1->SR&0X40)==0);//循環(huán)發(fā)送,直到發(fā)送完畢 ??
? ? USART1->DR = (u8) ch; ? ? ?
?? ?return ch;
}
#endif?
?
?
#if EN_USART1_RX ? //如果使能了接收
u8 USART_RX_BUF[USART_REC_LEN];?
u8 USART3_RX_BUF[USART_REC_LEN];
//接收緩沖,最大USART_REC_LEN個字節(jié).
//接收狀態(tài)
//bit15,?? ?接收完成標(biāo)志
//bit14,?? ?接收到0x0d
//bit13~0,?? ?接收到的有效字節(jié)數(shù)目
u16 USART_RX_STA=0;
u16 USART3_RX_STA=0;?
//接收狀態(tài)標(biāo)記?? ? ?
? /*1、使能對應(yīng)串口使用的時鐘
2、對應(yīng)GPIO配置
3、中斷配置(中斷通道 優(yōu)先級)
4、串口相關(guān)參數(shù)配置(波特率 數(shù)據(jù)位 停止位 等)
5、設(shè)置使用的中斷
6、使能串口函數(shù)
*/
void uart1_init(u32 bound){
? ? //GPIO端口設(shè)置
?? ?GPIO_InitTypeDef GPIO_InitStructure;
?? ?USART_InitTypeDef USART_InitStructure;
?? ?NVIC_InitTypeDef NVIC_InitStructure;
?? ?//打開GPIOA時鐘和串口1時鐘
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
?? ?//配置PA.10復(fù)用推挽輸出
?? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
?? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
?? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
?? ?GPIO_Init(GPIOA,&GPIO_InitStructure);
?? ?//配置PA.9浮空輸入
?? ?GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
?? ?GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
?? ?GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
?? ?GPIO_Init(GPIOA,&GPIO_InitStructure);
?? ?//中斷參數(shù)配置
?? ?NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
?? ?NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
?? ?NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;在這里存在兩個優(yōu)先級,要區(qū)分不能一樣
?? ?NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
?? ?NVIC_Init(&NVIC_InitStructure);?? ?//根據(jù)指定的參數(shù)初始化VIC寄存器
?? ?//串口參數(shù)配置
?? ?USART_InitStructure.USART_BaudRate = bound;
?? ?USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件控制
?? ?USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//收發(fā)模式
?? ?USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗
?? ?USART_InitStructure.USART_StopBits = USART_StopBits_1;//1個停止位
?? ?USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位數(shù)據(jù)位
?? ?USART_Init(USART1,&USART_InitStructure);
?? ?
?? ?USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
?? ?USART_Cmd(USART1,ENABLE);
}
?
????????usart1的中斷服務(wù)函數(shù)過程,當(dāng)接收到從電腦發(fā)過來的數(shù)據(jù),把接收到的數(shù)據(jù)保存在 USART_RX_BUF 中,同時在接收狀態(tài)寄存器(USART_RX_STA)中計數(shù)接收到的有效數(shù)據(jù)個數(shù),當(dāng)收到回車(回車的表示由 2 個字節(jié)組成:0X0D 和 0X0A)的第一個字節(jié) 0X0D 時,計數(shù)器將不再增加,等待0X0A 的到來,而如果 0X0A 沒有來到,則認(rèn)為這次接收失敗,重新開始下一次接收。如果順利接收到 0X0A,則標(biāo)記 USART_RX_STA 的第 15 位,這樣完成一次接收,并等待該位被其他程序清除,從而開始下一次的接收,而如果遲遲沒有收到 0X0D,那么在接收數(shù)據(jù)超過 USART_REC_LEN 的時候,則會丟棄前面的數(shù)據(jù),重新接收。
當(dāng)接收到從電腦發(fā)過來的數(shù)據(jù),把接收到的數(shù)據(jù)保存在 USART_RX_BUF 中,同時在接收狀態(tài)寄存器(USART_RX_STA)中計數(shù)接收到的有效數(shù)據(jù)個數(shù),當(dāng)收到回車(回車的表示由 2 個字節(jié)組成:0X0D 和 0X0A)的第一個字節(jié) 0X0D 時,計數(shù)器將不再增加,等待0X0A 的到來,而如果 0X0A 沒有來到,則認(rèn)為這次接收失敗,重新開始下一次接收。如果順利接收到 0X0A,則標(biāo)記 USART_RX_STA 的第 15 位,這樣完成一次接收,并等待該位被其他程序清除,從而開始下一次的接收,而如果遲遲沒有收到 0X0D,那么在接收數(shù)據(jù)超過 USART_REC_LEN 的時候,則會丟棄前面的數(shù)據(jù),重新接收。
void USART1_IRQHandler(void) ? ? ? ? ? ? ? ??? ?//串口1中斷服務(wù)程序
{
?? ?u8 Res;
?? ?if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET) //接收標(biāo)志位是否為1
?? ?{
?? ??? ?Res = USART1->DR;//Res = USART_ReceiveData(USART1)
?? ??? ?if((USART_RX_STA&0x8000) != 1) //未接收完成
?? ??? ?{
?? ??? ??? ?if(USART_RX_STA & 0x4000) //接收0x0D完成 等待0x0A到來
?? ??? ??? ?{
?? ??? ??? ??? ?if(Res == 0x0A) ? //如果接收到0x0A 接收完成標(biāo)志位置1
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?USART_RX_STA |= 0x8000;
?? ??? ??? ??? ??? ?USART_ClearITPendingBit(USART1,USART_IT_RXNE);
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else?? ??? ??? ??? ?//接收失敗 重新接收
?? ??? ??? ??? ??? ?USART_RX_STA = 0;
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?if(Res == 0x0D) ?//接收到的數(shù)據(jù)是否為0x0D
?? ??? ??? ??? ??? ?USART_RX_STA |= 0x4000; //位14置1
?? ??? ??? ??? ?else //非0x0D 0x0A這兩個字符
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?USART_RX_BUF[USART_RX_STA&0x3FFF] = Res; //把數(shù)據(jù)給數(shù)組
?? ??? ??? ??? ??? ?USART_RX_STA++;?? ??? ??? ??? ??? ??? ??? ?//數(shù)組下標(biāo)增加
?? ??? ??? ??? ??? ?if(USART_RX_STA>USART_REC_LEN-1)
?? ??? ??? ??? ??? ??? ?USART_RX_STA=0;//接收數(shù)據(jù)錯誤,重新開始接收?? ?
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ??? ?
?? ?}
}?
void uart3_init(u32 bound)
?? ?{
?? ?//GPIO端口設(shè)置
?? ? GPIO_InitTypeDef GPIO_InitStructure;
? ? ?USART_InitTypeDef USART_InitStructure;?? ??? ?
?? ? NVIC_InitTypeDef NVIC_InitStructure;
? ? //打開GPIOA時鐘和串口1時鐘
?? ? ? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
?? ??? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
?? ?//配置PB11復(fù)用推挽輸出
?? ? GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
?? ? GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
? ? ?GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
?? ? GPIO_Init(GPIOB,&GPIO_InitStructure);
?? ? //配置PB10浮空輸入
?? ? GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
?? ? GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
? ? ?GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
?? ? GPIO_Init(GPIOB,&GPIO_InitStructure);?? ?
? ??? ? //中斷參數(shù)配置
?? ? NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
?? ? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
?? ? NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;
?? ? NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
?? ? NVIC_Init (&NVIC_InitStructure);
?? ? //串口參數(shù)配置
?? ? USART_InitStructure.USART_BaudRate = bound;
?? ? USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//無硬件控制
?? ? USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;//收發(fā)模式
?? ? USART_InitStructure.USART_Parity = USART_Parity_No;//無奇偶校驗
?? ? USART_InitStructure.USART_StopBits = USART_StopBits_1;//1個停止位
?? ? USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8位數(shù)據(jù)位
?? ? USART_Init(USART3,&USART_InitStructure);
?? ??
?? ? USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
?? ? USART_Cmd(USART3,ENABLE);
?}
u8 Flag = 0;? ? 這里的flag作為一個標(biāo)志位,用于打印在串口助手
void USART3_IRQHandler(void) ? ? ? ? ? ? ? ??? ?//串口3中斷服務(wù)程序
{
?? ?u8 Res;
?? ?if(USART_GetITStatus(USART3,USART_IT_RXNE) == SET) //接收標(biāo)志位是否為1
?? ?{
?? ??? ?USART_ClearITPendingBit(USART3,USART_IT_RXNE);
?? ??? ?Res = USART3->DR;//Res = USART_ReceiveData(USART3)
?? ??? ?USART3_RX_BUF[USART_RX_STA&0x3FFF] = Res; //把數(shù)據(jù)給數(shù)組
?? ??? ?USART3_RX_STA++;?? ?
?? ??? ?Flag = 1;
?? ??? ?
?? ?}
}
#endif?? ?
?2.其次在.h文件中聲明
#ifndef __USART_H
#define __USART_H
#include "stdio.h"?? ?
#include "sys.h"?
#define USART_REC_LEN ??? ??? ??? ?200 ??? ?//定義最大接收字節(jié)數(shù) 200
#define EN_USART1_RX ?? ??? ??? ?1?? ??? ?//使能(1)/禁止(0)串口1接收
?? ? ??? ?
extern u8 ?USART_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節(jié).末字節(jié)為換行符?
extern u16 USART_RX_STA; ? ? ? ? ?? ??? ?//接收狀態(tài)標(biāo)記?? ?
extern u8 ?USART3_RX_BUF[USART_REC_LEN]; //接收緩沖,最大USART_REC_LEN個字節(jié).末字節(jié)為換行符?
extern u16 USART3_RX_STA;?
extern u8 Flag;
void uart3_init(u32 bound);
void uart1_init(u32 bound);
#endif
3.主函數(shù)程序,運(yùn)行文章來源:http://www.zghlxwxcb.cn/news/detail-405498.html
int main()
{
?? ?u8 i = 0,len;
?? ?NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
?? ?uart3_init(9600);
?? ?uart1_init(9600);
?? ?
?? ?while(1)
?? ?{
?? ??? ?if(Flag == 1)
?? ??? ?{
?? ??? ??? ?printf("%s",USART3_RX_BUF);
?? ??? ??? ?//USART3_RX_STA=0;
?? ??? ??? ?//memset(USART3_RX_BUF,0,sizeof(USART3_RX_BUF));
?? ??? ??? ?Flag = 0;
?? ??? ?}
?? ??? ?
?? ??? ?if(USART_RX_STA&0x8000)
?? ??? ?{
?? ??? ??? ?len=USART_RX_STA&0x3FFF;
?? ??? ??? ?for(i = 0;i<len;i++)
?? ??? ??? ?{
?? ??? ??? ??? ?
?? ??? ??? ??? ?USART_SendData(USART3,USART_RX_BUF[i]);將存入數(shù)組的數(shù)據(jù),發(fā)送到串口3
?? ??? ??? ??? ?while((USART3->SR&0x40) == 0);//等待發(fā)送結(jié)束 ?讀取USART1 SR寄存器狀態(tài)為0表示發(fā)送未完成 1為發(fā)送完成 (判斷發(fā)送是否成功)
?? ??? ??? ?}
?? ??? ??? ?printf("%s",USART_RX_BUF);
?? ??? ??? ?memset(USART_RX_BUF,0,sizeof(USART_RX_BUF));
?? ??? ??? ?USART_RX_STA = 0;
?? ??? ?}
?? ?}
}文章來源地址http://www.zghlxwxcb.cn/news/detail-405498.html
到了這里,關(guān)于stm32藍(lán)牙模塊通過手機(jī)和電腦雙向通信的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!