基于51单片机蓝牙直流电机控制(IR2104S驱动H桥)

2023-05-16

主要目标:
(1)用51系列单片机作为控制器;
(2)采用由四个MOS管组成的H桥电机驱动电路,并由IR2104S来驱动H桥;
(3)可实现电机正、反转,启停,加、减速;
(4)可采用蓝牙、按键进行效果切换,并加有LED灯(左、右方向灯)及蜂鸣器报警电路(转向时报警);
(5)采用5V直流稳压电源;

主要内容:
1、最小系统设计;
2、综合布局设计;
3、蓝牙控制C程序设计;
4、按键控制C程序设计;
5、方向灯及蜂鸣器C程序设计;
6、仿真观察实验效果;
7、电路焊接与调试;

要实现所要求的功能首先需要规划硬件模块,所需的元件为STC89C52RC芯片,12MHZ晶振,直流单机,IR2104S,MOS管IRF740,HC-05蓝牙模块,电容电阻导线若干,红、黄LED若干、按键若干、USB-TTL模块,三极管8050及8550以及蜂鸣器等一些其他模块。

首先先要实现最小系统的正常运行,单片机最小系统由单片机、晶振电路、复位电路、电源模块构成,硬件电路图会在下面给出的。实现了最小系统的运行后要开始考虑如何实现电机的驱动及状态控制, H桥由四个MOS管组成,全桥驱动可以由实现电机正反转,通过改变MOS开断的时间即通过给PWM波的方式来实现电机调速,可以选用IRF2104S来驱动H桥,需要通过蓝牙,按键切换可以判断出在编程的时候需要用到中断的知识,按下按键打开中断,来执行中断服务程序,具体可以通过代码的编写来实现,下面会对其有详细的叙述;在此次设计中我设计的功能:可实现电机调速,蓝牙控制,LED方向灯显示,蜂鸣器转向报警,在硬件焊接方面需要注意P0口要加上拉电阻、电解电容正负极不能接反等,焊接完成后需要进行电路的测试。

硬件电路图:
在这里插入图片描述

1.IRS2104S驱动电路:

在这里插入图片描述
图1-H桥
图一以四个IR740组成的H桥为基础,通过两个IR2104S来驱动,下面的图二为IR2104S数据手册中的半桥驱动电路图(左边桥和右半桥是对称的,以分析左半桥为例),图3为IR2104S内部电路原理图:
①VCC为芯片的电源输入,手册中给出的工作电压为10~20V。
② IN和#SD作为输入控制,可共同控制电机的转动状态(转向、转速和是否转动)。
③ VB和VS主要用于形成自举电路。
④ HO和LO接到MOS管栅极,分别用于控制上桥臂和下桥臂MOS的导通与截止。
COM脚直接接地即可。
在这里插入图片描述
图2-IR2104S半桥驱动

在这里插入图片描述
图3-IR2104S内部电路原理图

通过IN口给PWM波,#SD给高低电平。VCC通过一个二极管连接到VB,给VB口提供12V的电压,VB通过一个电容连接到VS,VS接到上下两个NMOS的中间,这部分是一个自举电路,因为NMOS导通需要VGS > VGSth ,由于NMOS导通后电阻很小,相当于一条导线,源极电压等于漏极电压,要确保VGS > VGSth ,所以这里需要一个自举电路来提高栅级的对地电压,并且自举电路还可以降低MOS管的导通电阻,从而减少发热损耗,还需要利用二极管的单向导电性来防止电流回流毁坏电路。下面图四为我的全桥电路图
在这里插入图片描述
因为PWM输出使上下两个NMOS轮流导通,(HO,LO)分别经历(0,0),(1,0),(0,1)三个过程,即自举电容电容充电,自举电容放电和下半桥栅级放电和上半桥栅级放电(上一阶段加在上面的电压),我在HO和LO与NMOS之间的限流电阻上并联一个二极管,加快放电速度。在输入电压出接了一个电容到地,是用来起滤波作用的。同时,PWM给不同的占空比可以进行电机调速。
在这里插入图片描述

2.HC-05蓝牙模块
HC-05蓝牙模块通过串口与51连接,可实现人机交互,我这里只将蓝牙当做接收端,通过手机端的蓝牙调试器APP向51发送控制信息(两者之间通信方式为串口通信,波特率设置为4800)。
在APP中设立了五个按键,即LEFT, RIGHT, UP, DOWN以及OK,分别用作左转,右转,加速,减速和停止,按键按下去后会通过串口发送对应的键值,HEX显示分别为0x48, 0x4A, 0x47, 0x4B, 0x49, 51单片机的SBUF寄存器存储接受到的值,然后我对接受的到信息进行处理。

3.独立按键模块
这一块我设置了三个独立按键,接到P0.0, P0.1, P0.2,同时这三个IO口接了上拉电阻起到保护引脚的作用,这三个按键分别起到加速,减速,停止的作用。
做了软件消抖(检测到按下口经过延时后再检测是否按下),提高准确性。

程序如下:

main.c文件:

#include "reg52.h"
#include "light.h"
#include "motor.h"
#include "blue.h"
#include "key.h"
extern  uchar  Turn_flag;
void main(void)
{
    PWM_Init();
    UART_Init();
    while(1)
    {
        Key_Ctrl(Key_Scan());
        LED_Display(Turn_flag);
    }
}

blue.c文件:

#include "reg52.h"
#include "blue.h"
#include "string.h"
#define  UART_RX_STA = 0;
uchar    UART_RX_BUF[UART_MAX_RECV_LEN];
uchar    Turn_flag = 0;
extern   uchar  comp;
sbit  L = P1 ^ 3;
sbit  R = P1 ^ 4;
sbit  LED_Stop = P1 ^ 0; //红色灯--刹车灯
sbit  BEEP  = P2^7;     //蜂鸣器
//定时器1初始化
void  UART_Init(void)
{
    SCON = 0x50;
    TMOD = 0x20;
    PCON = 0x80;
    TH1  = 0xF3;      //设置波特率为4800
    TL1  = 0xF3;
    ES   = 1;
    EA   = 1;
    TR1  = 1;
    L = 0;
R = 0;
LED_Stop =  0; //红色灯--刹车灯
BEEP  = 1;  
}
//串口发送数据
void UART_SendData(uchar *BUFF)
{
    uchar i;
    for(i = 0; i < strlen(BUFF) ; i++)
    {
        SBUF = *(BUFF + i);
        while(!TI);
        TI = 0;
    }
}
//串口中断函数,蓝牙电机控制
void UART_ReceiveData() interrupt 4
{
    ES = 0;		//暂时关闭串口中断
    RI = 0;
    UART_RX_BUF[0] = SBUF;   //把收到的信息从SBUF放到UART_RX_BUF[]中
    switch(UART_RX_BUF[0])
    {
    case 0x47:
        if(comp != 80)  comp += 10;
        else  comp = 80;
        break;
    case 0x48:
        L = 0;
        R = 1;
        Turn_flag = 1;
        break;
    case 0x49:
        comp = 0;
        Turn_flag = 0;
        break;
    case 0x4A:
        L = 1;
        R = 0;
        Turn_flag = 2;
        break;
    case 0x4B:
        if(comp != 0)   comp -= 10;
        else  comp = 0;
        Turn_flag = 3;
        break;
    default:
        break;
    }
    ES = 1;		//重新开启串口中断
    SBUF = UART_RX_BUF[0];
    while(!TI);
    TI = 0;
}

blue.h文件:

#ifndef    _BLUE_H
#define    _BLUE_H
#define    UART_MAX_RECV_LEN  40
#define    uchar   unsigned char
#define    uint	   unsigned int
void  UART_Init(void);
void  UART_SendData(uchar *BUFF);
#endif

motor.c文件:

#include "reg52.h" 
#include "motor.h" 
#define uchar unsigned char 
#define uint  unsigned int 
 
sbit  PWM1 = P2 ^ 6;    //PWM输出IO口 
sbit  PWM2 = P2 ^ 4;  
uchar cont = 0;          //定时器0中断计数值 
uchar comp ;      //定时器0的比较值 
//定时器0初始化 
void  PWM_Init(void) 
{ 
    TMOD = 0x01; 
    TH0  = (65536 - 1000) / 256; 
    TL0  = (65536 - 1000) % 256; 
    EA   = 1; 
    TR0  = 1; 
    ET0  = 1; 
    PWM1  = 0; 
    PWM2  = 0; 
} 

//定时器0中断函数, PWM占空比设置 
void  TIMER0_INT(void) interrupt 1 
{ 
    TH0  = (65536 - 1000) / 256; 
    TL0  = (65536 - 1000) % 256;  //1us 
    cont++; 
    if(cont <= comp) 
    { 
        PWM1 = 1; 
        PWM2 = 1; 
    } 
    else  if(cont <= 100)       //10khz 
    { 
        PWM1 = 0; 
        PWM2 = 0; 
    } 
    else cont = 0; 
} 

motor.h文件:

#ifndef  _MOTOR_H
#define  _MOTOR_H
void  PWM_Init(void);
#endif

light.c文件:

#include "reg52.h"
#include "light.h"
sbit  LED_Stop = P1 ^ 0; //红色灯--刹车灯
sbit  LED_L = P1 ^ 1;   //黄色灯--左边
sbit  LED_R = P1 ^ 2;   //黄色灯--右边
sbit  BEEP  = P2 ^ 7;   //蜂鸣器
sbit  Beep_ST = P1 ^ 5;

//i = 1 ,延时1us
void  delay_ms(uint i)
{
    while(i--);
}

void  LED_Display(uchar Turn_flag)
{
    if(Turn_flag == 0)
{
LED_Stop = 0;
        Beep_ST = 0;
        LED_L = 0;
        LED_R = 0;
        BEEP  = 0;
    }
    else if(Turn_flag == 1)
{
LED_Stop = 0;
        Beep_ST = 1;
        LED_L = 1;
        BEEP  = 1;
        delay_ms(5000);
        LED_L = 0;
        BEEP  = 0;
        delay_ms(5000);
    }
    else if(Turn_flag == 2)
{
LED_Stop = 0;
        Beep_ST = 1;
        LED_R = 1;
        BEEP  = 1;
        delay_ms(5000);
        LED_R = 0;
        BEEP  = 0;
        delay_ms(5000);
    }
    else if(Turn_flag == 3)
    {
        LED_Stop = 1;
       BEEP = 1;
    }
}

light.h文件:

#ifndef   _LIGHT_H
#define   _LIGHT_H
#define  uchar   unsigned char
#define  uint	   unsigned int
void  LED_Display(uchar );
void  delay_ms(uint );
#endif

key.c文件:

 #include "key.h"
#include "reg52.h"
#include "motor.h"
sbit  K1 = P0 ^ 0;
sbit  K2 = P0 ^ 1;
sbit  K3 = P0 ^ 2;
#define uchar unsigned char
#define uint  unsigned int
extern uchar comp ;
extern uchar Turn_flag;

void delay(uint i)
{
    while(i--);
}

u8  Key_Scan(void)
{
    if(K1 == 0)
    {
        delay(500);
        if(K1 == 0)  return 1;
        else         return 0;
    }
    else if(K2 == 0)
    {
        delay(500);
        if(K2 == 0)  return 2;
        else         return 0;
    }
    else if(K3 == 0)
    {
        delay(500);
        if(K3 == 0)  return 3;
        else         return 0;
    }
    else           return 0;
}

void   Key_Ctrl(u8 i)
{
    switch (i)
    {
    case  1:
        if(comp != 80)  comp += 10;
        else  comp = 80;
        break;
    case  2:
        if(comp != 0)   comp -= 10;
        else  comp = 0;
        Turn_flag = 3;
        break;
    case  3:
        comp = 0;
        break;
    default:
        break;
    }
}

key.h文件:

#ifndef  _KEY_H
#define  _KEY_H
#define  u8  unsigned char
#define  u16 unsigned int

u8     Key_Scan(void);
void   Key_Ctrl(u8 );
#endif

附焊接图:在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于51单片机蓝牙直流电机控制(IR2104S驱动H桥) 的相关文章

  • openwrt编译error: ext4_allocate_best_fit_partial: failed to allocate 13 blocks, out of space?

    编译openwrt时候报如下错误 xff1a Creating filesystem with parameters Size 50331648 Block size 4096 Blocks per group 32768 Inodes p
  • 在mac上创建鼠标双击可执行的shell脚本

    总是觉得mac权限管理好严格 xff0c 要创建向在window上执行bat那样的脚本需要如下操作 首先创建测试脚本 touch clickexe sh open e clickexe sh 在脚本中输入内容 echo 34 hello w
  • rm: cannot remove Permission denied 问题解决方法

    今天编译openwrt系统的时候 xff0c 碰到这样的问题 rm cannot remove xxx Permission denied 但是又不允许用root用户执行 xff0c 所以就要用root用户去修改权限 chmod 777 如
  • Arduino 舵机驱动板编程

    需要下载Adafruit的arduino库 xff0c 这个网上搜索一下很多 我的驱动板是16路基于I2C接口通信 xff0c 这个arduino库底层都做好了 xff0c 精度是12位 xff08 4096 xff09 设置非常简单 xf
  • 3d图形引擎结构

    其实3d引擎结构基本上都是类似的 xff0c 差别也只是细节的上的差别 xff0c 如jme引擎的结构如下 xff1a 首先是viewport xff0c 这个就像2d图层一样 xff0c 每个viewport开始渲染的时候都可以清除缓冲区
  • 树莓派开机启动frpc

    直接在 rc local里启动frpc失败 xff0c 原因是网络好像连接失败 所以写了个shell脚本 xff0c 通过sleep延时一下 xff0c 就启动成功了 首先建立startfrp sh bin bash cd home pi
  • esp32 arduino psram使用

    esp32 arduino固件是已经支持psram了的 xff0c 是模式2 xff0c 所以要使用heap caps malloc来分配 注意选择wrover modelus xff0c 其他的可能驱动不支持 示例代码 xff1a inc
  • 事件驱动框架(二)——状态机

    事件驱动框架 xff08 二 xff09 说明 本篇接上一篇事件驱动框架之后 xff0c 介绍状态机的原理相关的 xff0c 以及事件驱动框架下事件处理状态机的实现 因为代码大多还是参照QP源码 xff0c 所以仅供学习使用 有限状态机介绍
  • 小米10如何安装google play商店

    查了一下网上说可以安装gmail 小米商店就会自动安装google play的 xff0c 但是发现gmail在小米商店已经提示说 因为软件本身问题不能给安装 34 xff0c 查了一无果 xff0c 于是用之前华为安装google的apk
  • php 上传目录权限问题导致无法上传

    php除了有大小严格限制导致失败 xff0c 还有就是上传目录权限问题导致失败 xff0c 如果权限问题执行以下命令即可 sudo chown R www data www data Users George Desktop uploads
  • KeilC STM32添加.c .h文件的方法

    嵌入式初学者添加 c h文件是可能会出现 h头文件无法生效的问题 xff0c 在此将本人经历总结如下 xff0c 供大家参考 1 xff0c 把所需添加的文件 xff0c 放到这个文件夹下 项目名称 Core Src 2 xff0c 右击此
  • 传感器——ATGM332D 北斗定位模块

    NO 8 模型用GPS测速仪 xff08 已完成 xff09 xff08 更新第二版本 xff09 这个是用显示屏显示的 定位精度2 5m GPS模块VCC Arduino的5v GPS模块GND Arduino的GND GPS模块TXD
  • stm32f10--- 学习日志2021-07-10

    不知道标题是啥 xff0c 学到什么记录什么 寄存器占四个字节 偏移地址 xff1a 0x04 基地址 xff1a 0x4001 1000叫做GPIOC的基地址 APB2外设时钟使能寄存器 0x4002 1018 单片机认为它只是一个数值
  • 【unp】unix网络编程卷1-->环境搭建(ubuntu14.04)

    学习unp网络编程 xff0c 树上的例子均存在 include 34 unp h 34 xff0c 故需要对环境进行配置 1 到资源页下载unpv13e 2 解压并将unpv13e 移动到相应的文件夹下 3 编译 gt cd unpv13
  • 北醒激光雷达模组 资料汇总

    目录 1 文档说明1 1 北醒单点系列雷达激光模组相关资料1 2 北醒面阵系列雷达激光模组相关资料1 2 1 产品基本介绍1 2 2 Benewake 北醒 短距 TF LC02 2m资料整理1 2 3 Benewake 北醒 短距 TF
  • TFmini Plus在开源飞控PX4上的应用

    TFmini Plus在开源飞控PX4上的应用 PX4有着自己独特的优势 xff0c 受到广大爱好者的喜爱 TFmini Plus是北醒公司推出的性价比极高的激光雷达 xff0c 受到广大爱好者的追捧 本文介绍TFmini Plus和PX4
  • Benewake TFmini-S\TFmimi Plus\TFluna\TF02-Pro 串口版本雷达在STM32的例程

    目录 文档说明北醒串口标准通讯协议硬件接线Lidar通讯代码1 初始化USART1 2 开启USART1的空闲中断 3 USART2 IRQHandler增加中断判断4 中断处理函数 xff0c 用于接收雷达数据 协议处理注 xff1a 换
  • 使用CH341 I2C连接北醒TF系列I2C模式 Python例程

    目录 硬件接线 xff1a 源码结果输出 本文介绍了北醒单点系列雷达IIC模式下使用CH341芯片转接板读取雷达数据的例程 例程下载 xff1a 链接 https pan baidu com s 1KVJ fINxUgKZny2Gdi8T2
  • 蓝牙nrf51822程序的分析(一)

    蓝牙nrf51822程序的分析 一 最近继续用NRF51822开发一个东西 无奈之前没接触过蓝牙 连蓝牙串口模块也没有 所以对蓝牙的基础知识不够 xff0c 后面看了之后接着补充 花了2天时间把提供的NRF51822的程序大致看明白了 xf
  • 常用Arduino板介绍

    目录 NANO板介绍烧录说明 UNO板介绍烧录说明 Pro mini板介绍烧录说明 DUE板介绍烧录说明 NANO板介绍 概述 xff1a Arduino Nano是一款基于ATMega328P xff08 Arduino Nano 3 x

随机推荐

  • Modbus设备在Modbus scan上面的使用方法

    操作教程 参数 xff1a DeviceID xff1a 485从站 寄存器地址 xff1a 查询设备地址表 北醒雷达Dist在0x0000开始 读取寄存器长度 xff1a 雷达数据长度值 格式 xff1a MODBUS RTU 串口协议
  • Raspberry Pi Pico C/C++语言在Windows环境下开发环境搭建 Raspberry Pi Pico C/C++ SDK

    目录 前言Raspberry Pi Pico介绍需要支持的软件软件安装配置及注意事项ARM GCC compiler的安装CMake的安装Git 安装Visual Studio 2019的安装Visual Studio Code的配置Pyt
  • 【LoRa32U4II】介绍以及基于Arduino IDE编译环境搭建及测试

    目录 LoRa 模块LoRa32u4 II介绍LoRa32u4 II 资料下载LoRa32u4 II 规格介绍LoRa32u4 II 脚位说明 编译环境介绍电脑系统编译软件Arduino需求库 编译环境搭建及测试LoRa32u4 II 测试
  • 【Benewake(北醒) 】短距 TF-LC02 2m资料整理

    目录 1 TF LC02简要说明1 1 性能参数1 2产品图片及尺寸 2 运用2 1 在开源板Arduino上的运用2 2 在Python上的应用 1 TF LC02简要说明 1 1 性能参数 1 2产品图片及尺寸 2 运用 2 1 在开源
  • 【Arduino】Benewake(北醒) TF-LC02(TTL)基于Arduino 开发板运用说明

    目录 前言Benewake 北醒 TF LC02产品简要说明Arduino开发板介绍Benewake 北醒 TF LC02 接口及通讯协议说明接口定义串口协议说明通讯协议说明功能码说明 接线示意图例程说明配置软硬串口定义获取TOF数据的结构
  • 【Benewake(北醒) 】中距 TF02-i 40m工业版本CAN/485介绍以及资料整理

    目录 1 前言2 产品介绍3 产品快速测试3 1 产品规格书及使用说明书3 2 通用指令串口助手使用说明3 3 产品快速测试说明 4 基于开源硬件的运用整理4 1 在开源飞控上的运用 5 基于其他的运用整理5 1 在PLC上的运用说明5 2
  • 【ESP32 DEVKIT_V1】基于Arduino IDE环境搭建

    目录 一 前言二 板子介绍三 环境搭建1 Arduino IDE的安装2 在Arduino IDE上添加外包链接3 添加好外包链接后就可以下载对应的板子库文件 测试1 先把开发板接到电脑 xff0c 并在Arduino IDE上选择对应的开
  • 【ESP32 DEVKIT_V1】北醒TF系列雷达在ESP32 DEVKIT_V1开发板上的运用

    目录 前言一 硬件准备二 硬件接线说明串口接线示意图 xff1a I2C接先示意图 三 软件搭建及测试1 使用Arduino IDE编译教程2 使用vsCode 43 Arduino教程2 1 在vsCode上使用Arduino的环境搭建2
  • 【vsCode + Arduino】在Visual Studio Code编译Arduino项目

    目录 前言一 参考文档二 操作步骤2 1 安装Arduino IDE2 2 在vsCode里安装Arduino插件2 3 配置arduino的安装路径2 4 配置好后打开一个Arduino的项目文件夹进行相应的配置 三 目前已知问题 前言
  • 蓝牙:GATT,属性,特性,服务

    接着上一篇 通用属性配置文件 xff08 Generic Attribute Profile xff09 1 GATT简介 通用属性配置文件Generic Attribute Profile简称GATT GATT定义了属性类型并规定了如何使
  • RS232 RS422 RS485详细介绍

    1 RS 232 C RS 232 C是美国电子工业协会EIA xff08 Electronic Industry Association xff09 制定的一种串行物理接口标准 RS是英文 推荐标准 的缩写 xff0c 232为标识号 x
  • stm32串口使用以及串口中断接收不定长度字符串

    开始使用cubemx配置PA9 PA10分别为TX RX端 xff0c 在使能串口中断 之后其余值直接使用默认的就可以了 点击生成代码即可 span class token class name uint8 t span rx buff s
  • STM32-串口通信printf重定向

    前言 xff1a 平时我们进行c语言编程的时候会经常用到printf函数进行打印输出 xff0c 来调试代码 可是这个printf函数C库已经帮我们实现好了 xff0c 通常只需要直接调用即可 xff0c 但是如果在一个新的开发平台 xff
  • FMCW毫米波雷达原理

    Radar系列文章 传感器融合是将多个传感器采集的数据进行融合处理 xff0c 以更好感知周围环境 xff1b 这里首先介绍毫米波雷达的相关内容 xff0c 包括毫米波雷达基本介绍 xff0c 毫米波雷达数据处理方法 xff08 测距测速测
  • VMware虚拟机安装ubuntu16.04系统教程

    对于没有接触过Ubuntu系统的小伙伴来说 xff0c 直接在物理机上安装Ubuntu单系统或者windows Ubuntu双系统一件比较刺激的事情 xff0c 因为一不小心可能就会把电脑整崩溃 xff0c 或者出现各种问题 xff0c 所
  • c#实验五 文件与流

    实验五 文件与流 WPF还不太会 抄STZG的 xff0c 其他自己写的 一 实验目的 掌握文件类的使用 xff1b 掌握文件流的操作 xff1b 掌握二进制数据 文本数据的读写 xff1b 继续应用WPF技术进行界面编程 二 实验内容 要
  • 简易入门MFC

    工作需要用到MFC xff0c 需要能快速上手 xff0c 中间碰到不懂的简单的看了下源码 xff0c 参考了些资料 目标 xff1a 做一个简单的计算器 xff0c 代码就不考虑了 xff0c 主要强调如何上手MFC xff0c 和简单了
  • Problem: 美丽的黄山 (指针)

    Description 众所周知 xff0c 黄山市一片山 xff08 而不是一座山 xff09 假设这些山排成了一排 xff0c 每座山有各自的高度 现在游客们从最左边看山 xff0c 有些山因为高度没有它左边的某座山高 xff0c 就会
  • (冒泡排序) Problem: 并列排名

    冒泡排序原理就是 xff1a 如果有n个数 xff0c 相邻的两个数进行比较 xff0c 就是1号和2号 xff0c 2号和3号 n 1号和n号比较 xff0c 每次比较确定一个数的位置 也就是第一个轮回比较n 1次 xff0c 第二个就比
  • 基于51单片机蓝牙直流电机控制(IR2104S驱动H桥)

    主要目标 xff1a xff08 1 xff09 用51系列单片机作为控制器 xff1b xff08 2 xff09 采用由四个MOS管组成的H桥电机驱动电路 xff0c 并由IR2104S来驱动H桥 xff1b xff08 3 xff09