上一篇blink的例程使用的外设驱动为GPIO;这一篇继续基本外设驱动串口,串口设置波特率默认115200
例程目录:tinyos-main-release_tinyos_2_1_2\apps\cc2538_Test\TestPrintf
包含文件:
Makefile
TestPrintfAppC.nc----configuration
TestPrintfC.nc---------module
Makefile
COMPONENT=TestPrintfAppC
CFLAGS += -I$(TOSDIR)/lib/printf
CFLAGS += -DUSE_TIMER_HANDLER
CFLAGS += -DUSE_UART_HANDLER
CFLAGS += -DUART0_TX_INTERRUPT_OFF
include $(MAKERULES)
结合第一篇blink nesC语法
Makefile的书写规则COMPONENT应该=[configuration],此处为TestPrintfAppC
结尾处include $(MAKERULES) 为固定写法,旨在使用makerules
CFLAGS += -I$(TOSDIR)/lib/printf 使用printf库的路径
下面的是用户自己的条件编译,
CFLAGS += -DUSE_TIMER_HANDLER 使用Timer中断
CFLAGS += -DUSE_UART_HANDLER 使用UART中断
CFLAGS += -DUART0_TX_INTERRUPT_OFF 关闭UART TX中断
TestPrintfAppC.nc
#define NEW_PRINTF_SEMANTICS
#include "printf.h"
configuration TestPrintfAppC{
}
implementation {
components MainC, PrintfC, TestPrintfC;
components new TimerMilliC();
TestPrintfC.Boot -> MainC;
TestPrintfC.Timer -> TimerMilliC;
}
使用:
components为:MainC,PrintfC, TestPrintfC,TimerMilliC();
interface为:Boot,Timer
#define NEW_PRINTF_SEMANTICS 可以在编译的时候测试一下注释掉,其实就是对应有#warnning一些
TestPrintfC.nc
/*******************************************************************
*实验2----串口printf实验,串口(默认波特率115200)
*节点需求数1
*编译命令make cc2538cb
********************************************************************/
#include "printf.h"
module TestPrintfC @safe() {
uses {
interface Boot;
interface Timer;
}
}
implementation {
uint8_t dummyVar1 = 123;
uint16_t dummyVar2 = 12345;
uint32_t dummyVar3 = 1234567890;
/***************************************************
*启动事件
****************************************************/
event void Boot.booted() {
/**开启一秒的周期性定时器(单位毫秒) Timer**/
call Timer.startPeriodic(1000);
}
/***************************************************
*Timer定时时间到事件
****************************************************/
event void Timer.fired() {
/**串口(默认波特率115200)打印*********************************/
printf("Hi I am writing to you from my TinyOS application!!\n");
printf("Here is a uint8: %u\n", dummyVar1);
printf("Here is a uint16: %u\n", dummyVar2);
printf("Here is a uint32: %lu\n", dummyVar3);
/**启动缓冲区数据送至uart tx************************************/
printfflush();
}
}
可以参考blink的nesC的基础语法阅读代码;不多做介绍,实验结果可以去参考视频;
再此之前大家可以通过TestPrintfAppC.nc----configuration发现并没有wire PintfC组件,也可以通过yeti2组件的
图形查看会发现没有组件和他有连线,TestPrintfC.nc---------module部分没有使用PintfC的interface,事实上PintfC组件也并没有provides 任何interface,为什么可以使用PintfC/PintfP中的方法呢?
此处可以引申一个nesC的编程技巧,自己去查看tinyos-main-release_tinyos_2_1_2\tos\lib\printf下
PrintfC.nc和PrintfP.nc组件源码,在此略过;其实他们的连接是隐藏的,通过printf.h文件,当TestPrintfC.nc中调用printf和printfflush的时候通过printf.h指定到了PintfC提供的函数;这样的写法当然也是不科学的,增加了代码的阅读难度,一般常常用来自己编写printf等覆盖gcc等编译器自带的printf等库函数的实现;
下面介绍一下为什么不推荐使用PintfC组件来实现printf函数
1,打印是先放入缓冲区,调用printfflush()函数才操作串口
2,和blip等网络测试的blip_printf.h冲突
那么更加简单的做法呢?直接#include "printf.h",调用printf函数就行了,当然Makefile也要加入
CFLAGS += -DNOT_USE_PRINTFC_BUT_USE_PRINT
这个条件编译宏的含义就在于不使用PintfC组件,直接使用printf函数完成串口打印,再此例程后面的例程都是使用此直接法;
我们得出的结论是TinyOS系统,并不是把所有的代码写成nesC组件就高效,有时候简单的一个c或者一个h头文件就能搞定
printf的意义在于打印结果,调试使用较多!如需修改波特率可以去tinyos-main-release_tinyos_2_1_2\tos\chips\cc2538\usart下找到对应的文件修改就行!
nesC福利:
default-----除去C语言的switch使用,在nesC中常常用来修饰event,表示此事件不做处理
写法1:
event void Timer.fired() {
}
写法2:
default event void Timer.fired() {
}两者是等价的
@safe()---
常常用来修饰module,表明该组件内存等是安全的,也即是越界,野指针等是检查过的
如:
module TestPrintfC @safe()
关键字等的介绍会随着例程出现慢慢补充介绍!