文档章节

瑞萨单片机(R5F100LE)串口队列的实现和UART使用心得

kangxin1234
 kangxin1234
发布于 2015/07/28 11:32
字数 1197
阅读 658
收藏 0

    介绍一下如何使用瑞萨的串口,当然使用串口的配置很简单只要,用代码生成器配置一下就行了。如果你也用的R78/G13这个套件,使用串口与电脑通信的话,还需要一个USB转TTL的插头,板子上没有232电平转换电路。如果没用过串口的话这有个教程R78/G13开发套件 快速入门教程。要有这里就不介绍如何配置串口了,重点写一下串口队列的实现,ardiuno的串口用起来很方便,因为他有一个串口队列,这篇文章介绍在,R5F100LE中实现一个环形串口队列。

    环形队列就是头尾相连的队列,如果放入的数据不超出定义的队列长度,就可以一直使用,不用考虑队列的长度。环形队列的实现,主要就是三个函数,putMsg()将数据放入队列中,getMsg()将数据从队列中取出,取出的是第一个放入队列中的数据,这也是队列的基本特点。testQueue()检查队列中是否有数据,有数据的话就放回1。

#define QUEUELEN 256

uint8_t queuehead = 0, queuetail = 0;//队列头尾的指示
uint8_t msg[QUEUELEN];//队列存放数组

void putMsg(uint8_t m)    //将数据放入队列
{
	msg[queuetail] = m;
	if(++queuetail >= QUEUELEN) queuetail = 0;
}

uint8_t getMsg(void)    //从队列中取出数据,这个数据是最先放入队列的那个数据
{
	uint8_t m = msg[queuehead];
	if(++queuehead >= QUEUELEN) queuehead = 0;
	return m;
}

uint8_t testQueue(void)//检查数据中是否有数据
{
	return (queuetail == queuehead) ? 0:1;
}



    在r_cg_serial_user.c里,这里改写了__interrupt static void r_uart0_interrupt_receive(void)这个中断函数。从串口接收到的数据直接放入环形队列中。

/***********************************************************************************************************************
* Function Name: r_uart0_interrupt_receive
* Description  : This function is INTSR0 interrupt service routine.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
__interrupt static void r_uart0_interrupt_receive(void)
{
    uint8_t rx_data;
   
    rx_data = RXD0;

	putMsg(rx_data);//将从串口中接收的数据直接放入环形队列中
}

实现一个函数,向串口中打印字符串。

void printStr(char const * ch)
{		
	R_UART0_Send(ch, strlen(ch));//发送字符串

	while(g_uart0_tx_count);//等待数据发送完成
}


测试主程序:作用每隔500ms向串口打印“500hello world”,并把从串口中接收到的数据发回串口。

#include "r_cg_macrodriver.h"
#include "r_cg_cgc.h"
#include "r_cg_port.h"
#include "r_cg_serial.h"
#include "r_cg_timer.h"
/* Start user code for include. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
#include "r_cg_userdefine.h"

/***********************************************************************************************************************
Global variables and functions
***********************************************************************************************************************/
/* Start user code for global. Do not edit comment generated here */
extern uint32_t GlobalTime;    // 全局时钟变量在定时器中断函数中每ms加1
extern volatile uint16_t  g_uart0_tx_count;//串口发送数据计数,发完数据是为0
/* End user code. Do not edit comment generated here */
void R_MAIN_UserInit(void);

/***********************************************************************************************************************
* Function Name: main
* Description  : This function implements main function.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void main(void)
{    
    /* Start user code. Do not edit comment generated here */
	uint32_t nowTime=0, lastTime=0;//时间寄存
	char chBuf[32]={0}, ch=0;//数据buff
	R_MAIN_UserInit();
	R_TAU0_Channel0_Start();//定时器通道一
	R_UART0_Start();    //开启串口

    while (1U)
    {

                nowTime=GlobalTime;//更新当前时间
		if((nowTime-lastTime)>500)//每隔500ms
		{
			lastTime = GlobalTime;
			P13.0 = ~P13.0;//测试小灯
			sprintf(chBuf, "%ld", 500);//将数字转换为字符串
			strcat(chBuf, "hello world");//字符串拼接
			//R_UART2_Send(chBuf, strlen(chBuf));			
			printStr(chBuf);//从串口发出字符串
		}
		if(testQueue())//如果队列中有数据
		{
				ch = getMsg();//取出一个数据
				R_UART0_Send(&ch, 1);//发回串口
				while(g_uart0_tx_count);//等待发送完毕
		}

    }
    /* End user code. Do not edit comment generated here */
}

/***********************************************************************************************************************
* Function Name: R_MAIN_UserInit
* Description  : This function adds user code before implementing main function.
* Arguments    : None
* Return Value : None
***********************************************************************************************************************/
void R_MAIN_UserInit(void)
{
    /* Start user code. Do not edit comment generated here */
    EI();
    /* End user code. Do not edit comment generated here */
}

/* Start user code for adding. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */



如果你想从串口接收一长串数据,你最好在检测到,串口有数据之后延时一小段时间,以保证数据全部被放入队列。

接收数据之后你要做的就是解析这些数据了。接收几个有用的函数。

函数名:char *strtok(char s[], const char *delim);

功能介绍:分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。

测试代码:

#include<string.h>
#include<stdio.h>
int main(void)
{
    char input[16]="123,23,12";
    char*p;
    
    p=strtok(input,",");
    if(p)
        printf("%s\n",p);               
    p=strtok(NULL,",");
    if(p)
        printf("%s\n",p);
    p=strtok(NULL,",");
    if(p)
	printf("%s\n",p);

    return 0;
}


运行结果

假如你输入的是PID的,KP,KI, KD的话,可以直接用atof, atoi函数将对应的数字字符串变为数字。可以在线改参数。

还有sprintf,atof,atoi这几个函数都很好用。

cubeSuite + 工程链接





















-



© 著作权归作者所有

kangxin1234

kangxin1234

粉丝 38
博文 51
码字总数 35417
作品 0
程序员
私信 提问
加载中

评论(2)

kangxin1234
kangxin1234 博主

引用来自“wolfray”的评论

在cs+里用 sprinta 有问题呀,,总是不能得到正确结果,你可以试一下浮点数的转换
你说sprintf浮点数的转换有问题吗?回头试一下。
w
wolfray
在cs+里用 sprinta 有问题呀,,总是不能得到正确结果,你可以试一下浮点数的转换
区分:串口,COM口,UART,USART

本文主要简述串口,COM口,UART,USART之间的联系和区别,另外也讲述了串口的RS-232电平和TTL电平,以及单片机与电脑之间的串口连接方式。 串口 串口,即串行接口,与之相对应的另一种接口叫...

qq_26904271
2018/04/08
0
0
SI4463低功耗测试-STC单片机一样可以超低功耗

测试名称:SI4463透传模块休眠功耗测试 测试说明:测试RF63U透传模块的低功耗性能,RF63U使用STC单片机管理SI4463芯片,提供UART与射频的透明传输功能。 测试方案:将电流表串入模块电源线,...

xulikai
2018/05/11
0
0
STC12单片机串口U盘测试程序源码

开发工具: C++ 对象: 51单片机 文件: STC12单片机串口测试程序源码 文件说明: www.usbing.net 为了便于用户熟悉优博士串口U盘USB118AD模块,帮助用户快速使用UART串口进行通信,我们特别...

dataie456000
2015/12/01
70
0
关于瑞萨(R5F100LE)中断的应用问题

@kangxin1234 你好,前辈,想跟你请教个问题: 您的这个帖子里 TRIG = 1; delayMs(2); TRIG = 0; 是为了让他出现下降沿,然后进入中断么还是直接在下面这个图片里就进入中断了,如果是下降沿...

半个句号
2018/02/21
324
2
SYD8801 UART使用说明【uart轮发数据代码实现】【 uart中断发数据代码实现】【RFSleep函数对串口的影响】【中断中调用串口打印函数有可能会造成死机】

SYD8801是一款低功耗高性能蓝牙低功耗SOC,集成了高性能2.4GHz射频收发机、32位ARM Cortex-M0处理器、128kB Flash存储器、以及丰富的数字接口。SYD8801片上集成了Balun无需阻抗匹配网络、高效...

chengdong1314
2017/06/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

c语言实现Sqlite3的创建db和增删改查db操作

SQLite,是一款轻型的数据库,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中使用广泛,现在准备学习一下sqlite3的使用方法并写一个测试demo,后面在项目智能...

jorin_zou
12分钟前
2
0
【2019年8月版本】OCP 071认证考试最新版本的考试原题-第2题

choose three Which three are true about the CREATE TABLE command? A) It can include the CREATE...INDEX statement for creating an index to enforce the primary key constraint. B) ......

oschina_5359
15分钟前
3
0
如何在二维码中循环批量插入图片

现在二维码种类比较多,为了突出二维码的个性及吸引客户,很多朋友都喜欢在二维码上插入图片。想要每个二维码都与众不同,但是有的时候需要批量插入图片数量有限,如果制作的二维码比较多的话...

中琅软件
16分钟前
4
0
LTR那点事—AUC及其与线上点击率的关联详解

LTR(Learning To Rank)学习排序是一种监督学习(SupervisedLearning)的排序方法,现已经广泛应用于信息索引,内容推荐,自然语言处理等多个领域。以推荐系统为例,推荐一般使用多个子策略...

达观数据
16分钟前
3
0
IntelliJ 如何显示代码的代码 docs

希望能够在 IntelliJ 代码上面显示方法的 docs。 如何进行显示? 你可以使用 Ctrl + Q 这个快捷键来查看方法的 Docs。 https://blog.ossez.com/archives/3061...

honeymoose
19分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部