【跃昉科技BF2开发板试用体验】跃昉BF2物联网开发板试用体验

描述

本文来源电子发烧友社区,作者:Aivisus, 帖子地址:https://bbs.elecfans.com/jishu_2293431_1_1.html

通过电子发烧友论坛的试用申请,拿到了这款跃昉BF2物联网开发模块,模块比预想的要小很多,尺寸在一寸多点。但别看他小,它可是五脏俱全。把它与 IV18 荧光管放一起对比一下,就看出来了,它的体积是非常迷你的了。

官方对BF2的模块介绍是这样的,BF2开发板包含以下组件:LF-WM03模块、I/O口、JP短接口、State led状态指示灯、Power led电源指示灯、RST复位按键、MiniUSB口、Power selected电源选择口、四线插座、USB-to-UART桥接器、Data transfer selected传输选择。主要是面向智慧能源、智慧物流、智慧城市、智慧工厂等工业物联网应用,是一款基于RISC-V架构的边缘智能处理器产品

跃昉科技

这里介绍一下 IV18这个荧光管,IV-18(ИВ-18)荧光电子数码管,是上世纪80-90年代前苏联的产物,冷战时期曾大量制造并用于军事设备;它是一根管内嵌入了8个7段数字,并且每个数字右下角都有小数点,在管子的左侧,还有一个表示负数的短横线,在短横线上面还有一个较大的圆点符号。驱动它的整个电路由升压电路、MCU主控、RTC模块、VFD驱动、外围及接口器件这几部分组成。升压电路部分使用的还是廉价并经典的MC34063做高压升压,外扩了MOS管IRLR024,升压效率大幅提高,而且MC34063、电感、MOS管一点也感觉不到温度;IV-18的推荐工作电压为45v-70v,工作在49v的时候效果最佳。

因为IV18荧光管模块带有 温度,湿度,环境亮度的传感器,但其不具有网络功能,因此想利用 BF的物联网功能,将 IV18改造成为一款物联网时钟,主要改造的目的是:

1、把IV18物联网模块的传感数据通过物联网协议传输到物联网平台上,以便实时记录环境的监测数据

2.、能够对时钟模块进行自动的校时,以便让时钟模块运行更加准确

这两个模块它们放在一起是这样的:

跃昉科技

根据IV18 MCU的电路图,IV18时钟模块使用的是STC12C56的8位单片机驱动,C51的代码开发。这里通过串口连接两个模块,达到数据双向通讯和控制的目的。

这里通过BF2的P12,14 的UART0 与 STC12c56的P3.1,P3.0 相连即可,需要注意的是,STC处理器的工作电压是5V, 按理需要对STC的IO进行分压后,再与BF2连接,但在实际测试中,直接连接也可以工作,因此就简化处理,直接连接上了。

跃昉科技

硬件连接很简单,硬件连接完后,主要的工作是软件开发,分别开发C51代码与BF2模块上的代码。

这里把 BF2当成STC单片机的上位机即可,完成数据收发与命令的接收控制逻辑。

C51的开发比较简单,不多说,主要的代码如下:

/**
**  I/O接口定义
**/
sbit	SCL			=	P2^7;		//DS3231数据接口
sbit	SDA			=	P2^6;		//DS3231数据接口
/**
** 	DS3231常数定义
**/
#define DS3231_WriteAddress 0xD0    //器件写地址
#define DS3231_ReadAddress  0xD1    //器件读地址
#define DS3231_SECOND       0x00    //秒
#define DS3231_MINUTE       0x01    //分
#define DS3231_HOUR         0x02    //时
#define DS3231_WEEK         0x03    //星期
#define DS3231_DAY          0x04    //日
#define DS3231_MONTH        0x05    //月
#define DS3231_YEAR         0x06    //年
//1
#define DS3231_ALARM1SECOND 0x07    //秒
#define DS3231_ALARM1MINUTE 0x08    //分
#define DS3231_ALARM1HOUR   0x09    //时
#define DS3231_ALARM1WEEK   0x0A    //星期/日
//2
#define DS3231_ALARM2MINUTE 0x0b    //分
#define DS3231_ALARM2HOUR   0x0c    //时
#define DS3231_ALARM2WEEK   0x0d    //星期/日
#define DS3231_CONTROL      0x0e    //控制寄存器
#define DS3231_STATUS       0x0f    //状态寄存器
#define BSY                 2       //忙
#define OSF                 7       
#define DS3231_XTAL         0x10    
#define DS3231_TEMPERATUREH 0x11    
#define DS3231_TEMPERATUREL 0x12    
i=17;
for(;i>0;i--)
{
DIN = Tmp&0x0001;	 *nop* ();
CLK = 1;			 *nop* ();
CLK = 0;			 *nop* ();
Tmp>>=1;
}
LOAD	=	1;	 *nop* ();
LOAD	=	0;	 *nop* ();
/**
** 	函数名称:			void	TimerInit()
**	功能描述:			定时器初始化
**	创建时间:			15:39
**	版    本:			v1.0.0
**/
void	TimerInit()
{
AUXR	=	0xC0;			//Timer0 12T Timer1 1T
TMOD	=	0x11;			//Set Timer0 & Timer1 as mode1(16bit)
TL1		=	T1MS;			//Initial timer1 low byte
TH1		=	T1MS>>8;		//Initial timer1 high byte
TR1		=	1;				//Timer1 start running
TL0		=	T125US;			//Initial timer0 low byte
TH0		=	T125US>>8;		//Initial timer0 high byte
TR0		=	1;				//Timer0 start running
}
/**
** 	函数名称:			void	Timer0Interrupt() interrupt 1
**	功能描述:			定时器0中断函数
**	创建时间:			15:39
**	版    本:			v1.0.0
**/
void	Timer0Interrupt() interrupt 1
{
TL0		=	T125US;			//Reload timer0 low byte
TH0		=	T125US>>8;		//Reload timer0 high byte
IR_RX();
//*******************************
//冒号闪烁PWM
if(DOTpwmloop<31)		DOTpwmloop++;	else	DOTpwmloop=0;
if(DOTpwmloop<=DOTcut)	DOTS=!DOTonoff;	else	DOTS=DOTonoff;
}
/**
** 	函数名称:			void	Timer1Interrupt() interrupt 3
**	功能描述:			定时器1中断函数
**	创建时间:			15:39
**	版    本:			v1.0.0
**/
void	Timer1Interrupt() interrupt 3
{
TL1		=	T1MS;			//Reload timer1 low byte
TH1		=	T1MS>>8;		//Reload timer1 high byte
if(RGBloop<1024)	RGBloop++;
if(DOTloopelse{DOTloop=0;if(DOTcut<31)	DOTcut++;}
if(NUMloopelse{NUMloop=0;if(NUMcut<20)	NUMcut++;}
if(NUMmode==1)
{
	if(NUM500msloop<1000)		NUM500msloop++;
	if(NUM500msloop==300)		NUMcut=0;
}
F_50ms_Loop++;
F_100ms_Loop++;
F_250ms_Loop++;
F_500ms_Loop++;
F_1s_Loop++;
F_2s_Loop++;
if(F_50ms_Loop	>=50)	{F_50ms		=	1;	F_50ms_Loop			=	0;}
if(F_100ms_Loop	>=100)	{F_100ms	=	1;	F_100ms_Loop		=	0;}
if(F_250ms_Loop	>=250)	{F_250ms	=	1;	F_250ms_Loop		=	0;}
if(F_500ms_Loop	>=500)	{F_500ms	=	1;	F_500ms_Loop		=	0;}
if(F_1s_Loop	>=1000)	{F_1s		=	1;	F_1s_Loop			=	0;}
if(F_2s_Loop	>=2000)	{F_2s		=	1;	F_2s_Loop			=	0;}
}
/**
** 	函数名称:			void	Beep(uchar AT)
**	功能描述:
**	创建时间:			01 23:09
**	版    本:			v1.0.0
**/
void	Beep(uchar AT)
{
ulong i,j;
uchar D=35,E=32,Y=3;
switch(AT)
{
case BEEPPOWERON:	 			//正常开机		·
j=0;while(j<400){SPK=!SPK;for(i=0;ibreak;
case BEEPSHUTDOWN:				//正常关机
j=0;while(j<1800){SPK=!SPK;for(i=0;ifor(i=0;i<15;i++)DelayMS(Y);
j=0;while(j<400){SPK=!SPK;for(i=0;ifor(i=0;i<15;i++)DelayMS(Y);
j=0;while(j<400){SPK=!SPK;for(i=0;ibreak;
case BEEPERROR:					//错误		····
j=0;while(j<400){SPK=!SPK;for(i=0;ifor(i=0;i<15;i++)DelayMS(Y);
j=0;while(j<400){SPK=!SPK;for(i=0;ifor(i=0;i<15;i++)DelayMS(Y);
j=0;while(j<400){SPK=!SPK;for(i=0;ifor(i=0;i<15;i++)DelayMS(Y);
j=0;while(j<400){SPK=!SPK;for(i=0;ibreak;
case BEEPCONFIRM:				//确认
j=0;while(j<2800){SPK=!SPK;for(i=0;ibreak;
case BEEPOPERATE:				//正常操作		·
j=0;while(j<400){SPK=!SPK;for(i=0;ibreak;
}
SPK=0;
}
/**
** 	函数名称:			void	RGB1s()
**	功能描述:			变换一次模式
**	创建时间:			16:29
**	版    本:			v1.0.0
**/
void	RGB1s()
{
RGBloop	=	0;
if(RGBlastcolor<13)	RGBlastcolor++;else	 RGBlastcolor=0;
}
/**
** 	函数名称:			void	RGBFlash(uchar M)
**	功能描述:			LED闪烁
**	入口参数:			M:	模式
**	创建时间:			16:29
**	版    本:			v1.0.0
**/
void	RGBFlash(uchar M)
{
if((RGBloop/RGBLOOPCOUNT)==RGBlaststate)	return;
RGBlaststate=(RGBloop/RGBLOOPCOUNT);
switch(M)
{
	case	RGBMOFF:
		RGBr	=	0;
		RGBg	=	0;
		RGBb	=	0;
		break;
	case	RGBMR:
		if(RGBlastcolor%2)
		{
			if(RGBrif(RGBg>0)	RGBg--;
			if(RGBb>0)	RGBb--;
		}
		else
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMRG:
		if(RGBlastcolor%2)
		{
			if(RGBrif(RGBgif(RGBb>0)	RGBb--;
		}
		else
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMG:
		if(RGBlastcolor%2)
		{
			if(RGBr>0)	RGBr--;
			if(RGBgif(RGBb>0)	RGBb--;
		}
		else
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMGB:
		if(RGBlastcolor%2)
		{
			if(RGBr>0)	RGBr--;
			if(RGBgif(RGBbelse
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMB:
		if(RGBlastcolor%2)
		{
			if(RGBr>0)	RGBr--;
			if(RGBg>0)	RGBg--;
			if(RGBbelse
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMRB:
		if(RGBlastcolor%2)
		{
			if(RGBrif(RGBg>0)	RGBg--;
			if(RGBbelse
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMRGB:
		if(RGBlastcolor%2)
		{
			if(RGBrif(RGBgif(RGBbelse
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMFADE:
		if(RGBlastcolor==0)			//
			{if(RGBrif(RGBgif(RGBbelse if(RGBlastcolor==2)	//
			{if(RGBrif(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor==4)	//绿
			{if(RGBrif(RGBgif(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor==6)	//
			{if(RGBr>0)		RGBr--;	if(RGBgif(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor==8)	//蓝
			{if(RGBr>0)		RGBr--;	if(RGBgif(RGBbelse if(RGBlastcolor==10)	//
			{if(RGBr>0)		RGBr--;	if(RGBg>0)	RGBg--;	if(RGBbelse if(RGBlastcolor==12)	//红
			{if(RGBrif(RGBg>0)	RGBg--;	if(RGBbelse
			{if(RGBr>0)	RGBr--;	if(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;		}
		break;
	case	RGBMFADEC:
		if(RGBlastcolor%7==0)			//
			{if(RGBrif(RGBgif(RGBbelse if(RGBlastcolor%7==1)	//
			{if(RGBrif(RGBg>0)	RGBg--;	if(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor%7==2)	//绿
			{if(RGBrif(RGBgif(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor%7==3)	//
			{if(RGBr>0)		RGBr--;	if(RGBgif(RGBb>0)	RGBb--;	}
		else if(RGBlastcolor%7==4)	//蓝
			{if(RGBr>0)		RGBr--;	if(RGBgif(RGBbelse if(RGBlastcolor%7==5)	//
			{if(RGBr>0)		RGBr--;	if(RGBg>0)	RGBg--;	if(RGBbelse if(RGBlastcolor%7==6)	//红
			{if(RGBrif(RGBg>0)	RGBg--;	if(RGBbbreak;
}
LEDSendData(RGBr,RGBg,RGBb);
}
/**
** 	函数名称:			void	DOT1s()
**	功能描述:			DOT变换一次模式
**	创建时间:			03 17:33
**	版    本:			v1.0.0
**/
void	DOT1s()
{
DOTcut	=	0;
DOTonoff=!DOTonoff;
}
/**
** 	函数名称:			void	NUM1s()
**	功能描述:			NUM变换一次模式
**	创建时间:			05 15:52
**	版    本:			v1.0.0
**/
void	NUM1s()
{
NUM500msloop=	0;
NUMcut		=	0;
}
/**
** 	函数名称:			bit	CheckTime(bit DT)
**	功能描述:			日期时间格式检测
**	出口参数:			0:检查日期格式	1:检查时间格式
**	出口参数:			0:有误	1:格式正确
**	创建时间:			01-29 21:25
**	版    本:			v1.0.0
**/
bit	CheckTime(bit DT)
{
xdata uchar Mo,Da,Ho,Mi,Se;
xdata uint Ye;
bit Ok=1;
Ye=S_YEAR;
Mo=S_MONTH;
Da=S_DAY;
Ho=S_HOUR;
Mi=S_MINUTE;
Se=S_SECOND;
if(DT==0)
{
	if(Ye>99)			return 0;
	if((Mo>12)||(Mo<1))	return 0;
	if(Da<1)			return 0;
	switch(Mo)
	{
		case 1:case 3:case 5:case 7:case 8:case 10:case 12:if(Da>31)return 0;break;
		case 4:case 6:case 9:case 11:if(Da>30)return 0;break;
		case 2:
			if((Ye%4==0)&&(Ye!=0))
			{if(Da>29)return 0;}
			else
			{if(Da>28)return 0;}
	}
}
else
{
	if(Ho>23) return 0;
	if(Mi>59) return 0;
	if(Se>59) return 0;
}
return	1;
}
/**
** 	函数名称:			void	Num_Process(uchar N)
**	功能描述:			处理函数
**	创建时间:			04 16:11
**	版    本:			v1.0.0
**/
void	Num_Process(uchar N)
{
switch(NOWSTATE)
{
case	S_SETYEAR:						//年
Beep(BEEPOPERATE);
S_YEAR	=	(S_YEAR*10+N)%100;
break;
case	S_SETMONTH:						//月
Beep(BEEPOPERATE);
S_MONTH	=	(S_MONTH*10+N)%100;
break;
case	S_SETDAY:						//日
Beep(BEEPOPERATE);
S_DAY	=	(S_DAY*10+N)%100;
break;
case	S_SETHOUR:						//时
Beep(BEEPOPERATE);
S_HOUR	=	(S_HOUR*10+N)%100;
break;
case	S_SETMINUTE:					//分
Beep(BEEPOPERATE);
S_MINUTE=	(S_MINUTE*10+N)%100;
break;
case	S_SETSECOND:					//秒
Beep(BEEPOPERATE);
S_SECOND=	(S_SECOND*10+N)%100;
break;
case	S_NORMAL:
case	S_POWEROFF:
if(N>0 && N<10)
{
Beep(BEEPOPERATE);
RGBmode	=	N;
}
break;
case	S_SETA1M:						//1分钟
case	S_SETA2M:						//2分钟
Beep(BEEPOPERATE);
S_MINUTE=	(S_MINUTE*10+N)%100;
break;
case	S_SETA1H:						//1小时
case	S_SETA2H:						//2小时
Beep(BEEPOPERATE);
S_HOUR=	(S_HOUR*10+N)%100;
break;
}
}
/**
** 	函数名称:			void	IR_Process(uchar IrData)
**	功能描述:
**	创建时间:			04 16:06
**	版    本:			v1.0.0
**/
void	IR_Process(uchar IrData)
{
uchar	i;
uint	j;
if(F_Alarm)
{
	Beep(BEEPCONFIRM);
	AlarmReset();
	F_Alarm	=	0;
	return;
}
switch(IrData)
{
	//**
	case	0x45:
		if(NOWSTATE==S_POWEROFF)
		{
			Beep(BEEPPOWERON);
			DelayMS(200);
			LASTN[0]=	' ';
			LASTN[1]=	' ';
			LASTN[2]=	' ';
			LASTN[3]=	' ';
			LASTN[4]=	' ';
			LASTN[5]=	' ';
			NUM1s();
			NOWSTATE	=	S_NORMAL;
			POWERON		=	0;
		}
		else
		{
			NOWSTATE	=	S_POWEROFF;
			Beep(BEEPSHUTDOWN);
			for(i=0;i<6;i++){LASTN[i]=Num[i];Num[i]=' ';}
			DOTonoff	=	0;
			DOT1s();
			NUM1s();
		}
		break;
	//**
	case	0x46:	 							//LIGHT
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_POWEROFF)
		{
			Beep(BEEPOPERATE);
			if(RGBmode)
			{
				RGBmodesave	=	RGBmode;
				RGBmode		=	RGBMOFF;
			}
			else
				RGBmode		=	RGBmodesave;
		}
		break;
	//**
	case	0x47:
		if(NOWSTATE==S_NORMAL)
		{
			Beep(BEEPPOWERON);
			DOTonoff	=	1;
			DOT1s();
			S_YEAR	=	YEAR;
			S_MONTH	=	MONTH;
			S_DAY	=	DAY;
			S_HOUR	=	HOUR;
			S_MINUTE=	MINUTE;
			S_SECOND=	SECOND;
			NUMLOOPCOUNT=	5;
			RGBmodeold	=	RGBmode;
			RGBmode		=	RGBMR;
			RGBlastcolor=	0;
			RGB1s();
			NOWSTATE=	S_SETSECOND;
		}
		else if(NOWSTATE==S_SHOWDATE)
		{
			Beep(BEEPPOWERON);
			DOTonoff	=	0;
			DOT1s();
			S_YEAR	=	YEAR;
			S_MONTH	=	MONTH;
			S_DAY	=	DAY;
			S_HOUR	=	HOUR;
			S_MINUTE=	MINUTE;
			S_SECOND=	SECOND;
			NUMLOOPCOUNT=	5;
			RGBmodeold	=	RGBmode;
			RGBmode		=	RGBMG;
			RGBlastcolor=	0;
			RGB1s();
			NOWSTATE=	S_SETDAY;
		}
		else if(NOWSTATE==S_SHOWA1)
		{
			Beep(BEEPPOWERON);
			S_SECOND=	A1ONOFF;
			S_HOUR	=	A1H;
			S_MINUTE=	A1M;
			NUMLOOPCOUNT=	5;
			RGBmodeold	=	RGBmode;
			RGBmode		=	RGBMB;
			RGBlastcolor=	0;
			RGB1s();
			NOWSTATE=	S_SETA1M;
		}
		else if(NOWSTATE==S_SHOWA2)
		{
			Beep(BEEPPOWERON);
			S_SECOND=	A2ONOFF;
			S_HOUR	=	A2H;
			S_MINUTE=	A2M;
			NUMLOOPCOUNT=	5;
			RGBmodeold	=	RGBmode;
			RGBmode		=	RGBMB;
			RGBlastcolor=	0;
			RGB1s();
			NOWSTATE=	S_SETA2M;
		}
		else if(NOWSTATE==S_SETYEAR || NOWSTATE==S_SETMONTH || NOWSTATE==S_SETDAY || NOWSTATE==S_SETHOUR || NOWSTATE==S_SETMINUTE || NOWSTATE==S_SETSECOND || NOWSTATE==S_SETA1H || NOWSTATE==S_SETA1M || NOWSTATE==S_SETA2H || NOWSTATE==S_SETA2M)	//如果在调整时间日期状态下
		{
			Beep(BEEPERROR);
			DelayMS(200);
			NUMLOOPCOUNT=	25;
			RGBmode		=	RGBmodeold;
			RGB1s();
			NOWSTATE	=	S_NORMAL;
		}
		break;
	//**
	case	0x44:	 							//DATE
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_SHOWMOONDATE || NOWSTATE==S_SHOWTEMP || NOWSTATE==S_SHOWA1 || NOWSTATE==S_SHOWA2)
		{
			Beep(BEEPOPERATE);
			Num[0]	=	'0'+(FormatDate?MONTH:YEAR)/10;
			Num[1]	=	'0'+(FormatDate?MONTH:YEAR)%10;
			Num[2]	=	'0'+(FormatDate?DAY:MONTH)/10;
			Num[3]	=	'0'+(FormatDate?DAY:MONTH)%10;
			Num[4]	=	'0'+(FormatDate?YEAR:DAY)/10;
			Num[5]	=	'0'+(FormatDate?YEAR:DAY)%10;
			DOTonoff	=	0;
			DOT1s();
			NOWSTATE	=	S_SHOWDATE;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWDATE)
		{
		  	Conversion(0,(YEAR/10)*16+YEAR%10,(MONTH/10)*16+MONTH%10,(DAY/10)*16+DAY%10);
			Beep(BEEPOPERATE);
			Num[0]	=	'0'+(FormatDate?month_moon:year_moon)/16;
			Num[1]	=	'0'+(FormatDate?month_moon:year_moon)%16;
			Num[2]	=	'0'+(FormatDate?day_moon:month_moon)/16;
			Num[3]	=	'0'+(FormatDate?day_moon:month_moon)%16;
			Num[4]	=	'0'+(FormatDate?year_moon:day_moon)/16;
			Num[5]	=	'0'+(FormatDate?year_moon:day_moon)%16;
			DOTonoff	=	1;
			DOT1s();
			NOWSTATE	=	S_SHOWMOONDATE;
			ShowDateLoop=	0;
		}
		break;
	//**
	case	0x40:	 							//ALARM
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_SHOWMOONDATE || NOWSTATE==S_SHOWDATE || NOWSTATE==S_SHOWTEMP || NOWSTATE==S_SHOWA2)
		{
			Beep(BEEPOPERATE);
			Num[0]	=	'a';
			Num[1]	=	'1';
			Num[2]	=	(A1ONOFF?'0'+A1H/10:' ');
			Num[3]	=	(A1ONOFF?'0'+A1H%10:'0');
			Num[4]	=	(A1ONOFF?'0'+A1M/10:'f');
			Num[5]	=	(A1ONOFF?'0'+A1M%10:'f');
			DOTonoff	=	1;
			DOT1s();
			NOWSTATE	=	S_SHOWA1;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWA1)
		{
			Beep(BEEPOPERATE);
			Num[0]	=	'a';
			Num[1]	=	'2';
			Num[2]	=	(A2ONOFF?'0'+A2H/10:' ');
			Num[3]	=	(A2ONOFF?'0'+A2H%10:'0');
			Num[4]	=	(A2ONOFF?'0'+A2M/10:'f');
			Num[5]	=	(A2ONOFF?'0'+A2M%10:'f');
			DOTonoff	=	1;
			DOT1s();
			NOWSTATE	=	S_SHOWA2;
			ShowDateLoop=	0;
		}
		break;
	//**
	case	0x43:	 							//TEMP
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_SHOWMOONDATE || NOWSTATE==S_SHOWDATE || NOWSTATE==S_SHOWA1 || NOWSTATE==S_SHOWA2)
		{
			Beep(BEEPPOWERON);
			for(i=1;i<20;i++)
			{
				j=GetTemp();
				if(j>60)	DelayMS(50);
				else i=20;
			}
			if(FormatTemp)	j=32+j*1.8;
			Num[0]	=	' ';
			Num[1]	=	((j>99)?'0'+(j%1000)/100:' ');
			Num[2]	=	((j>9)?'0'+(j%100)/10:' ');
			Num[3]	=	j%10+'0';
			Num[4]	=	' ';
			Num[5]	=	(FormatTemp?'f':'c');
			DOTonoff	=	0;
			DOT1s();
			NOWSTATE	=	S_SHOWTEMP;
			ShowDateLoop=	0;
		}
		break;
	//**
	case	0x07:	 							//LEFT
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_POWEROFF)
		{
			if(RGBbright>=10)
			{
				RGBbright-=7;
				RGBr=0;RGBg=0;RGBb=0;
				Beep(BEEPOPERATE);
			}
		}
		else if(NOWSTATE==S_SETSECOND)	{NOWSTATE=S_SETMINUTE;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETMINUTE)	{NOWSTATE=S_SETHOUR;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETHOUR)	{NOWSTATE=S_SETSECOND;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETYEAR)	{NOWSTATE=S_SETDAY;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETDAY)		{NOWSTATE=S_SETMONTH;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETMONTH)	{NOWSTATE=S_SETYEAR;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA1M)		{NOWSTATE=S_SETA1H;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA1H)		{NOWSTATE=S_SETA1M;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA2M)		{NOWSTATE=S_SETA2H;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA2H)		{NOWSTATE=S_SETA2M;		Beep(BEEPOPERATE);}
		break;
	//**
	case	0x15:	 							//RIGHT
		if(NOWSTATE==S_NORMAL || NOWSTATE==S_POWEROFF)
		{
			if(RGBbright<=24)
			{
				RGBbright+=7;
				RGBr=0;RGBg=0;RGBb=0;
				Beep(BEEPOPERATE);
			}
		}
		else if(NOWSTATE==S_SETSECOND)	{NOWSTATE=S_SETHOUR;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETHOUR)	{NOWSTATE=S_SETMINUTE;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETMINUTE)	{NOWSTATE=S_SETSECOND;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETYEAR)	{NOWSTATE=S_SETMONTH;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETMONTH)	{NOWSTATE=S_SETDAY;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETDAY)		{NOWSTATE=S_SETYEAR;	Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA1M)		{NOWSTATE=S_SETA1H;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA1H)		{NOWSTATE=S_SETA1M;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA2M)		{NOWSTATE=S_SETA2H;		Beep(BEEPOPERATE);}
		else if(NOWSTATE==S_SETA2H)		{NOWSTATE=S_SETA2M;		Beep(BEEPOPERATE);}
		break;
	//**
	case	0x09:	 							//FUNC
		if(NOWSTATE==S_NORMAL)
		{
			Beep(BEEPPOWERON);
			if(NUMmode<2)NUMmode++;else NUMmode=0;//NUMmode切换
			if(NUMmode==1)NUMLOOPCOUNT=15;else NUMLOOPCOUNT=25;	//调整各模式的颜色渐变STEP毫秒数
		}
		else if(NOWSTATE==S_SETA1H || NOWSTATE==S_SETA1M || NOWSTATE==S_SETA2H || NOWSTATE==S_SETA2M)
		{
			Beep(BEEPPOWERON);
			if(S_SECOND)S_SECOND=0;else S_SECOND=1;
		}
		else if(NOWSTATE==S_SHOWTEMP)			//显示温度状态
		{
			Beep(BEEPPOWERON);
			if(FormatTemp)FormatTemp=0;else FormatTemp=1;
			FormatSave();
			for(i=1;i<20;i++)
			{
				j=GetTemp();
				if(j>60)	DelayMS(50);
				else i=20;
			}
			if(FormatTemp)	j=32+j*1.8;			//℉
			Num[0]	=	' ';
			Num[1]	=	((j>99)?'0'+(j%1000)/100:' ');
			Num[2]	=	((j>9)?'0'+(j%100)/10:' ');
			Num[3]	=	j%10+'0';
			Num[4]	=	' ';
			Num[5]	=	(FormatTemp?'f':'c');
			DOTonoff	=	0;
			DOT1s();
			NUM1s();
			NOWSTATE	=	S_SHOWTEMP;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWDATE)
	   	{
			Beep(BEEPOPERATE);
			if(FormatDate)FormatDate=0;else FormatDate=1;
			FormatSave();
			Num[0]	=	'0'+(FormatDate?MONTH:YEAR)/10;
			Num[1]	=	'0'+(FormatDate?MONTH:YEAR)%10;
			Num[2]	=	'0'+(FormatDate?DAY:MONTH)/10;
			Num[3]	=	'0'+(FormatDate?DAY:MONTH)%10;
			Num[4]	=	'0'+(FormatDate?YEAR:DAY)/10;
			Num[5]	=	'0'+(FormatDate?YEAR:DAY)%10;
			DOTonoff	=	0;
			DOT1s();
			NOWSTATE	=	S_SHOWDATE;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWMOONDATE)
		{
		  	Conversion(0,(YEAR/10)*16+YEAR%10,(MONTH/10)*16+MONTH%10,(DAY/10)*16+DAY%10);
			if(FormatDate)FormatDate=0;else FormatDate=1;
			FormatSave();
			Beep(BEEPOPERATE);
			Num[0]	=	'0'+(FormatDate?month_moon:year_moon)/16;
			Num[1]	=	'0'+(FormatDate?month_moon:year_moon)%16;
			Num[2]	=	'0'+(FormatDate?day_moon:month_moon)/16;
			Num[3]	=	'0'+(FormatDate?day_moon:month_moon)%16;
			Num[4]	=	'0'+(FormatDate?year_moon:day_moon)/16;
			Num[5]	=	'0'+(FormatDate?year_moon:day_moon)%16;
			DOTonoff	=	1;
			DOT1s();
			NOWSTATE	=	S_SHOWMOONDATE;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWA1)
		{
			Beep(BEEPOPERATE);
			if(A1ONOFF)A1ONOFF=0;else A1ONOFF=1;
			AlarmSave(1,A1H,A1M,A1ONOFF);
			Num[0]	=	'a';
			Num[1]	=	'1';
			Num[2]	=	(A1ONOFF?'0'+A1H/10:' ');
			Num[3]	=	(A1ONOFF?'0'+A1H%10:'0');
			Num[4]	=	(A1ONOFF?'0'+A1M/10:'f');
			Num[5]	=	(A1ONOFF?'0'+A1M%10:'f');
			DOTonoff	=	1;
			DOT1s();
			NOWSTATE	=	S_SHOWA1;
			ShowDateLoop=	0;
		}
		else if(NOWSTATE==S_SHOWA2)
		{
			Beep(BEEPOPERATE);
			if(A2ONOFF)A2ONOFF=0;else A2ONOFF=1;
			AlarmSave(2,A2H,A2M,A2ONOFF);
			Num[0]	=	'a';
			Num[1]	=	'2';
			Num[2]	=	(A2ONOFF?'0'+A2H/10:' ');
			Num[3]	=	(A2ONOFF?'0'+A2H%10:'0');
			Num[4]	=	(A2ONOFF?'0'+A2M/10:'f');
			Num[5]	=	(A2ONOFF?'0'+A2M%10:'f');
			DOTonoff	=	1;
			DOT1s();
			NUM1s();
			NOWSTATE	=	S_SHOWA2;
			ShowDateLoop=	0;
		}
		break;
	//**
	case	0x16:
		if(NOWSTATE==S_NORMAL)
		{
			Beep(BEEPOPERATE);
			if(FormatTime)FormatTime=0;else FormatTime=1;
			FormatSave();
			Num[0]	=	(FormatTime?'1':'2');
			Num[1]	=	(FormatTime?'2':'4');
			Num[2]	=	'h';
			Num[3]	=	' ';
			Num[4]	=	' ';
			Num[5]	=	' ';
			DOTonoff	=	0;
			DOT1s();
			NUM1s();
			NOWSTATE	=	S_SHOWTEMP;
			ShowDateLoop=	0;
		}
		if(NOWSTATE==S_SETHOUR || NOWSTATE==S_SETMINUTE || NOWSTATE==S_SETSECOND)
		{
			GetDateTime();
			S_YEAR	=	YEAR;
			S_MONTH	=	MONTH;
			S_DAY	=	DAY;
			if(CheckTime(1))
			{
				ModifyTime(S_YEAR,S_MONTH,S_DAY,S_HOUR,S_MINUTE,S_SECOND);
				Beep(BEEPCONFIRM);
			}
			else
			{
				Beep(BEEPERROR);
			}
			DelayMS(200);
			NUMLOOPCOUNT=	25;
			RGBmode		=	RGBmodeold;
			NOWSTATE	=	S_NORMAL;
		}
		if(NOWSTATE==S_SETYEAR || NOWSTATE==S_SETMONTH || NOWSTATE==S_SETDAY)
		{
			GetDateTime();
			S_HOUR		=	HOUR;
			S_MINUTE	=	MINUTE;
			S_SECOND	=	SECOND;
			if(CheckTime(0))
			{
				ModifyTime(S_YEAR,S_MONTH,S_DAY,S_HOUR,S_MINUTE,S_SECOND);
				Beep(BEEPCONFIRM);
			}
			else
			{
				Beep(BEEPERROR);
			}
			DelayMS(200);
			NUMLOOPCOUNT=	25;
			RGBmode		=	RGBmodeold;
			RGB1s();
			NOWSTATE	=	S_NORMAL;
		}
		if(NOWSTATE==S_SETA1H || NOWSTATE==S_SETA1M || NOWSTATE==S_SETA2H || NOWSTATE==S_SETA2M)
		{
			if(CheckTime(1))
			{
				if(NOWSTATE==S_SETA1H || NOWSTATE==S_SETA1M)		AlarmSave(1,S_HOUR,S_MINUTE,S_SECOND);
				else if(NOWSTATE==S_SETA2H || NOWSTATE==S_SETA2M)	AlarmSave(2,S_HOUR,S_MINUTE,S_SECOND);
				Beep(BEEPCONFIRM);
			}
			else
			{
				Beep(BEEPERROR);
			}
			DelayMS(500);
			NUMLOOPCOUNT=	25;
			RGBmode		=	RGBmodeold;
			RGB1s();
			NOWSTATE	=	S_NORMAL;
		}
		break;
	//**
	case	0x19:
		if(NOWSTATE==S_SETYEAR || NOWSTATE==S_SETMONTH || NOWSTATE==S_SETDAY || NOWSTATE==S_SETHOUR || NOWSTATE==S_SETMINUTE || NOWSTATE==S_SETSECOND || NOWSTATE==S_SETA1H || NOWSTATE==S_SETA1M || NOWSTATE==S_SETA2H || NOWSTATE==S_SETA2M)	//如果在调整时间日期状态下
		{
			Beep(BEEPERROR);
			DelayMS(200);
			NUMLOOPCOUNT=	25;
			RGBmode		=	RGBmodeold;
			RGB1s();
			NOWSTATE	=	S_NORMAL;
		}
		break;
	//**
	case	0x0D:	Num_Process(0); 	break;				//0
	case	0x0C:	Num_Process(1); 	break;				//1
	case	0x18:	Num_Process(2); 	break;				//2
	case	0x5E:	Num_Process(3); 	break;				//3
	case	0x08:	Num_Process(4); 	break;				//4
	case	0x1C:	Num_Process(5); 	break;				//5
	case	0x5A:	Num_Process(6); 	break;				//6
	case	0x42:	Num_Process(7); 	break;				//7
	case	0x52:	Num_Process(8); 	break;				//8
	case	0x4A:	Num_Process(9); 	break;				//9
}
}

)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>)>;i++){;}j++;};>;i++){;}j++;}>;i++){;}j++;}>;i++){;}j++;};i++){;}j++;};i++){;}j++;};i++){;}j++;}>;i++){;}j++;};i++){;}j++;};i++){;}j++;};>)>)>

BF2的开发,主要按开发板所带的开发资料来进行,BF2开发板带科丰富的开发资料,需要仔细的看一下,主要开发指导文件在,《BF2 SDK入门指南》主要介绍快速了解SDK的使用,

BF2开发资料有:

SPEC 目录,主要是开发板,芯片规格书以及SDK 文档资料

SDK 主要是SDK软件,编译工具链以及例程

Dev_tools 是一些下载工具

SDK里主要的内容有:

Component: SDK提供的组件

Customer_App:SDK提供的DEMO,开发主要参考这些demo代码来完成

Docs: 即文档目录,所有SDK的库,函数的说明,以及编译工具的配置,说明

Make_script_riscv 编译相关脚本

Toolchain : 编译工具链

tools 烧写工具

在BF2的SDK里提供了三种平台的开发环境,分别是 Darwin, Linux , MySYS

这里我选用的是 Linux的开发环境,搭建Linux开发环境方法如下:

1.在Linux 下建立一个主工作目录,也可以创建一个 DOCK,在DOCK中操作

  1. 将BF2提供的 riscv.rar 文件解压开,把其中的 Linux 目录复制到 Linux 下 。

3 将SDK里的 lf_iot_sdk 和 components 整个目录复制到工作目录下

3.配置环境变量,分别把 riscv 的SDK头文件主目录和连接的库文件目录放入环境变量中

  1. 在Linux 下执行编译命令,编译一个测试文件, 测试开发环境创建正确,在Linux下可以看到编译器的版本如下

跃昉科技

建立编译环境完成后,下一步进行响应的代码的开发,这次主要参考了SDK Customer_app 的三个主要DEMO工程,分别是:

sdk_app_uart_ctl

sdk_at_module

lf686_gate_demo

他们分别是串口通信功能的实现,串口命令的的开发,以及 IOT 网关的实现代码,以便使用 MQTT 物联网协议,将传感数据传送到案例物联网平台上。

/*
 * Copyright (c) 2020 LeapFive.
 *
 * This file is part of
 *     *** LeapFive Software Dev Kit ***
 *      (see www.leapfive.com).
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of LeapFive Lab nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include 
#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "demo.h"

void log_step(const char *step[2])
{
    printf("%s   %srn", step[0], step[1]);
}

void cmd_uart_flush(char *buf, int len, int argc, char **argv)
{
    int fd;
    const char *pbuf1 = "1>0123456789abcdefghijklmnopqrstuvwxyz>0123456789abcdefghijklmnopqrstuvwxyz>0123456789abcdefghijklmnopqrstuvwxyz>2";
    const char *pbuf2 = "3<0123456789abcdefghijklmnopqrstuvwxyz<0123456789abcdefghijklmnopqrstuvwxyz<0123456789abcdefghijklmnopqrstuvwxyz<4";


    fd = aos_open("/dev/ttyS1", 0);
    if (fd < 0) {
        printf("open ttyS1 errorrn");
        return;
    }
    while (1)
    {
        aos_write(fd, pbuf1, strlen(pbuf1));
        while ( 1 == UART_GetTxBusBusyStatus(1)) {
        }
        //lf_uart_flush(1);
        aos_ioctl(fd, IOCTL_UART_IOC_BAUD_MODE, 115200);
        aos_ioctl(fd, IOCTL_UART_IOC_BAUD_MODE, 4800);
        vTaskDelay(2000);
        aos_write(fd, pbuf2, strlen(pbuf2));
        aos_ioctl(fd, IOCTL_UART_IOC_BAUD_MODE, 115200);
        aos_ioctl(fd, IOCTL_UART_IOC_BAUD_MODE, 4800);
        vTaskDelay(2000);
   }
}

void bluart_block_entry(void *arg)
{
    int length;
    uint8_t buf_recv[50];
    const char *name = arg;
    uint32_t count = 0;

    int fd = aos_open(name, 0);
    aos_ioctl(fd, IOCTL_UART_IOC_BAUD_MODE, 115200);
    aos_ioctl(fd, IOCTL_UART_IOC_READ_BLOCK, 0);

    log_info("%s-> fd = %drn", name, fd);

    while (1) {
        length = aos_read(fd, buf_recv, sizeof(buf_recv));
        if (length > 0) {
            log_info("%s name.length = %d:rn", name, length);
            aos_write(fd, buf_recv, length);
        }
        vTaskDelay(500);
        log_info("test.rn");
        count++;

        if (count == 5) {
            log_info("set noblock.rn");
            aos_ioctl(fd, IOCTL_UART_IOC_READ_NOBLOCK, 0);
        }

        if (count == 10) {
            log_info("set block.rn");
            aos_ioctl(fd, IOCTL_UART_IOC_READ_BLOCK, 0);
        }
    }
}

void bluart_ioctl1_entry(void *arg)
{
    int res;
    char buf_recv[16];
    const char *name = arg;
    uart_ioc_waitread_t waitr_arg;
    int fd;

    fd = aos_open(name, 0);

    log_info("%s-> fd = %drn", name, fd);

    while (1) {
        //log_info("ready to read.rn");
        waitr_arg.buf = buf_recv;
        waitr_arg.read_size = sizeof(buf_recv);
        waitr_arg.timeout = 5000;
        res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRD_MODE, (unsigned long)(&waitr_arg));
        //res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRDFULL_MODE, (unsigned long)(&waitr_arg));
        //res = aos_ioctl(fd, IOCTL_UART_IOC_WAITENDBYTE_MODE, (unsigned long)(&waitr_arg));
        if (res > 0) {
            log_info("%s name.length = %d:rn", name, res);
            aos_write(fd, buf_recv, res);
        }
    }
}

void bluart_ioctl2_entry(void *arg)
{
    int res;
    char buf_recv[16];
    const char *name = arg;
    uart_ioc_waitread_t waitr_arg;
    int fd;

    fd = aos_open(name, 0);

    log_info("%s-> fd = %drn", name, fd);

    while (1) {
        //log_info("ready to read.rn");
        waitr_arg.buf = buf_recv;
        waitr_arg.read_size = sizeof(buf_recv);
        waitr_arg.timeout = 0;
        res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRD_MODE, (unsigned long)(&waitr_arg));
        //res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRDFULL_MODE, (unsigned long)(&waitr_arg));
        if (res > 0) {
            log_info("%s name.length = %d:rn", name, res);
            aos_write(fd, buf_recv, res);
        }
    }
}

void bluart_ioctl3_entry(void *arg)
{
    int res;
    char buf_recv[16];
    const char *name = arg;
    uart_ioc_waitread_t waitr_arg;
    int fd;

    fd = aos_open(name, 0);

    log_info("%s-> fd = %drn", name, fd);

    while (1) {
        log_info("ready to read.rn");
        waitr_arg.buf = buf_recv;
        waitr_arg.read_size = sizeof(buf_recv);
        waitr_arg.timeout = AOS_WAIT_FOREVER;
        res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRD_MODE, (unsigned long)(&waitr_arg));
        //res = aos_ioctl(fd, IOCTL_UART_IOC_WAITRDFULL_MODE, (unsigned long)(&waitr_arg));
        if (res > 0) {
            log_info("%s name.length = %d:rn", name, res);
            aos_write(fd, buf_recv, res);
        }
    }
}

void cmd_uart_ioctl(char *buf, int len, int argc, char **argv)
{
    if (argc != 2) {
        log_error("arg error.rn");
        return;
    }
    if (0 == memcmp(argv[1], "1", 1)) {
        aos_task_new("bluart_ioctl", bluart_ioctl1_entry, "/dev/ttyS1", 2048);
    } else if (0 == memcmp(argv[1], "2", 1)) {
        aos_task_new("bluart_ioctl", bluart_ioctl2_entry, "/dev/ttyS1", 2048);
    } else if (0 == memcmp(argv[1], "3", 1)) {
        aos_task_new("bluart_ioctl", bluart_ioctl3_entry, "/dev/ttyS1", 2048);
    }
}

void cmd_uart_block(char *buf, int len, int argc, char **argv)
{
    //aos_task_new("uart0_block", bluart_block_entry, "/dev/ttyS0", 2048);
    aos_task_new("uart1_block", bluart_block_entry, "/dev/ttyS1", 2048);
}

const static struct cli_command cmds_user[] STATIC_CLI_CMD_ATTRIBUTE = {
    { "uartflush", "uart flush", cmd_uart_flush},
    { "uartblock", "uart block", cmd_uart_block},
    { "uartioctl", "uart io control", cmd_uart_ioctl},
};

int uart_ctl_cli_init(void)
{
    // static command(s) do NOT need to call aos_cli_register_command(s) to register.
    // However, calling aos_cli_register_command(s) here is OK but is of no effect as cmds_user are included in cmds list.
    // XXX NOTE: Calling this *empty* function is necessary to make cmds_user in this file to be kept in the final link.
    //return aos_cli_register_commands(cmds_user, sizeof(cmds_user)/sizeof(cmds_user[0]));
    return 0;
}

代码开发主要使用原始的 VI 方式进行,如下图:

跃昉科技

在 阿里云物联网平台上测试接收到的MQTT消息,说明已经能过够收到IV18上传的数据。

跃昉科技

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分