- 浏览: 718648 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
xuelj:
我的Android进阶之旅------>Android使用9Patch图片作为不失真背景 -
lBovinl:
,浩瀚~
我的Android进阶之旅------>经典的大客推荐(排名不分先后)!! -
xyy_zero:
看着听犀利的,大神,有demo吗?可以分享下不。我最近需要开发 ...
给android设备增加串口功能
给android设备增加串口功能
给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_BAUD 9600 //定义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_BUF 512 struct _FIFO_Stack { unsigned char buf[LEN_BUF]; short ptr_r; short ptr_w; }; //数据流式符合字符串头检索 #define LEN_MATCH_STRING_HEADER 9 struct _match_string_header { char match[LEN_MATCH_STRING_HEADER]; int state; }; //数据流式符合字符串尾检索,并提取数据结构 #define LEN_MATCH_STRING_TAIL 3 struct _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; //捕获数据状态或是捕获字符尾状态 }; //修改flash struct _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); //读取全部 //成功返回字节数,失败返回-1 short read_all_fifo_stack(struct _FIFO_Stack *stack,unsigned char *buf); //写入1个字节 //失败返回-1,成功返回1 int write_byte_fifo_stack(struct _FIFO_Stack *stack,unsigned char byte); //数据流式符合字符串头检索方法 //初始化 //成功返回1,失败返回0 int 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,失败返回0 int 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个半字 //成功返回写入的字节数,失败返回-1 int write_flash(unsigned short *buf); //读取flash,读取1024字节,512半字 //成功返回读取的字节数,失败返回-1 int read_flash(unsigned short *buf); //读取flash,获得flag和baud //成功返回波特率,失败返回-1 int read_baud(struct _edit_flash *edit); //写入波特率到flash //成功返回1,失败返回0 int 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); } //读取全部 //成功返回字节数,失败返回0 short 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,成功返回1 int 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,失败返回0 int 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,失败返回0 int 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,没有则置1 WRPR_Value = FLASH_GetWriteProtectionOptionByte(); //需要写保护的页面置1,不需要的置0 ProtectedPages = ~(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个半字 //成功返回写入的字节数,失败返回-1 int 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,没有则置1 WRPR_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半字 //成功返回读取的字节数,失败返回-1 int 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 //成功返回波特率,失败返回-1 int 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,失败返回0 int 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); //接收数据,整理除去前两位 //写入fifo write_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); //写入fifo write_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的接收fifo init_fifo_stack(&fifo_uart2); //初始化uart1的接收fifo init_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; //中断占先等级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //打开中断 NVIC_Init(&NVIC_InitStructure); //初始化 //配置UART2中断 NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; //通道设置为串口1中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //中断占先等级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //中断响应优先级0 NVIC_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; //管脚9 GPIO_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; //管脚10 GPIO_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; //管脚9 GPIO_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; //管脚10 GPIO_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; //管脚9 GPIO_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); //写入到flash write_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默认是没有标准串口的api的,这个包增加了jni来访问linux串口设备,以及增加java api来访问,有完整的示例代码。
android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo 代码简单 无bug 完美运行 android 串口测试demo...
Android串口通信(Android Studio) serial Port 简单的demo 好久之前整的
Android系统访问串口设备源码,android源码,0分下载了
在通过网络查找,参考各位大能给的信息,重新修改了SerialPort.c,修改了打开串口参数,满足设置停止位、奇偶校验停止位功能。 修改了端口读取阻塞模式为非阻塞模式,增加一个清除端口数据函数。同时已经编译过了,...
Android串口开发框架 Android串口开发框架 Android串口开发框架
Android 串口通信权限问题Android 串口通信权限问题Android 串口通信权限问题Android 串口通信权限问题
android串口通讯,用导线连接串口收发口测试,打开,关闭,收发数据正常。 Android Studio项目,导入直接使用,含apk文件,使用SerialPort开发。
Android高级应用源码-Android系统访问串口设备源码.zip
安卓Android源码——安卓Android系统访问串口设备源码.zip
自动读取串口列表,支持收发Hex与txt切换,支持循环自动发送,支持定时发送,APP串口调试功能均在一个界面操作,无需来回切换配置,界面操作清晰明了
android usb转串口数据通信示例(源代码) android usb转串口数据通信示例。物联网开发中也会经常用到usb转串口,对android手机进行通信。一般都会用otc线进行转换。我在GitHub下来一份代码,亲测可用。并进行了修改...
在单板机承载的Android系统中,通过串口以Modbus RTU协议操控PLC的类库。改编自python类库modbus_tk。
Android Studio开发的串口调试助手源码,支持串口扫描、字符串和十六进数据制显示和发送等功能。
android studio可以直接运行,已经封装好了,可以直接使用,串口直接调用连接就好,不需判断是否连接上,断开重连自动化
网上好多不会修改android串口的权限,上传脚本文件供大家使用,公司真实环境无私奉献出来。
Android 平台提供了丰富的功能和接口,开发人员可以使用 Java 或 Kotlin 等编程语言编写 Android 应用程序。Android 项目也可以是针对特定设备或特定需求进行自定义开发的软件解决方案。 以下是 Android 项目的一些...
android RS232串口读写程序,内含jni程序代码,使用android studio打开编译