Android io模拟串口驱动,模拟串口--基于STM8普通IO口的模拟串口驱动程序

标准串口通讯数据的格式为:起始位(1) + 数据位(8) + 校验位(1) + 停止位(1)

串口通讯另外一个重要的的部分是设置波特率,波特率就是1秒钟内串口所传输的Bit(位)数。

关于采样频率:为了较小读取或者发送串行数据的误差,我们采取了在N(我用的是4次)次中断中,取固定位置的读取的数据。

我以stm8中9600波特率计算的过程为例:(1秒钟传输9600位)

可以计算出传输1位所需要的时间 T1 = 1/9600 约为104us

由此可知,发送一位数据,定时器中断的时间间隔应为 104/4 = 26us(4倍采样频率)

stm8 内部晶振频率为16M,我采用8分频也就是2M,故MCU震荡周期为 1/2M = 0.5us

由上面的计算我们可以知道要发送一位数据,定时器中断的初值应设为为 26/0.5 =52

以上为相关数据的计算过程,下面是模拟串口驱动程序和注释:

定时器中断与IO口配置:

void TIM3_Configuration(void)

{

TIM3_DeInit();

TIM3_TimeBaseInit(TIM3_PRESCALER_8,52);        //52  104

TIM3_ITConfig(TIM3_IT_UPDATE ,ENABLE);

TIM3_ARRPreloadConfig(ENABLE);

TIM3_Cmd(ENABLE);                                                //DISABLE TIM3_Cmd(DISABLE)

}

//模拟串口引脚定义

#define SIM_UART_TX_PORT               GPIOC

#define SIM_UART_TX_PIN                GPIO_PIN_2

#define SimUartTxHigh()                (SIM_UART_TX_PORT->ODR |= (u8)(SIM_UART_TX_PIN))

#define SimUartTxLow()                 (SIM_UART_TX_PORT->ODR &= (u8)(~SIM_UART_TX_PIN))

#define SIM_UART_RX_PORT               GPIOC

#define SIM_UART_RX_PIN                GPIO_PIN_3

#define SimUartRxStatus()              (SIM_UART_RX_PORT->IDR & SIM_UART_RX_PIN)

GPIO_Init(SIM_UART_RX_PORT, SIM_UART_RX_PIN,GPIO_MODE_IN_PU_NO_IT);

GPIO_Init(SIM_UART_TX_PORT, SIM_UART_TX_PIN,GPIO_MODE_OUT_PP_LOW_FAST);

/* Includes ------------------------------------------------------------------*/

#include "stm8s.h"

#include "global.h"

//默认采样频率为4倍  一下为16M晶振 8分频 后计数器的装载值

//9600B 104us发送一位  4倍采样频率 故为26us发送一位

#define  SIM_BAUDRATE_9600     52

#define  SIM_BAUDRATE_4800     104

#define  SIM_BAUDRATE_2400     208

/* Private variables ---------------------------------------------------------*/

u8 RxByteIndex;        //接收字节索引

u8 RxSampFreq;         //采样频率控制 1/4

u8 TxXKCnt = 3;        //需要发送数据包的字节数

u8 SimUartRxBuff[10];  //接收数据包缓冲

u8 SimUartTxBuff[10] = {0x55, 0xaa, 0x66};

bool IsSimUartRxFinish;//是否接收完成标志

bool IsSimUartRecv;    //模拟串口是否处于接收状态

/* Private functions ---------------------------------------------------------*/

/* Public functions ----------------------------------------------------------*/

void InterruptSimUart(void);

static void Drv_SimUartTxByte(void);

static void Drv_SimUartRxByte(void);

/*******************************************************************************

#Function      :   InterruptSimUart

#Description   :   模拟串口中断调用程序  切换发送与接收

#Parameter     :   NULL

#Return        :   NULL

#AuthorAndData :   huangzhigang 20141013

*******************************************************************************/

void InterruptSimUart(void)

{

if(IsSimUartRxFinish)   //接收完成后立刻发送数据  也可以自己定义什么时候发送数据

{

IsSimUartRxFinish = FALSE;

IsSimUartRecv = FALSE;

}

if(IsSimUartRecv)

{

Drv_SimUartRxByte();

}

else

{

Drv_SimUartTxByte();

}

}

/*******************************************************************************

#Function      :   Drv_SimUartRxByte

#Description   :   模拟串口接收函数

#Parameter     :   NULL

#Return        :   NULL

#AuthorAndData :   huangzhigang 20141013

*******************************************************************************/

static void Drv_SimUartRxByte(void)

{

static u8 RxBitNum;    //接收位计数

static u8 Verify;      //校验码

static u8 OverTime;    //接收超时计数

static u8 s_u8Rxbuff;  //一字节接收缓存

if(SimUartRxStatus())

{

OverTime++;

}

else

{

OverTime = 0;

}

if(OverTime > 44)

{

OverTime = 45;

RxByteIndex = 0;

RxBitNum = 0;

}

if((SimUartRxStatus()) && (RxBitNum == 0))

{

RxSampFreq = 0;

}

else

{

++RxSampFreq;

}

if(RxSampFreq == 1)

{

if(RxBitNum == 0)                                           //低电平,起始位bit0

{

if(!SimUartRxStatus())

{

Verify = 0;

s_u8Rxbuff = 0;

RxBitNum++;

}

}

else if((RxBitNum > 0) && (RxBitNum < 9))                   //数据位  bit1~8

{

if(SimUartRxStatus())                                   //高电平

{

s_u8Rxbuff = s_u8Rxbuff | (0x01 << (RxBitNum -1));

Verify++;

}

RxBitNum++;

}

else if(RxBitNum == 9)                                      //校验位  bit9

{

RxBitNum++;

if(Verify & 0x01)

{

if(SimUartRxStatus()) {RxBitNum = 0;}               //奇校验

}

else

{

if(!SimUartRxStatus()) {RxBitNum = 0;}

}

}

else if(RxBitNum == 10)                                     //停止位 bit10

{

if(SimUartRxStatus())

{

RxBitNum = 0;

if(RxByteIndex == 0)                                //头码1为0X55

{

if(s_u8Rxbuff == 0x55)

{

SimUartRxBuff[RxByteIndex] = s_u8Rxbuff;

RxByteIndex++;

}

else

{

RxByteIndex = 0;

}

//TEST  测试  接收到一字节数据后马上回复

//                    IsSimUartRxFinish = TRUE;

}

else if(RxByteIndex == 1)                           //头码2为0Xaa

{

if(s_u8Rxbuff == 0xaa)

c2c9ed493cd281aa86d8a6f5178c4c01.gif [1] [2] 610626052e95c7fbe3d254abc769d9ad.gif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值