给android设备增加串口功能
来源:互联网 发布:java log4j 用法 编辑:程序博客网 时间:2024/04/30 19:43
给android设备增加串口功能
本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.
环境:
主机:WIN7
开发环境:MDK4.23
功能:
打开Android手机或者平台的蓝牙,通过蓝牙连接蓝牙转串口板,通过蓝牙转串口板的串口与需要调试的串口设备相连
说明:
1.PCB为我同学hunter绘制,他同时是stm32的高手,感谢他提供的支持.
2.制作了一个蓝牙转串口的板子,Android设备连接上这个板子,就相当于增加了一个串口.
3.单片机选用的是STM32F101C8,蓝牙模块选用的是HC05.HC05本身就是一个蓝牙转串口模块,再增加一个单片机的作用是可以通过单片机来配置波特率等参数.
4.蓝牙转串口板可以用MINI USB来供电,或者用3.7V锂电池来供电,板子上带有充电管理芯片,由于没锂电池,充电这块还没有测试.
5.上位机程序(Android上的串口助手)暂时没有时间写,可以在安卓市场上搜索"蓝牙串口"下一个串口助手.
6.在上位机发送指定格式可以配置波特率,例:AT+BAUD9600END
实物图:
电路图:
第1部分:
图片较大,部分没有显示.可以在新窗口打开图片来看到全部内容
第2部分:
下位机程序:
public.h
#ifndef _PUBLIC_H_#define _PUBLIC_H_//公共头文件#include "main.h"#include "string.h"#include "stdlib.h"#include "stm32f10x_tim.h"//宏定义#define U8 unsigned char#define U16 unsigned short#define U32 unsigned long//蓝牙转串口的缓存长度#define LEN_BT_STACK 10//蓝牙波特率设置命令#define BT_BAUD_4800"AT+UART=4800,0,0"#define BT_BAUD_9600 "AT+UART=9600,0,0"#define BT_BAUD_19200"AT+UART=19200,0,0"#define BT_BAUD_38400"AT+UART=38400,0,0"#define BT_BAUD_57600"AT+UART=57600,0,0"#define BT_BAUD_115200"AT+UART=115200,0,0"#define DEFAULT_BAUD9600//定义flash页大小#if defined (STM32F10X_HD) || defined (STM32F10X_HD_VL) || (STM32F10X_CL) || defined (STM32F10X_XL) #define FLASH_PAGE_SIZE ((uint16_t)0x800) #define FLASH_PAGES_TO_BE_PROTECTED (FLASH_WRProt_Pages12to13 | FLASH_WRProt_Pages14to15) #else #define FLASH_PAGE_SIZE ((uint16_t)0x400) //需要关闭写保护的页面 #define FLASH_PAGES_TO_BE_PROTECTED (FLASH_WRProt_Pages60to63) #endif//定义操作的flash的始末地址63K-64K#define BANK1_WRITE_START_ADDR ((uint32_t)0x0800FC00)#define BANK1_WRITE_END_ADDR ((uint32_t)0x08010000)//数据结构//通过蓝牙发过来的串口2的数据堆栈//数据结构为循环队列,读写缓冲#define LEN_BUF512struct _FIFO_Stack{unsigned char buf[LEN_BUF];short ptr_r;short ptr_w;};//数据流式符合字符串头检索#define LEN_MATCH_STRING_HEADER 9struct _match_string_header{char match[LEN_MATCH_STRING_HEADER];int state;};//数据流式符合字符串尾检索,并提取数据结构#define LEN_MATCH_STRING_TAIL 3struct _match_string_tail{char match[LEN_MATCH_STRING_TAIL];int state;//当前状态/下标int value;//最后取得的值int max_len;//数据最大长度char capture_string[10];int capture_index;//当前捕获数据下标struct _match_string_header match_string_header;//用来比较尾是否正确int flag;//捕获数据状态或是捕获字符尾状态};//修改flashstruct _edit_flash{unsigned short buf[512];int flag;//判断flash是否被修改过int baud;//需要写入/读出的波特率};//公共变量//声明串口结构体extern USART_InitTypeDef USART_InitStructure;//声明FIFO堆栈给UART2使用extern struct _FIFO_Stack fifo_uart2;//声明FIFO堆栈给UART1使用extern struct _FIFO_Stack fifo_uart1;//声明修改flash结构体extern struct _edit_flash edit_flash;//公共函数//按照蓝牙转串口的格式发送指令void send_bt_cmd(char *str);//循环缓冲方法//初始化void init_fifo_stack(struct _FIFO_Stack *stack);//读取全部//成功返回字节数,失败返回-1short read_all_fifo_stack(struct _FIFO_Stack *stack,unsigned char *buf);//写入1个字节//失败返回-1,成功返回1int write_byte_fifo_stack(struct _FIFO_Stack *stack,unsigned char byte);//数据流式符合字符串头检索方法//初始化//成功返回1,失败返回0int init_match_string_header(struct _match_string_header *m_str,char *buf);//返回-1失败,返回0正在运行,返回1成功int match_string_header_state(struct _match_string_header *m_str,char ch);//数据流式符合字符串尾检索,并提取数据结构方法//初始化//成功返回1,失败返回0int init_match_string_tail(struct _match_string_tail *m_str,char *buf,int max_len);//返回-1失败,返回0正在运行,成功返回得到的数据int match_string_tail_state(struct _match_string_tail *m_str,char ch);//flash操作//打开需要操作页面的写保护void open_write_lock();//向flash中写入数据,1024字节,512个半字//成功返回写入的字节数,失败返回-1int write_flash(unsigned short *buf);//读取flash,读取1024字节,512半字//成功返回读取的字节数,失败返回-1int read_flash(unsigned short *buf);//读取flash,获得flag和baud//成功返回波特率,失败返回-1int read_baud(struct _edit_flash *edit);//写入波特率到flash//成功返回1,失败返回0int write_baud(struct _edit_flash *edit,int baud);#endif
public.c:
#include "public.h"//公共变量//定义串口结构体USART_InitTypeDef USART_InitStructure;//声明FIFO堆栈给UART2使用struct _FIFO_Stack fifo_uart2;//声明FIFO堆栈给UART1使用struct _FIFO_Stack fifo_uart1;//声明修改flash结构体struct _edit_flash edit_flash;//按照蓝牙转串口的格式发送指令void send_bt_cmd(char *str){while(*str != '\0'){ USART_SendData(USART2,*str++); //发送一位数据while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET){} //等待字符发送完毕}USART_SendData(USART2,'\r'); //发送一位数据while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET){} //等待字符发送完毕USART_SendData(USART2,'\n'); //发送一位数据while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET){} //等待字符发送完毕}//循环缓冲方法//初始化void init_fifo_stack(struct _FIFO_Stack *stack){stack->ptr_r = 0;stack->ptr_w = 0;memset(stack->buf,0,LEN_BUF);}//读取全部//成功返回字节数,失败返回0short read_all_fifo_stack(struct _FIFO_Stack *stack,unsigned char *buf){short i = 0;short j = 0;short len = 0;short len2 = 0;//如果已经读完,则不读if (stack->ptr_r - stack->ptr_w == 0 || \stack->ptr_r - stack->ptr_w == -1){ return -1;}//如果读指针小于写指针if (stack->ptr_r < stack->ptr_w){len = stack->ptr_w - stack->ptr_r; for(i = 0;i < len;i++){ buf[i] = stack->buf[stack->ptr_r++];}return len;}else{ //读指针大于写指针的情况len = (LEN_BUF - 1) - stack->ptr_r + 1;len2 = stack->ptr_w; for (i = 0;i < len;i++){ buf[j++] = stack->buf[stack->ptr_r++];}stack->ptr_r = 0;for (i = 0;i < len2;i++){ buf[j++] = stack->buf[stack->ptr_r++];}return (len + len2);}}//写入1个字节//失败返回-1,成功返回1int write_byte_fifo_stack(struct _FIFO_Stack *stack,unsigned char byte){//如果已经写完,则不写if (stack->ptr_w - stack->ptr_r == -1){ return -1;}stack->buf[stack->ptr_w++] = byte;//判断是否已经写满if (stack->ptr_w == LEN_BUF){ stack->ptr_w = 0;}}//数据流式符合字符串头检索方法//初始化//成功返回1,失败返回0int init_match_string_header(struct _match_string_header *m_str,char *buf){int len = 0;int i = 0;len = strlen(buf);if (len > LEN_MATCH_STRING_HEADER){return 0;}m_str->state = 0;for (i = 0;i < len;i++){m_str->match[i] = buf[i];}m_str->match[i] = '\0';return 1;}//返回-1失败,返回0正在运行,返回1成功int match_string_header_state(struct _match_string_header *m_str,char ch){if (ch == m_str->match[m_str->state]){m_str->state++;if (m_str->match[m_str->state] == '\0'){m_str->state = 0;return 1;}else{return 0;}}else{m_str->state = 0;return -1;}}//数据流式符合字符串尾检索,并提取数据结构方法//初始化//成功返回1,失败返回0int init_match_string_tail(struct _match_string_tail *m_str,char *buf,int max_len){int len = 0;int i = 0;len = strlen(buf);if (len > LEN_MATCH_STRING_TAIL){return 0;}m_str->state = 0;m_str->value = 0;m_str->max_len = max_len;m_str->capture_index = 0;m_str->flag = 0;for (i = 0;i < len;i++){m_str->match[i] = buf[i];}m_str->match[i] = '\0';init_match_string_header(&(m_str->match_string_header),m_str->match);return 1;}//返回-1失败,返回0正在运行,成功返回得到的数据int match_string_tail_state(struct _match_string_tail *m_str,char ch){int flag = 0;//判断是否捕获数据状态还是捕获字符尾状态if (m_str->flag || ch == 'E'){//捕获字符尾状态m_str->flag = 1;flag = match_string_header_state(&(m_str->match_string_header),ch);if (flag == -1){//初始化数据m_str->state = 0;m_str->capture_index = 0;m_str->flag = 0;}if (flag == 1){m_str->capture_string[m_str->capture_index] = '\0';m_str->value = atoi(m_str->capture_string);//初始化数据m_str->state = 0;m_str->capture_index = 0;m_str->flag = 0;return m_str->value;}return flag;}else{//捕获数据状态if (ch < '0' || ch > '9'){return -1;}//当已经达到最大数据长度且当前数据不是//当不是数据字符返回错误if (m_str->capture_index >= m_str->max_len){m_str->state = 0;m_str->capture_index = 0;m_str->flag = 0;return -1;}else{m_str->capture_string[m_str->capture_index++] = ch;//如果达到最大长度,则置为捕获字符状态if (m_str->capture_index >= m_str->max_len){m_str->flag = 1;}return 0;}}}//打开需要操作页面的写保护void open_write_lock(){uint32_t WRPR_Value = 0xFFFFFFFF, ProtectedPages = 0x0;volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;//解锁flash控制器FLASH_Unlock();//得到所有已经被写保护的页面号,如果被写保护则置0,没有则置1WRPR_Value = FLASH_GetWriteProtectionOptionByte();//需要写保护的页面置1,不需要的置0ProtectedPages = ~(WRPR_Value | FLASH_PAGES_TO_BE_PROTECTED);//检查需要的页是否被写保护if((WRPR_Value | (~FLASH_PAGES_TO_BE_PROTECTED)) != 0xFFFFFFFF ){//擦除小信息模块,关闭写保护FLASHStatus = FLASH_EraseOptionBytes();//如果不是所有页面都需要打开写保护if(ProtectedPages != 0x0){ //将其他页面置位写保护 FLASHStatus = FLASH_EnableWriteProtection(ProtectedPages);}//复位系统,重新载入小信息NVIC_SystemReset();}}//向flash中写入数据,1024字节,512个半字//成功返回写入的字节数,失败返回-1int write_flash(unsigned short *buf){uint32_t EraseCounter = 0x0,Address = 0x0;uint32_t WRPR_Value = 0xFFFFFFFF;uint32_t NbrOfPage;volatile FLASH_Status FLASHStatus = FLASH_COMPLETE;int i = 0;//得到需要操作的页面数NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FLASH_PAGE_SIZE;//得到所有已经被写保护的页面号,如果被写保护则置0,没有则置1WRPR_Value = FLASH_GetWriteProtectionOptionByte();//判断此页面是否被写保护,如果没有写保护则进行操作if ( (WRPR_Value & FLASH_PAGES_TO_BE_PROTECTED) != 0x00){//清除所有等待标志位FLASH_ClearFlag(FLASH_FLAG_BSY | FLASH_FLAG_EOP|FLASH_FLAG_PGERR |FLASH_FLAG_WRPRTERR);//擦数指定页面for(EraseCounter = 0; (EraseCounter < NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter++){ FLASHStatus = FLASH_ErasePage(BANK1_WRITE_START_ADDR + (FLASH_PAGE_SIZE * EraseCounter));}//得到操作flash的起始地址Address = BANK1_WRITE_START_ADDR;//写flash,每次写2个字节while((Address < BANK1_WRITE_END_ADDR) && (FLASHStatus == FLASH_COMPLETE)){FLASHStatus = FLASH_ProgramHalfWord(Address, buf[i++]);Address = Address + 2;}return i;}else{ return -1;}}//读取flash,读取1024字节,512半字//成功返回读取的字节数,失败返回-1int read_flash(unsigned short *buf){uint32_t Address = 0x0;int i = 0;//得到操作flash的起始地址Address = BANK1_WRITE_START_ADDR;//读flash,每次读两个字节while((Address < BANK1_WRITE_END_ADDR)){buf[i++] = *(__IO uint16_t*) Address;Address += 2;}return i;}//修改flash结构的方法//初始化void init_edit_flash(struct _edit_flash *edit){ edit->flag = 0;edit->baud = 0;memset(edit->buf,0,512);}//读取flash,获得flag和baud//成功返回波特率,失败返回-1int read_baud(struct _edit_flash *edit){read_flash(edit->buf);edit->flag = edit->buf[0];edit->baud = edit->buf[1] << 16;edit->baud += edit->buf[2];if (edit->flag == 0xa5){ return (edit->baud);}else{ return -1;}}//写入波特率到flash//成功返回1,失败返回0int write_baud(struct _edit_flash *edit,int baud){edit->buf[0] = 0xa5;edit->buf[1] = baud >> 16;edit->buf[2] = baud & 0xffff;if (write_flash(edit->buf) > 0){edit->flag = 0xa5;edit->baud = baud; return 1;}else{ return 0;}}stm32f10x_it.c:(串口中断文件)
/** ****************************************************************************** * @file SysTick/stm32f10x_it.c * @author MCD Application Team * @version V3.4.0 * @date 10/15/2010 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and peripherals * interrupt service routine. ****************************************************************************** * @copy * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2> */ /* Includes ------------------------------------------------------------------*/#include "stm32f10x_it.h"#include "main.h"#include "public.h"/** @addtogroup STM32F10x_StdPeriph_Examples * @{ *//** @addtogroup SysTick * @{ *//* Private typedef -----------------------------------------------------------*//* Private define ------------------------------------------------------------*//* Private macro -------------------------------------------------------------*//* Private variables ---------------------------------------------------------*//* Private function prototypes -----------------------------------------------*//* Private functions ---------------------------------------------------------*//******************************************************************************//* Cortex-M3 Processor Exceptions Handlers *//******************************************************************************//** * @brief This function handles NMI exception. * @param None * @retval None */void NMI_Handler(void){}/** * @brief This function handles Hard Fault exception. * @param None * @retval None */void HardFault_Handler(void){ /* Go to infinite loop when Hard Fault exception occurs */ while (1) { }}/** * @brief This function handles Memory Manage exception. * @param None * @retval None */void MemManage_Handler(void){ /* Go to infinite loop when Memory Manage exception occurs */ while (1) { }}/** * @brief This function handles Bus Fault exception. * @param None * @retval None */void BusFault_Handler(void){ /* Go to infinite loop when Bus Fault exception occurs */ while (1) { }}/** * @brief This function handles Usage Fault exception. * @param None * @retval None */void UsageFault_Handler(void){ /* Go to infinite loop when Usage Fault exception occurs */ while (1) { }}/** * @brief This function handles SVCall exception. * @param None * @retval None */void SVC_Handler(void){}/** * @brief This function handles Debug Monitor exception. * @param None * @retval None */void DebugMon_Handler(void){}/** * @brief This function handles PendSV_Handler exception. * @param None * @retval None */void PendSV_Handler(void){}/** * @brief This function handles SysTick Handler. * @param None * @retval None */void SysTick_Handler(void){ TimingDelay_Decrement();}/******************************************************************************//* STM32F10x Peripherals Interrupt Handlers *//* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the *//* available peripheral interrupt handler's name please refer to the startup *//* file (startup_stm32f10x_xx.s). *//******************************************************************************//** * @brief This function handles PPP interrupt request. * @param None * @retval None *//*void PPP_IRQHandler(void){}*//** * @} */ /** * @} */ //串口1接收中断//与真实串口通信void USART1_IRQHandler(void) {unsigned char rx_dat; if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断发生接收中断{USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志rx_dat = USART_ReceiveData(USART1); //接收数据,整理除去前两位//写入fifowrite_byte_fifo_stack(&fifo_uart1,rx_dat);}}//返回src中dst字符串的标号,正确返回标号,失败返回-1//src:源字符串//dst:目标字符串//len:源字符串比较的长度int index_of_string(char *src,char *dst,int len){int size_dst = 0;int i = 0;int j = 0;//获得目标字符串长度size_dst = strlen(dst);//如果len小于目标字符串长度,返回失败if (len < size_dst){return 0;}for (i = 0;i <= len - size_dst;i++){for (j = 0;j < size_dst;j++){if (src[i + j] != dst[j]){break;}}if (j == size_dst){return i;}}return -1;}//串口2接收中断//与蓝牙串口模块通信void USART2_IRQHandler(void) {unsigned char rx_dat; if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //判断发生接收中断{//清除中断标志USART_ClearITPendingBit(USART2, USART_IT_RXNE); //接收数据 rx_dat = USART_ReceiveData(USART2); //写入fifowrite_byte_fifo_stack(&fifo_uart2,rx_dat);}}/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
main.c:(主文件)
/* 功能:蓝牙转串口模块 作者:jdh时间:2012-2-27*/#include "public.h"static __IO uint32_t TimingDelay;//定义GPIO结构体GPIO_InitTypeDef GPIO_InitStructure;/* Private function prototypes -----------------------------------------------*/void Delay(__IO uint32_t nTime);//初始化内部晶振static void RCC_Config(void){ //将外设 RCC寄存器重设为缺省值 RCC_DeInit(); //内部晶振使能 RCC_HSICmd(ENABLE); //使能外部晶振 //SystemInit(); //等待工作稳定 while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); if(1) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); FLASH_SetLatency(FLASH_Latency_2);//高速时钟 RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); //设置 PLL 时钟源及倍频系数 RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9); //使能或者失能 PLL,这个参数可以取:ENABLE或者DISABLE RCC_PLLCmd(ENABLE);//如果PLL被用于系统时钟,那么它不能被失能 //等待指定的 RCC 标志位设置成功 等待PLL初始化成功 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //设置系统时钟(SYSCLK) 设置PLL为系统时钟源 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //等待PLL成功用作于系统时钟的时钟源 // 0x00:HSI 作为系统时钟 // 0x04:HSE作为系统时钟 // 0x08:PLL作为系统时钟 while(RCC_GetSYSCLKSource() != 0x08); }} //设置串口波特率void set_uart_baud(int num,int baud){if (num == 1){//更新串口波特率USART_Cmd(USART1,DISABLE);USART_InitStructure.USART_BaudRate = baud;USART_Init(USART1,&USART_InitStructure);USART_Cmd(USART1, ENABLE);}if (num == 2){//更新串口波特率USART_Cmd(USART2,DISABLE);USART_InitStructure.USART_BaudRate = baud;USART_Init(USART2,&USART_InitStructure);USART_Cmd(USART2, ENABLE);}}//初始化void init(){//定义中断结构体NVIC_InitTypeDef NVIC_InitStructure;//初始化结构体 GPIO_StructInit(&GPIO_InitStructure);//初始化uart2的接收fifoinit_fifo_stack(&fifo_uart2);//初始化uart1的接收fifoinit_fifo_stack(&fifo_uart1);//中断NVIC设置:允许中断,设置优先级 NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //更新事件 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //响应优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //允许中断 NVIC_Init(&NVIC_InitStructure); //写入设置 //RCC_Config();//打开串口对应的外设时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE); //初始化参数USART_InitStructure.USART_BaudRate = DEFAULT_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(USART1,&USART_InitStructure);//初始化参数USART_InitStructure.USART_BaudRate = DEFAULT_BAUD;USART_Init(USART2,&USART_InitStructure);//TXE发送中断,TC传输完成中断,RXNE接收中断,PE奇偶错误中断,可以是多个 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//配置UART1中断NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//通道设置为串口1中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断NVIC_Init(&NVIC_InitStructure); //初始化//配置UART2中断NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;//通道设置为串口1中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断NVIC_Init(&NVIC_InitStructure); //初始化//启动串口USART_Cmd(USART1, ENABLE); USART_Cmd(USART2, ENABLE); //设置IO口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //串口1的管脚初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //管脚9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //选择GPIO响应速度GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //TX初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //管脚10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //选择GPIO响应速度GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //RX初始化 //设置IO口时钟 //RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //串口2的管脚初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //管脚9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //选择GPIO响应速度GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure); //TX初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //管脚10GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //选择GPIO响应速度GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure); //RX初始化 /* Setup SysTick Timer for 1 msec interrupts */if (SysTick_Config(SystemCoreClock / 1000)){ /* Capture error */ while (1);}//设置IO口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //管脚9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; //选择GPIO响应速度GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出//初始化修改flash结构init_edit_flash(&edit_flash);//打开需要操作页面的写保护open_write_lock();}init_blue(int baud){//置高AT_EN脚 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_0);send_bt_cmd("AT+INIT");Delay(100);send_bt_cmd("AT+CMODE=1"); Delay(100); switch (baud){case 4800:{send_bt_cmd("AT+UART=4800,0,0"); Delay(100); break;}case 9600:{send_bt_cmd("AT+UART=9600,0,0"); Delay(100); break;}case 19200:{send_bt_cmd("AT+UART=19200,0,0"); Delay(100); break;}case 38400:{send_bt_cmd("AT+UART=38400,0,0"); Delay(100); break;}case 57600:{send_bt_cmd("AT+UART=57600,0,0"); Delay(100); break;}case 115200:{send_bt_cmd("AT+UART=115200,0,0"); Delay(100); break;}default:{send_bt_cmd("AT+UART=9600,0,0"); Delay(100); break;}}//置低AT_EN脚 GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_ResetBits(GPIOB,GPIO_Pin_0); }int main(void){ struct _match_string_header match_string_header;struct _match_string_tail match_string_tail;unsigned char buffer[LEN_BUF];unsigned char buffer1[LEN_BUF];int len = 0;int i = 0;int flag = 0;int flag2 = 0;int flag3 = 0;int baud = 0;//初始化系统init();//初始化蓝牙//读取flash中波特率write_baud(&edit_flash,9600);baud = read_baud(&edit_flash);//读取有效if (baud > 0){ set_uart_baud(1,baud);set_uart_baud(2,baud);}else{//设置默认波特率set_uart_baud(1,DEFAULT_BAUD); set_uart_baud(2,DEFAULT_BAUD);}//设置默认波特率Delay(10);init_blue(DEFAULT_BAUD);set_uart_baud(1,DEFAULT_BAUD);set_uart_baud(2,DEFAULT_BAUD);Delay(500);init_blue(DEFAULT_BAUD);set_uart_baud(1,DEFAULT_BAUD);set_uart_baud(2,DEFAULT_BAUD);//初始化匹配字符init_match_string_header(&match_string_header,"AT+BAUD");init_match_string_tail(&match_string_tail,"END",8);while (1){//读取fifo_uart1中所有数据len = read_all_fifo_stack(&fifo_uart1,buffer1);//处理for (i = 0;i < len;i++){ USART_SendData(USART2,buffer1[i]); //发送数据while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET){}//等待发送结束}//读取fifo_uart2中所有数据len = read_all_fifo_stack(&fifo_uart2,buffer);//处理for (i = 0;i < len;i++){ if (flag == 0){flag3 = match_string_header_state(&match_string_header,buffer[i]);if (flag3 == 1){flag = 1;}}else{flag2 = match_string_tail_state(&match_string_tail,buffer[i]);if (flag2 > 0){if (flag2 == 4800 || flag2 == 9600 || flag2 == 19200 || flag2 == 38400 || flag2 == 115200){//重启蓝牙init_blue(flag2);//更新串口波特率set_uart_baud(1,flag2);//写入到flashwrite_baud(&edit_flash,flag2);//返回成功 send_bt_cmd("set baud successful\n");flag = 0;continue;}else{ send_bt_cmd("set baud fail\n");}}}//转发数据USART_SendData(USART1,buffer[i]); //发送数据while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET){}//等待发送结束}}}/** * @brief Inserts a delay time. * @param nTime: specifies the delay time length, in milliseconds. * @retval None */void Delay(__IO uint32_t nTime){ TimingDelay = nTime; while(TimingDelay != 0);}/** * @brief Decrements the TimingDelay variable. * @param None * @retval None */void TimingDelay_Decrement(void){ if (TimingDelay != 0x00) { TimingDelay--; }}#ifdef USE_FULL_ASSERT/** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */void assert_failed(uint8_t* file, uint32_t line){ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { }}#endif
- 给android设备增加串口功能
- 给Android设备增加串口功能
- 给oscinventory增加记录设备变化的功能
- 增加Input设备功能
- 全志Android设备增加Usb host ADK 功能
- 给JavaBeans 增加XPath功能
- 给ASP增加绘图功能
- 给ASP增加绘图功能
- django给admin增加功能
- 串口调试Android设备
- Android系统访问串口设备
- Android系统访问串口设备
- Android系统访问串口设备
- Android系统访问串口设备
- Android系统访问串口设备
- 给BLOG增加了一个在线音乐功能
- 给IE的右键菜单增加功能
- 给MS SQL增加自动编号功能
- 【搬家】VB.NET开发全功能串口调试助手
- G711 G723 G729线路占多少带宽问题
- 设置输入法弹出时,处于焦点状态的控件所在界面保持原样
- Singleton 单例模式 -IOS开发
- pointer endianess sizeof()
- 给android设备增加串口功能
- 深入JVM之根类加载器的测试
- Oracle约束的4种状态小结
- 如何编写HTTP Servlet程序
- ftok的陷阱
- 对INIT_WORK的理解
- 深入JVM之类的主动使用和final关键字
- 开源软件_源码SVN地址
- 来来来