首页 > 学习收获 > 嵌入式相关 > Neuron芯片中SCI的应用
2008
01-03

Neuron芯片中SCI的应用

前几天在做这个项目,将PIC和Neuron芯片通过SCI连接起来。不得不说ECHELON公司的文档有点不清晰。尽管文档很多,但是仅仅增加了开发者查询资料的困难程度而已。恩。

至于Neuron芯片是什么,呵呵,百度一下你就知道。大致的说就是应用于LonWorks现场总线的专用通讯芯片,内部封装了LonTalk协议的低下全部六层,用户仅需要实现第七层就可以。很方便,另一方面,也意味着不开源、封闭……呵呵,当然,这个不是我们关心的方面了。

从ECHELON的文档看来,好像最近才加入了SCI模块,这样就可以实现一个硬件的UART。之前的Neuron芯片虽然也提供了串行接口,但是好像是软件实现的,所以速度较慢。有硬件的移位器当然还是硬件的好。

然后,实际使用的话,UART仅可以进行异步通信。从名字也可以看出来么。使用IO8作为接收,IO10作为发送。在Neuron C中声明一个SCI口很简单,语法是

IO_8 sci [baud (const-expr)] [twostopbits] io-object-name;

其中,baud参数是用来指定波特率的,使用其中的const-expr参数来指定通讯时使用的波特率。这个const-expr是一个enum,包括SCI_300, SCI_600, SCI_1200, SCI_2400, SCI_4800, SCI_9600, SCI_19200, SCI_38400, SCI_57600, and SCI_115200这些可用的值。twostopbits如果也出现在声明句中,那么就指定通信时停止位是两位。

当然,程序中也可以更改波特率,使用 io_set_baud(io-obj-name, rate) 函数就可以。io-obj-name就是你定义的SCI的端口名称,rate就是列举出来的那些可用值的其中一个。要说明的是:如果在声明SCI端口时并没有指定波特率,即没有使用baud参数,那么在使用串行通信前,必须用io_set_baud来指定一个有效的波特率。

还有就是,这个enum是在一个默认不被包含的一个头文件里面被定义的,所以编译时可能会出现SCI_19200未被定义的错误。这时在程序的common.h或者别的头文件里面包含该头文件即可。(头文件名字忘了。。明天到公司查一下再补上……)

然后……这个波特率定义还真麻烦……为了能够自定义波特率,程序中一定要有这么一行参数定义

#pragma specify_io_clock clock-rate

其中clock-rate是你Neuron芯片外接的晶振的频率,必须是”10 MHz”,”6.5536 MHz”,”5 MHz”或者”2.5 MHz”中的一个,包括引号。

那么定义完成后,就可以使用SCI来进行通讯了。但是,SCI的通讯和普通IO通讯不同,熟悉的io_in和io_out是不可用的。可用的函数如下:

unsigned short buffer-size;
unsigned short buffer[buffer-size];
unsigned short io_in_request(io-object-name, buffer, buffer-size);
unsigned short io_out_request(io-object-name, buffer, buffer-size);
unsigned short io_in_ready(io-object-name);
unsigned short io_out_ready(io-object-name);
unsigned short sci_get_error(io-object-name);
void sci_abort(io-object-name);

其中开始两个是buff的定义。io_in_request和io_out_request用以初始化和开始一个输入和一个输出。输入的值放在buffer里面或者输出buffer里面的值,输入或者输出的字符个数由buffer-size定义。比如,SCI接口名sciport,定义了一个unsigned short buff[20],然后准备接收8个字符,那么就

io_in_request(sciport,buff,8);

至于发送方面,本人项目中没有用到,不敢乱说。呵呵。仔细研究文档+自己好好试验,肯定都能出来的。恩。

那么,如何判定其接收完成以进行处理动作呢?看了看文档,只是说了SCI是使用中断模式、以及提供了两个启用、禁用中断的函数,然后说在接收完buffer-size这么多数据后接收就完成。但是没有说接收完成会怎么样。好在还有一个io_in_ready。这个函数在其他情况下,返回值是指示接收是否成功完成的。不过在SCI里面,有点特殊,这个函数的返回的是当前通过SCI接收到的字符数。有了这个,就比较方便了。比如刚才的例子,我们希望每接收到8个字节就处理一下,那么就可以

when(io_in_ready(sciport)==8)
{…}

呵呵。接收部分我就发现这么多,高手也请多多指教。

另外,在这里也共享一段我项目里面SCI接收的代码。

//定义段
#pragma specify_io_clock “10 MHz”
IO_8 sci baud (SCI_19200) SCIPort;
unsigned short buff[10];

//开机后有个定时器延时。延时结束才开始SCI接收
when(timer_expires(starttimer))
{
io_in_request(SCIPort,buff,8);
}

when(io_in_ready(SCIPort)==8)
{
//do sth. with buff[]
…..
sci_abort(SCIPort); //安全起见先中断SCI
io_in_request(SCIPort,buff,8); //再度开始接收
}

代码测试,在3120+PIC16F73,19200,8,n,1参数下通过。可正常接收。

最后编辑:
作者:龙天
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。