STM8S 带缓冲区 串口中断 使用心得

2019-09-17来源: eefocus关键字:STM8S  缓冲区  串口中断


#include "UART.H"

 

/*-------------------------串口初始化函数------------------------*/

 

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

* 函数名称:void UART2_Init(void)

*

* 功能描述:UART2初始化函数

*

* 参数列表:无

*

* 返回结果:无

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

void UART2_Init(void)

{

UART2_CR1=0x00;

UART2_CR2=0x00;

UART2_CR3=0x00;

 

UART2_BRR2=0x0B;

UART2_BRR1=0x08;

UART2_CR2=0x2c; //允许接收,发送,开接收中断

_asm("rim"); //开全局中断

}

 

/*-------------------------串口接收相关函数------------------------*/

 

unsigned char RNUM;     //定义接收变量

u8 rx_buffer[RX_BUFFER_SIZE]; //接收缓冲区

 

#if RX_BUFFER_SIZE <= 256

u8 rx_wr_index = 0, rx_rd_index = 0, rx_counter; //接收写指针,接收读指针,接收字符个数

#else

u16 rx_wr_index = 0, rx_rd_index = 0, rx_counter; //接收写指针,接收读指针,接收字符个数

#endif

 

#if RX_BUFFER_SIZE < 256

u8 rx_counter; //接收字符个数

#else

u16 rx_counter; //接收字符个数

#endif

 

_Bool rx_buffer_overflow; //接收缓冲区溢出标志

 

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

* 函数名称:@far @interrupt void UART2_Rec_HandledInterrupt(void)

*

* 功能描述:接收中断函数

*

* 参数列表:无

*

* 返回结果:无

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

@far @interrupt void UART2_Rec_HandledInterrupt(void)

    if (UART2_SR & 0X0F)

{

RNUM = UART2_SR;

RNUM = UART2_DR; //读取数据

}

    else

    {

        RNUM = UART2_DR; //读取数据

    }

 

rx_buffer[rx_wr_index++] = RNUM; //把数据写入接收缓冲区 接收写指针++

    

#if RX_BUFFER_SIZE == 256

if (++rx_counter == 0) rx_buffer_overflow = 1;  //溢出标志置位

#else

if (rx_wr_index == RX_BUFFER_SIZE)  rx_wr_index = 0; //如果写入指针等于 缓冲区大小 写入指针指向第一位

if (++rx_counter == RX_BUFFER_SIZE)

{

rx_counter = 0;

rx_buffer_overflow = 1;

}

#endif

}

 

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

* 函数名称:char getchar(void)

*

* 功能描述:从接收缓冲区获取一字节数据

*

* 参数列表:无

*

* 返回结果:获取到的数据

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

char getchar(void)

{

char data;

while (rx_counter == 0);    //如果接收数据个数为0 则等待

data = rx_buffer[rx_rd_index++];

#if RX_BUFFER_SIZE != 256

if (rx_rd_index == RX_BUFFER_SIZE)  rx_rd_index = 0;

#endif

_asm("sim"); //关总中断

--rx_counter;

_asm("rim"); //开总中断

return data;

}

 

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

* 函数名称:int getStr(char *Buf,int count)

*

* 功能描述:从接收缓冲区获取一帧数据

*

* 参数列表:*Buf  存储收到的数据 数组

*   count 要获取的数据长度

*

* 返回结果:返回获取到的数据长度

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

int getStr(char *Buf,int count)

{

int i = 0;

for (i=0; i

Buf[i] = getchar();

}    

Buf[i] = '';

return i;

}                           

 

/*-------------------------串口发送相关函数------------------------*/

 

//发送相关变量

u8 tx_buffer[TX_BUFFER_SIZE]; //接收缓冲区

 

#if TX_BUFFER_SIZE <= 256

u8 tx_wr_index = 0, tx_rd_index = 0;//发送写指针,发送读指针

#else

u16 tx_wr_index = 0, tx_rd_index = 0;//发送写指针,发送读指针

#endif

 

#if TX_BUFFER_SIZE < 256

u8 tx_counter = 0; //发送字符个数

#else

u16 tx_counter = 0; //发送字符个数

#endif

 

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

* 函数名称:@far @interrupt void UART2_Txc_HandledInterrupt(void)

*

* 功能描述:发送中断函数

*

* 参数列表:无

*

* 返回结果:无

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

@far @interrupt void UART2_Txc_HandledInterrupt(void)

{

UART2_SR &= ~(1<<6); //清除送完成状态位

    

if (tx_counter > 0) //发送队列还有未发送完成的数据

{

UART2_DR = tx_buffer[tx_rd_index]; //把要发送的数据移入发送寄存器

--tx_counter; //未发送数据-1

#if TX_BUFFER_SIZE != 256

if (++tx_rd_index == TX_BUFFER_SIZE) //如果发送读指针等于发送缓冲区个数 

                tx_rd_index = 0; //指针指向第一个数据

#endif

}

else

{

UART2_CR2 &= ~(1 << 7);  //关闭发送完成中断

}

}

 

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

* 函数名称:void putchar(unsigned char data)

*

* 功能描述:仿CVAVR发送一字节数据

*

* 参数列表:data:要发送的数据

*

* 返回结果:无

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

void putchar(u8 c)

{

while (tx_counter == TX_BUFFER_SIZE); //如果发送队列满,则等待

_asm("sim"); //关总中断

if (tx_counter || ((UART2_SR & 0X80) == 0))

{

//如过还有未发送完成的数据

tx_buffer[tx_wr_index] = c; //将现有的数据放入队列后面

        

#if TX_BUFFER_SIZE != 256

if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index = 0; //调整写指针

#endif

++tx_counter; //发送个数+1

}

else //发送寄存器为空,直接发送

UART2_DR = c;

while((UART2_SR & 0X80) == 0); //等待发送完成

_asm("rim"); //开总中断

}

 

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

* 函数名称:void putStr(char *buf,int len,int br)

*

* 功能描述:发送一帧数据

*

* 参数列表:*buf:要发送的数据数组

*    len:要发送数据的长度

*     br:是否在结束添加空格回车

*

* 返回结果:无

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

void putStr(char *buf, int len, char br)

{   

int i = 0;

for (i=0; i

{

putchar(buf[i]);   

}  

if (br == 1)

{

putchar(0x0d); 

putchar(0x0a);    

}


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

* Copyrighe(C) 2017-2100 Demon

* All rights reserved

*

* 文件名称UART.H

* 简要描述:UART初始化、收发函数

*

* 当前版本:V1.0

* 作者/修改者:Demon

* 完成日期:

* 修订说明:

*

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

 

#ifndef _UART_H_

#define _UART_H_

 

#include "MAIN.H"

 

 

/***********************串口2收发相关变量**************************/

extern unsigned char RNUM; //定义UART发送和接收变量

//接收相关

#define RX_BUFFER_SIZE 64 //定义接收缓冲区大小

extern unsigned char rx_buffer[RX_BUFFER_SIZE]; //接收缓冲区数组

 

#if RX_BUFFER_SIZE <= 256

extern unsigned char rx_wr_index,rx_rd_index,rx_counter; //接收写指针,接收读指针,接收字符个数

#else

extern u16 rx_wr_index,rx_rd_index; //接收写指针,接收读指针,

#endif

#if RX_BUFFER_SIZE < 256

extern unsigned char rx_counter; //接收字符个数

#else

extern u16 rx_counter;  //接收字符个数

#endif

extern _Bool rx_buffer_overflow; //接收缓冲区溢出标志

//发送相关

#define TX_BUFFER_SIZE 8 //定义发送缓冲区大小

extern unsigned char tx_buffer[TX_BUFFER_SIZE]; //接收缓冲区

#if TX_BUFFER_SIZE <= 256

extern unsigned char tx_wr_index,tx_rd_index;   //发送写指针,发送读指针

#else

extern u16 tx_wr_index,tx_rd_index; //发送写指针,发送读指针

#endif

#if TX_BUFFER_SIZE < 256

extern unsigned char tx_counter; //发送字符个数

#else

extern u16 tx_counter; //发送字符个数

#endif

void UART2_Init(void); //串口2初始化函数

//void putStr(u8 *p, u8 len);     //发送一帧数据函数

void putchar(unsigned char c); //发送一个字节函数;

void putStr(char *buf, int len, char br); //发送一帧数据

char getchar(void); //从接收缓冲区获取一个字节函数

int getStr(char *Buf,int count); //从接收缓冲区获取一帧数据函数

#endif //_UART_H_

关键字:STM8S  缓冲区  串口中断 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic474711.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM8S学习01——SPI&IIC
下一篇:STM8L中断线和中断端口使用方法

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

ST系列STM8S003F3P6单片机芯片介绍
众所周知,意法半导体的stm8s系列主流8位微控制器适于工业、消费类和计算机市场的多种应用,特别是要实现大批量的情况。基于STM8专有内核,STM8S系列采用ST的130纳米工艺技术和先进内核架构,主频达到24 MHz,处理能力高达20MIPS。嵌入式EEPROM、RC振荡器和全套标准外设为设计者提供了稳定且可靠的解决方案。相关工具链,从经济型探索套件到更复杂的评估套件和第三方工具,为利用STM8S微控制器进行开发提供了极大方便。STM8S系列包括四个产品线,具有不同特性,但是保持了全面兼容性和可升级性,从而减少了未来产品设计变更。•STM8S003/005/007超值型是入门级产品,具有基本功能。•STM8S103/105基本型
发表于 2020-07-21
<font color='red'>ST</font>系列<font color='red'>STM8S</font>003F3P6单片机芯片介绍
STM8S如何实现Atomthreads最低功耗
(status);  }针对STM8我们最自然想到的是在其中加一个wfi,STM8进入wfi模式几乎不会影响任何外设的运行。以STM8S105K4为例,其进入该模式的典型电流是1.8mA。这个电流,用一节2000mA手机供电,理论上也最多能坚持46天,才一个月多点。这个记录太差了。STM8还有一个HALT模式,这是该芯片的最低功耗模式,电流是uA级别。但是该模式有诸多限制,进入该模式系统几乎所有的clock都停止,你的TImer,adc,uart等等全部停止,除了AWU。atomthreads如果你在idle直接进入HALT,因为基本只有外部中断可以唤醒退出这个模式,当系统醒来了,请你想想,你的系统心跳还准么?你的应用线程
发表于 2020-07-21
<font color='red'>STM8S</font>如何实现Atomthreads最低功耗
三分钟看懂stm8s单片机实现多通道转换
今天在使用stm8s单片机的AD功能,单片机上有AN0到AN9十个通道。想只用其中的三路AN5到AN7。//ADC初始化void ADC_Init(void){ADC_CR1 = 0x50;ADC_CR2 = 0x38;ADC_TDRL = 0xE0;//禁止施密特触发}unsigned int Read_ADC_Temp(unsigned channel){unsigned int i,ADtemp;ADC_Init();//ADC_CSR = 0x00;ADC_CSR = channel;ADC_CR1 = 0x01;// CR1寄存器的最低位置1,使能ADC转换for(i = 0;i 《 300;i
发表于 2020-07-21
三分钟看懂<font color='red'>stm8s</font>单片机实现多通道转换
STM8S的定时器周期中断时钟测试系统
  1 问题  在下面的测试程序中,如果将Init_CLK()函数中的 CLK_CKDIVR |= 0x08;去掉’|‘,则TIM1的功能实现跟预设定相同(10ms中断一次),但是TIM2的PWM频率就变高了;如果加上,则TIM2的功能实现跟预设定相同(产生1Hz的PWM),但是TIM1的周期就变长了;  尝试了很多测试,均无效(买的开发板和另一块gs自画板测试也都一样)。  2 尝试  因为STM8S默认使用内部16M高速RC振荡器,且8分频,则系统启动主时钟为2M。即CLK_CKDIVR = 0X18;,如果再去赋值CLK_CKDIVR |= 0X08; 则主时钟还是不变即0X18,但是如果赋值为CLK_CKDIVR
发表于 2020-07-21
<font color='red'>STM8S</font>的定时器周期中断时钟测试系统
STM8S利用STVP方式进行IO复用分析
1 说明STM8S的IO复用用程序代码配置起来比较麻烦,一般是操作flash来操作opTIon byte字节,配置寄存器更加麻烦,可以使用STM 标准外设驱动库来设置。本文使用一种界面配置的方式来配置IO复用管脚,即使用STVP来配置。 因为FLASH保存的数据是掉电不丢失的,先用STVP把OpTIon Bytes擦写好后,再用STVD仿真器烧写程序就可实现IO复用了。程序方式配置IO复用见这里2 配置流程【step1】打开STVP软件【step2】打开我们需要下载的xxx.s19文件,CTRL+F5(File-》Ram Exec)【step3】配置需要复用的引脚IO口的复用功能主要配置在于AFR0-AFR7。这里我们配置定时器
发表于 2020-07-21
<font color='red'>STM8S</font>利用<font color='red'>ST</font>VP方式进行IO复用分析
采用STM8S内部时钟产生PWM(TIM2)
  1 说明  采用STM8S内部时钟(HSI);  PWM模式2;  占空比为50%,频率为2Hz(方便测试LED灯);  PD2口外接LED灯,PD2口输出PWM波;  系统时钟初始化很重要:CLK_CKDIVR |= 0x08;  2 代码
发表于 2020-07-14
采用<font color='red'>STM8S</font>内部时钟产生PWM(TIM2)
小广播
何立民专栏 单片机及嵌入式宝典

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

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