本文來源電子發燒友社區,作者: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中操作
- 將BF2提供的 riscv.rar 文件解壓開,把其中的 Linux 目錄復制到 Linux 下 。
3 將SDK里的 lf_iot_sdk 和 components 整個目錄復制到工作目錄下
3.配置環境變量,分別把 riscv 的SDK頭文件主目錄和連接的庫文件目錄放入環境變量中
- 在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上傳的數據。
-
躍昉科技
+關注
關注
0文章
66瀏覽量
1888 -
開發板試用
+關注
關注
3文章
301瀏覽量
2040
發布評論請先 登錄
相關推薦
評論