stm8 uart2 串口接收中断协议解码+定时器中断

发布者:老卫最新更新时间:2018-06-01 来源: eefocus关键字:stm8  uart2  串口接收  中断协议解码  定时器中断 手机看文章 扫描二维码
随时随地手机看文章

协议解码的时候,如果上位机发送数据不完整或者有错误,通过定时器中断将之接收的不完整数据清楚。定时的时间长短可有定时器觉得,ms为单位。


//初始化位毫秒单位

void Timer_Init()
{
TIM1_PSCRH  = (unsigned char) ( ( (F_CPU / 1000) - 1) >> 8);     /* 16M系统时钟经预分频f=fck/(PSCR+1) */
TIM1_PSCRL  = (unsigned char) ( (F_CPU / 1000) - 1);             /* PSCR=0x3E7F,f=16M/(0x3E7F+1)=1000Hz,每个计数周期1ms */


TIM1_ARRH  = 0;                                                            /* 这三行不知道为什么要先初始化,如果不定时第一次用时将不正常 */
TIM1_ARRL  = 1;                                                            /*  */
TIM1_CR1  = 0x01;                                                         /* 计数器使能,开始计数 */
}




void ClearTimeOut( void )
{
TIM1_IER_UIE  = 0;                                                            /*  Turn off the interrupts. */
TIM1_CR1  = 0x00;                                                         /* 计数器停止计数 */
TIM1_SR1  = 0;                                                            /* 清除定时器0标志 */
}



/*
 * -----------------------------------------------------------------------------
 * timeout ()
 * -----------------------------------------------------------------------------
 */
void SetTimeOut( unsigned int ticks )
{
TIM1_CR1  = 0x00;                                                         /* 计数器关闭 */
TIM1_SR1  = 0;                                                            /* 清除更新中断标记 */
TIM1_CNTRH  = 0;
TIM1_CNTRL  = 0;                                                            /* 清零计数器 */
TIM1_ARRH  = (ticks >> 8);                                                 /* 自动重载寄存器ARR=0x01F4=500 */
TIM1_ARRL  = ticks;                                                        /* 每记数ticks=500次产生一次中断,即500ms  ;ARR设置可看作一个门限值, CNT由0增加到ARR值,自动清零,并置位事件标志 */


TIM1_IER_UIE  = 1;                                                            /*  Turn on the interrupts. */
TIM1_CR1  = 0x01;                                                         /* 计数器使能,开始向上计数 */
}




#pragma vector = TIM1_OVR_UIF_vector
__interrupt void TIM1_UPD_OVF_IRQHandler( void )
{
unsigned char i;


for ( i = 0; i < 30; i++ )
m_ucData[i] = 0;
state_machine  = 0;
retFlag         = 0; 
        
        TIM1_IER_UIE = 0;                                                    /*  Turn off the interrupts. */
TIM1_CR1  = 0;                                                    /* 计数器停止计数 */
TIM1_SR1  = 0;                                                    /* 清除定时器0标志 */
}




void uart_init( void )
{
UART2_CR2_TEN  = 1;
UART2_CR2_REN  = 1;
UART2_CR2_RIEN= 1;
UART2_BRR2  = ( (unsigned char) ( (F_CPU / BAUD_RATE) & 0x0f) ) + ( ( (unsigned char) ( (F_CPU / BAUD_RATE) >> 8) ) & 0xf0);
UART2_BRR1  = ( (unsigned char) ( (F_CPU / BAUD_RATE) >> 4) );
}

/*
 * ******************************************************************************
 *
 * ******************************************************************************
 */
#pragma vector = UART2_R_RXNE_vector
__interrupt void UART2_IRQHandler( void )
{
unsigned char rcvcount;
unsigned char lencnt;
unsigned char xorchkm;
unsigned char rcvdat;
if ( UART2_SR_RXNE == 1 )
{
UART2_SR_RXNE = 0;


rcvdat = UART2_DR;


/* uart_tx_byte(rcvdat); */


/* 如下是协议解析情况 ,全协议不超过30字节
* 位机发送数据的时候,两个接收数据包之间不少于100毫秒。
*/
if ( state_machine == 0 )                               /* 协议解析状态机 */
{
if ( rcvdat == 0x55 )                           /* 接收到帧头第一个数据 */
{
SetTimeOut( 100 );                      /* 9600bps,一秒钟1200字节。25毫秒为30字节 */
lencnt  = 0;            /* 接收数据计数器 */
m_ucData[lencnt++]= rcvdat;       /* 数据保存 */
state_machine  = 1;
}else
state_machine = 0;                      /* 状态机复位 / */
}else if ( state_machine == 1 )
{
xorchkm = rcvdat;                               /* 开始计算异或校验和 / */


m_ucData[lencnt++]= rcvdat;               /* 数据保存 */
state_machine  = 2;
}else if ( state_machine == 2 )
{
xorchkm  ^= rcvdat;
m_ucData[lencnt++]= rcvdat;               /* 数据保存 */
state_machine  = 3;
}else if ( state_machine == 3 )
{
m_ucData[lencnt++]= rcvdat;               /* 数据保存 */
rcvcount  = rcvdat;               /* 接收数据长度 */
xorchkm  ^= rcvdat;
                        if(rcvcount>=24)                                //数据长度不能超过24个字节
                              state_machine  = 0;
                        else
                              state_machine  = 4;
}else if ( state_machine == 4 || state_machine == 5 )
{
m_ucData[lencnt++]= rcvdat;               /* 数据保存 */
xorchkm  ^= rcvdat;
if ( (lencnt - 4) == rcvcount )                 /* 判断数据是否接收完毕 */
state_machine = 6;
else
state_machine = 5;
}else if ( state_machine == 6 )
{
if ( xorchkm == rcvdat )                        /* 判断异或校验和是否相等 */
{
state_machine  = 7;
m_ucData[lencnt++]= rcvdat;       /* 数据保存 */
}else
state_machine = 0;
}else if ( state_machine == 7 )
{
if ( 0xAA == rcvdat )                           /* 判断是否接收到帧尾结束符 / */
{
m_ucData[lencnt++] = rcvdat;            /* 数据保存 */
ClearTimeOut();
retFlag = 0x01;                         /* 置标志,表示一个数据包接收到 / */
}
state_machine = 0;                              /* 复位状态 / */
}
}
}


关键字:stm8  uart2  串口接收  中断协议解码  定时器中断 引用地址:stm8 uart2 串口接收中断协议解码+定时器中断

上一篇:STM8中断的设置(ST Visual Develop和IAR环境下)
下一篇:stm8中断使用

推荐阅读最新更新时间:2024-03-16 16:04

STM8 的汇编学习
STM8 CPU中的寄存器只有6个,即A、X、Y 、SP、 PC 、CC。 完成内存种的2个8位无符号数相加,结果还保存到内存中。 unsigned char a,b,c; c = a + b; STM8汇编如下: LD A,$1000 ADD A,$1001 LD $1002,A 这里假设a,b,c这3个变量分别存储在内存中,地址为1000,1001,1002。 static @inline void jump_to_new_prog(void) 远程升级部分汇编代码 { _asm( LDW X, SP ); _asm( LD A, $FF ); _asm( LD XL, A ); _asm(
[单片机]
串口通讯程序(单片机接收后再发送到电脑)
下次写一个程序在发送回 电脑 的基础上还要在液晶上显示 #include reg52.h unsigned char temp; void init(); //初始化函数 void main(void) { init(); while(1) { } } void init() { SCON=0x50; TMOD=0x20; TH1=0XF3; TL1=0XF3; EA=1; ES=1; TR1=1; } void usb() interrupt 4 { temp=SBUF; RI=0; SBUF=temp; while(!TI); TI=0; }
[单片机]
<font color='red'>串口</font>通讯程序(单片机<font color='red'>接收</font>后再发送到电脑)
stm8用什么软件编程?stm8开发环境搭建手把手教程!
STM8单片机开发环境的由3部分组成:电脑端开发环境、目标板、烧录仿真器。 我们要具备以上3个条件才能开始STM8单片机的开发,下面我们为大家详细讲解下STM8的开发环境搭建。 STM8目标板: STM8 单片机系统硬件,我们最终要编程的目标。 烧录仿真器:连接电脑和目标的编译连接器,主要作用:仿真、程序烧录、软件调试。 电脑端开发环境: 单片机程序的开发是在电脑上完成的,我们需要在电脑端搭建单片机对应的开发环境。 接下来,我们就详细的给大家介绍一下STM8单片机开发环境搭建。 1.STM8目标板: 目标单片机电路板就是要开发的STM8单片机系统硬件了,如下图: 这个是我们无际单片机编程带学员研发的l
[单片机]
<font color='red'>stm8</font>用什么软件编程?<font color='red'>stm8</font>开发环境搭建手把手教程!
STM8单片机关于rtc部分代码分享
STM8 rtc 时钟可以使用内部低频时钟源,或者外部低速 32768Hz 时钟源,关于 rtc 部分代码如下: #include #include voidinit_rtc(void) { RTC_InitTypeDefRTC_InitStr; RTC_TimeTypeDefRTC_TImeStr; RTC_DateTypeDefRTC_DateStr; #if0 /*LSI*/ CLK_RTCClockConfig(CLK_RTCCLKSource_LSI,CLK_RTCCLKDiv_1); CLK_PeripheralClockConfig(CLK_Peripheral_RTC,ENABLE); RTC_I
[单片机]
<font color='red'>STM8</font>单片机关于rtc部分代码分享
[STM8学习笔记] IAR工程搭建笔记
1. 打开IAR软件。 2.选择 - - 3. - - 会弹出一个对话框,根据你的MCU系列下拉选择MCU型号; 然后再根据你的编程语言选择编程语言。 选择好了之后,点击【OK】 - 选择你要保存的工程路径以及工程名。 4. 配置工程参数:选中工程名,右键选择【options...】 4.1 选择芯片型号:Device:STM8L051F3(这里是我使用的MCU型号) 4.2 编译时需要的头文件相对路径添加(这样后续工程路径变更,也不会影响头文件找不到的问题) $PROJ_DIR$ $PROJ_DIR$..user 4.3 输出可执行文件配置如下: 4.4 debug调试器配置如
[单片机]
[<font color='red'>STM8</font>学习笔记] IAR工程搭建笔记
STM8单片机串口同时识别自定义协议和Modbus协议
  在单片机开发中,串口是最常用的和外界交换数据的渠道,要使用串口,那必不可少的就是通信协议,通信协议就是单片机和外界通信的语言,要想正常和其他设备正常交流,首先语言必须相通。   在实际开发过程中由于各种原因,导致很多时候单片机和外界其他设备协议不兼容,在使用的时候就比较麻烦。比如单片机要和两个设备通信,但是这两个设备的通信协议的不一样,在使用时单片机就必须使用两个串口分别和两个设备通信。如果这两个设备同时使用时还不感觉到资源浪费,如果每次只接一个设备,那么另一个串口也不能作为其他功能使用,还得留着备用。这样的话单片机的资源就被白白浪费掉了。于是想着能不能在一个串口上支持两个协议,让单片机自动去识别接收到的数据使用的是哪个协
[单片机]
<font color='red'>STM8</font>单片机<font color='red'>串口</font>同时识别自定义<font color='red'>协议</font>和Modbus<font color='red'>协议</font>
STM8 用户启动区域(UBC)
用户启动区域(UBC)包含有复位和中断向量表,它可用于存储IAP及通讯程序。UBC有一个两级保护结构可保护用户代码及数据在IAP编程中免于无意的擦除或修改。这意味着该区域总是写保护的,而且写保护不能通过使用MASS密钥来解锁。 在ICP模式下(使用SWIM接口)可以通过修改选项字节来配置UBC的大小。UBC选项字节指定了分配在UBC中的页的数量。UBC区域的起始地址是0x00 8000。 可以通过读取UBC选项字节来获得UBC区域的大小。请参考图6,图7和图8来了解UBC区域的存储器映射。对于选项字节部分,请参考相应的数据手册了解更多的UBC选项字节的细节。 (图六:小容量STM8S的UBC区域大小) 1. UBC =
[单片机]
<font color='red'>STM8</font> 用户启动区域(UBC)
一起学mini2440裸机开发(十一)--mini2440定时器0中断实验
在前边讲解系统时钟和定时器时,曾给出一个实验,实现的功能是:使用定时器0的功能,使LED每秒钟闪烁一次,当时是使用查询方式实现的,现在使用中断方式实现上述功能。 下图为我的工程文件布局: 下面贴出我的代码,你也可以去这里下载, http://download.csdn.net/detail/mybelief321/5457371 下载下来之后,直接编译,点击Flash/Download ,下载到nor flash中运行。 main.c文件 #include led.h #include timer.h #include isrservice.h #include interrupt.h unsigne
[单片机]
一起学mini2440裸机开发(十一)--mini2440<font color='red'>定时器</font>0<font color='red'>中断</font>实验
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved