导读
本文作为Contiki内核分析的实战环节,将之前学习梳理的Contiki内核知识,进行综合的应用,做出带有一定实用价值的项目,从而提高Contiki的应用能力。
引入
疫情影响,还没有回到公司,过年回家时只带了一块普中的51开发板,在电脑上只找到了开发板的部分资料。1602LCD屏,ds1302模块,at24c02模块,组合一下可以做一个数字万年历。系统上电后,从at24c02中读取参数,post给ds1302协程,之后ds1302协程负责读取ds1302,更新时间,并把时间信息post给1602协程。下面分模块开始拆解。
1602LCD
1602是16x2的LCD显示器,显示控制较为简单,相关背景知识略过不讲,网上可以找到大把资料。下面给出1602部分的程序,并重点关注1602控制代码和Contiki的结合。
#include"spin_1602.h"
#include"spin_timer.h"
#include"etimer.h"
#include"process.h"
#include"spin_gpio.h"
#include<reg52.h>
#include<stdio.h>
sbit rs=P2^6; //命令/数据选择
sbit rw=P2^5; //读写口
sbit e=P2^7; //锁存控制
/*DB0~DB7连到了P00~P07*/
sbit BusyFlag=P0^7;//查忙标志位
//**************************************************************************************************
//查忙
//**************************************************************************************************
void checkbusy()
{
P0= 0xFF; //单片机I/O口设置为输入
rs = 0; //命令/数据选择,为0时选择命令
rw = 1; //读/写选择,为1时选择读
e = 0;
e = 1; //使能
while (BusyFlag== 1); //查忙标志位,等待标志位为0,即表示写入完毕
e= 0; //关闭读写
}
//**************************************************************************************************
//向LCD写一命令
//**************************************************************************************************
void wcode(uchar t)
{
checkbusy(); //查忙
rs=0; // 写的是命令
rw=0; // 写状态
e=1; //使能
P0=t; //写入命令
delayms(1); //等待写入,如果时间太短,会导致液晶无法显示 大约延时2ms
e=0; //数据的锁定
}
//**************************************************************************************************
//向LCD写一数据
//**************************************************************************************************
void wdata(uchar t)
{
checkbusy(); //查忙
rs=1; // 写的是数据
rw=0; // 写状态
e=1; //使能
P0=t; //写入数据
delayms(1); //等待写入,如果时间太短,会导致液晶无法显示 大约延时2ms
e=0; //数据的锁定
}
//**************************************************************************************************
//LCD显示第一行
//**************************************************************************************************
void put_line1(uchar line1[])
{
uchar i;
wcode(0x80); //设置第一行显示地址
for(i=0;i<16;i++) //循环16次,写完1行
{
wdata(line1[i]); //写入该行数据
}
}
//**************************************************************************************************
//LCD显示第二行
//**************************************************************************************************
void put_line2(uchar line2[])
{
uchar i;
wcode(0xc0); //设置第二行显示地址
for(i=0;i<16;i++) //循环16次,写完1行
{
wdata(line2[i]); //写入该行数据
}
}
//**************************************************************************************************
//LCD 初始化
//**************************************************************************************************
void InitLCD(){
wcode(0x01); //清屏
wcode(0x06); //输入方式控制,增量光标不移位
wcode(0x0e); //显示开关控制
wcode(0x38); //功能设定:设置16x2显示,5x7显示,8位数据接口 38
}
PROCESS(lcd,"lcd");
PROCESS_THREAD(lcd, ev, dataa)
{
PROCESS_BEGIN();
InitLCD();
while(1)
{
//等待事件到来
PROCESS_WAIT_EVENT()