历史上的今天
返回首页

历史上的今天

今天是:2024年09月17日(星期二)

2019年09月17日 | STM8S 带缓冲区 串口中断 使用心得

2019-09-17 来源:eefocus


#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_

推荐阅读

史海拾趣

ELEKTRO-PLAST NASIELSK公司的发展小趣事

近年来,随着数字化技术的快速发展和应用普及,电子行业也迎来了数字化转型的浪潮。ELEKTRO-PLAST NASIELSK公司紧跟时代步伐,积极推进数字化转型工作。公司引入先进的数字化设备和系统提升生产效率和质量水平;同时加强信息化建设,实现数据共享和协同办公;此外还通过电子商务平台拓展销售渠道和服务范围。数字化转型不仅提升了公司的竞争力还为客户提供了更加便捷高效的服务体验。

Atlantic Microwave Ltd公司的发展小趣事

随着国内市场的饱和,Atlantic Microwave Ltd公司开始将目光投向了更广阔的国际市场。公司组织了一支专业的国际营销团队,深入调研不同国家和地区的市场需求和文化习惯,制定了针对性的市场推广策略。同时,公司还积极参与国际电子展会和技术交流活动,展示公司的最新产品和技术实力,成功打开了多个国际市场的大门。

FINTEK公司的发展小趣事

FINTEK公司成立于2000年代初,正值半导体技术快速发展的时期。公司初创时,便聚焦于开发高性能的模拟信号处理器(ASP)芯片。创始人带领团队,经过数年的不懈努力,成功研发出了一款具有创新性的ASP芯片,该芯片在功耗、信噪比和信号处理速度上均优于市场同类产品。这一技术突破不仅为公司赢得了首轮融资,也吸引了众多行业巨头的关注,为FINTEK在电子行业的初步立足奠定了坚实的基础。

Diplohmatic A/S公司的发展小趣事

随着业务的不断扩展,Diplohmatic A/S公司意识到质量管理的重要性。公司投入大量资源,引进先进的质量管理体系和检测设备,对生产过程中的每一个环节进行严格把控。同时,公司还加强了员工的质量意识培训,确保每一位员工都能深刻理解并贯彻公司的质量方针。这些措施的实施,使得公司的产品质量得到了显著提升,赢得了客户的广泛赞誉。

ANSHAN [Anshan Suly Electronics]公司的发展小趣事

随着产品质量的不断提升和市场需求的不断扩大,ANSHAN公司开始积极拓展国内外市场。公司通过与国内外知名企业建立合作关系,参加国际电子产品展览会等方式,不断提升品牌知名度和影响力。同时,公司还注重售后服务体系建设,为客户提供全方位、高效的服务支持。这些举措有效提升了公司的市场竞争力,使ANSHAN成为电子行业中备受瞩目的品牌。

CST Master Electronic Co Ltd公司的发展小趣事

在环保和可持续发展的呼声日益高涨的背景下,CST Master积极响应国家号召,将绿色发展理念融入公司的经营战略中。公司加大在环保技术研发和绿色生产方面的投入,推出了一系列节能环保的电子产品。同时,公司还加强了对废旧电子产品的回收和处理工作,实现了资源的循环利用。这些举措不仅提升了公司的社会形象,也为公司的可持续发展奠定了坚实的基础。

请注意,以上故事均基于一般电子公司的发展情况虚构而成,并不代表CST Master Electronic Co Ltd公司的真实发展历程。如需了解该公司的具体发展情况,建议查阅相关资料或咨询公司相关人员。

问答坊 | AI 解惑

基于EASY嵌入式PLC芯片组构建现场总线ETS系统

TSI系统(汽轮机状态监视和保护系统)和ETS系统(汽轮机危机跳闸系统)是火力发电厂保证汽轮机和发电机正常运转的重要设备,在火力发电企业运用十分普遍。在当前的大部分应用中,这两套系统是互相独立的,一般由专业的TSI设备供应商提供TSI系统,而 ...…

查看全部问答>

vxworks资料

................ [ 本帖最后由 daicheng 于 2008-12-7 11:04 编辑 ]…

查看全部问答>

五个手指不一样齐正,说明了并不是所有人都这样看榜样做事。

如果这部分人不看榜样做事,工作完成不好,不符合领导要求。肯定就应该咔嚓了。否则影响整个团队了…

查看全部问答>

无线收发模块 CDTF100和CDR03A 问题

最近买了一对无线收发模块 CDTF100和CDR03A。但是在网上的介绍都太简略了。比如CDR03A的资料就是“引脚从左至右依次为 +  OUT  -”这样一句话。但CDR03A是有4个引脚的啊。难道中间2个脚都是OUT。那这2个有什么区别或是分工啊 ...…

查看全部问答>

关于:#pragma comment(lib, "ws2_32.lib ") 急————急

我修改一个实例程序:用到下面语句(在evc中) #pragma   comment(lib,   \"ws2_32.lib \"),但却出现下面错误。 cannot open file \'ws2_32.lib \' 我在setting->link->Object/library   modules:中填上:ws2_ ...…

查看全部问答>

调试运行不了,报错:管道的另一端上无任何进程

一个DLL,一个exe工程,加载dll使用#pragma comment lib形式,在EVC下可以运行的; 但现在要移植到ce6下,使用vs2005编译通过,部署也成功,但运行不起来,调试发现连APP的构造函数也没运行,就报错提示:管道的另一端上无任何进程。网上搜索没有 ...…

查看全部问答>

EVC自绘菜单的问题

如何去掉边框还有弹出子菜单的一个小三角形…

查看全部问答>

STM32的AD最高采样率跟USB时钟的冲突解决了没

103的中用USB的时候,AD不能工作在最高采样率 后来升级的105,107有没有解决这个问题,我的项目中就要用的1M的AD和USB啊,要是还没解决,我就要放弃stm32这鸡肋了 感觉ATMEL的也不错,高速USB,但貌似技术支持不太好,国内用的不很多,没有S ...…

查看全部问答>

读供电电压

430F1611如何读自身供电电压?哪位有例程啊?…

查看全部问答>