本文来源电子发烧友社区,作者: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中操作
3 将SDK里的 lf_iot_sdk 和 components 整个目录复制到工作目录下
3.配置环境变量,分别把 riscv 的SDK头文件主目录和连接的库文件目录放入环境变量中
建立编译环境完成后,下一步进行响应的代码的开发,这次主要参考了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上传的数据。
全部0条评论
快来发表一下你的评论吧 !