我的世界服务器如何做充钱网站,大地资源免费视频观看,外贸邦,网站建设 提供源码文章目录 W25Q64初始化SPI初始化W25Q初始化 AlARM模块初始化AlARM模块绘制Draw函数AlARM的更新函数AlARM中最重要的函数 W25Q64初始化
W25Q64用来存储用户设置的闹钟值#xff0c;开机的时候自动读取闹钟记录。
SPI初始化
使用CubeMx自动配置。
#define SPI1CS_ON HAL_GP… 文章目录 W25Q64初始化SPI初始化W25Q初始化 AlARM模块初始化AlARM模块绘制Draw函数AlARM的更新函数AlARM中最重要的函数 W25Q64初始化
W25Q64用来存储用户设置的闹钟值开机的时候自动读取闹钟记录。
SPI初始化
使用CubeMx自动配置。
#define SPI1CS_ON HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_RESET)
#define SPI1CS_OFF HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11, GPIO_PIN_SET)static volatile bool gSPI1TxCplt 0;
static volatile bool gSPI1RxCplt 0;static void SPI1WaitTxCplt(void)
{while(gSPI1TxCplt 0);gSPI1TxCplt 0;
}static void SPI1WaitRxCplt(void)
{while(gSPI1RxCplt 0);gSPI1RxCplt 0;
}void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{if(SPI1 hspi-Instance){gSPI1TxCplt 1;}
}void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{if(SPI1 hspi-Instance){gSPI1RxCplt 1;}
}static int SpiWrite(unsigned char *wbuf, unsigned int length){HAL_StatusTypeDef status HAL_SPI_Transmit_DMA(hspi1, wbuf, length);if(HAL_OK ! status) return -1;SPI1WaitTxCplt();return length;
}static int SpiRead(unsigned char *rbuf, unsigned int length){HAL_StatusTypeDef status HAL_SPI_Receive_DMA(hspi1, rbuf, length);if(HAL_OK ! status) return -1;SPI1WaitRxCplt();return length;
}W25Q初始化
使用SPI读取W25Q的ID验证通信的正确性
static unsigned int ReadID(void)
{ unsigned char cmd 0x9F; // W25X_JedecDeviceIDunsigned char id[3] {0};SPI1CS_ON;SpiWrite(cmd,1);SpiRead(id, 3);SPI1CS_OFF;unsigned int ID (id[0] 16) | (id[1] 8) | (id[2]);return ID;
}void W25QInit(void){int ID ReadID();if(ID ! 0xEF4017)return;printf(ID is %d,ID);
}int W25QPageWrite(uint32_t addr,unsigned char *buf,unsigned int length){unsigned char data[4];data[0] 0x02;data[1] (addr 0xFF0000)16;data[2] (addr 0x00FF00)8;data[3] (addr 0x0000FF);W25QWriteEnable();SPI1CS_ON;int ret SpiWrite(data,4);if(ret 0){SPI1CS_OFF;}ret SpiWrite(buf,length);if(ret 0){SPI1CS_OFF;}SPI1CS_OFF;WaitWrite();return (int)length;
}int W25QRead(uint32_t addr,unsigned char *buf,unsigned int length){unsigned char data[4];data[0] 0x03;data[1] (addr 0xFF0000)16;data[2] (addr 0x00FF00)8;data[3] (addr 0x0000FF);SPI1CS_ON;int ret SpiWrite(data,4);if(ret 0){SPI1CS_OFF;}ret SpiRead(buf,length);if(ret ! length){SPI1CS_OFF;}SPI1CS_OFF;return (int)length;
}void W25QEraseSector(uint32_t addr){unsigned char data[4];data[0] 0x20;data[1] (addr 0xFF0000)16;data[2] (addr 0x00FF00)8;data[3] (addr 0x0000FF);W25QWriteEnable();SPI1CS_ON;int ret SpiWrite(data,4);if(ret 0){SPI1CS_OFF;}SPI1CS_OFF;WaitWrite();}AlARM模块初始化
设置闹钟界面的信息
/** 描述设置闹钟界面的页面加载函数* 参数无 * 返回值无 */
static void AlarmLoader(uint8_t num){if(num ALARM_COUNT-1){alarm_s alarm2;if(setting.now SETTING_NOW_NONE || num ! Main_Menu.selected)Alarmget(num, alarm2);elsememcpy(alarm2, alarm, sizeof(alarm_s));AddAlarmBasic(num, alarm2);}addExitOption();
}
/** 描述设置闹钟界面的确认函数* 参数无 * 返回值无 */
static void AlarmSelect(){bool isExiting exitSelected();GetMenupre(alarmMenus);DoAction(isExiting);
}/** 描述设置闹钟界面的按钮函数等菜单基本信息 * 参数无 * 返回值无 */
void AlarmMenu(void){SetButtonFunc(menuUp, (bool (*)(void))AlarmSelect, menuDown);SetMenuFunc(preOption, AlarmSelect, nextOption,AlarmLoader);SetMenuInfo(ALARM_COUNT,MENU_TYPE_STR,PSTR(STR_ALARMMENU));SetMenuPre(alarmMenus,AlarmMenu);AnimotionInto(NULL);
}AlARM模块绘制Draw函数
alarm模块是STR菜单界面更改界面的值通过状态机的方式逐个改变每个数据的值然后通过确认赋值改变完所有数据值后保存到外部Flash中。
static void AlarmUp(void){setting.val;if(setting.val getMaxValForSetting())setting.val 0;if(setting.now SETTING_NOW_HOUR appConfig.timeMode TIMEMODE_12HR setting.val 0)setting.val 1;
}static void AlarmDown(void){setting.val--;if(setting.now SETTING_NOW_HOUR appConfig.timeMode TIMEMODE_12HR setting.val 0)setting.val 12;uint8_t max getMaxValForSetting();if(setting.val max)setting.val max;
}static void AlarmDraw(void){uint8_t w 5;uint8_t x;char buff[4];buff[1] 0x00;switch(setting.now){case SETTING_NOW_EN:x 6;w 8;buff[0] setting.val ? ALARM_SET_CHAR : ALARM_UNSET_CHAR;break;case SETTING_NOW_HOUR:x 22;w 16;break;case SETTING_NOW_MIN:x 46;w 16;break;case SETTING_NOW_AMPM:x 62;w 8;buff[0] setting.val ? CHAR_PM : CHAR_AM;break;case SETTING_NOW_DAY_MON:case SETTING_NOW_DAY_TUE:case SETTING_NOW_DAY_WED:case SETTING_NOW_DAY_THUR:case SETTING_NOW_DAY_FRI:case SETTING_NOW_DAY_SAT:case SETTING_NOW_DAY_SUN:{uint8_t dow setting.now - SETTING_NOW_DAY_MON;x 70 (8 * dow);w 8;buff[0] setting.val ? dowChars[dow] : -;}break;default:return;}uint8_t y 8 ((Main_Menu.selected * 8) - (Main_Menu.scroll * 8));OledClearArea(x, y, w);if(setting.now SETTING_NOW_HOUR || setting.now SETTING_NOW_MIN)sprintf(buff, PSTR(%02hhu), setting.val);OledShowStr(x,y,buff,OLED_8X8);
}static void SelectedAlarm()
{static uint8_t dayBit;static bool wasPM;SetMenuFunc(AlarmUp, AlarmSelect, AlarmDown, AlarmLoader);Main_Menu.func.draw AlarmDraw;switch(setting.now){case SETTING_NOW_NONE:Alarmget(Main_Menu.selected, alarm);setting.now SETTING_NOW_EN;setting.val alarm.enabled;break;case SETTING_NOW_EN:alarm.enabled setting.val;setting.now SETTING_NOW_HOUR;time_s time;time.hour alarm.hour;time.ampm CHAR_24;TimeSetMode(time, appConfig.timeMode);setting.val time.hour;wasPM (alarm.hour 12);break;case SETTING_NOW_HOUR:{uint8_t hour setting.val;uint8_t max appConfig.timeMode TIMEMODE_12HR ? 12 : 23;if(hour max)hour max;if(appConfig.timeMode TIMEMODE_12HR){time_s time;time.hour hour;time.ampm wasPM ? CHAR_PM : CHAR_AM;TimeSetMode(time, TIMEMODE_24HR);hour time.hour;}alarm.hour hour;setting.now SETTING_NOW_MIN;setting.val alarm.min;}break;case SETTING_NOW_MIN:alarm.min setting.val;if(appConfig.timeMode TIMEMODE_12HR){setting.now SETTING_NOW_AMPM;setting.val wasPM;}else{setting.now SETTING_NOW_DAY_MON;setting.val alarm.mon;}dayBit 0;break;case SETTING_NOW_AMPM:{time_s time;time.hour alarm.hour;time.ampm setting.val ? CHAR_PM : CHAR_AM;TimeSetMode(time, TIMEMODE_24HR);alarm.hour time.hour;setting.now SETTING_NOW_DAY_MON;setting.val alarm.mon;}break;case SETTING_NOW_DAY_MON:case SETTING_NOW_DAY_TUE:case SETTING_NOW_DAY_WED:case SETTING_NOW_DAY_THUR:case SETTING_NOW_DAY_FRI:case SETTING_NOW_DAY_SAT:case SETTING_NOW_DAY_SUN:if(setting.val)alarm.days | _BV(dayBit);elsealarm.days ~_BV(dayBit);dayBit;setting.val (bool)(alarm.days _BV(dayBit));if(setting.now ! SETTING_NOW_DAY_SUN)setting.now;else{AlarmSave(Main_Menu.selected, alarm);setting.now SETTING_NOW_NONE;SetMenuFunc(preOption, AlarmSelect, nextOption,AlarmLoader);Main_Menu.func.draw NULL;}break;default:break;}
}AlARM的更新函数
如果当前时间是闹钟设置的时间则进行相应。改变当前页面绘制函数称为闹钟响后的绘制函数。 void AlarmUpdate(void){bool wasGoingOff alarmSetOff;bool alarmNow goingOff();if(alarmSetOff){if(alarmNow){if(wasGoingOff ! alarmSetOff){oldDrawFunc SetDrawFunc(AlarmDraw);oldBtn1Func SetButtonSignedFunc(BTN1, NULL);oldBtn2Func SetButtonSignedFunc(BTN2, (bool (*)(void))AlarmStop);oldBtn3Func SetButtonSignedFunc(BTN3, NULL);BuzzerPlay(tuneAlarm,VOL_ALARM,PRIO_ALARM);}if(!LedFlashing()){static led_t ledFlash LEDGREEN;ledFlash (ledFlash LEDGREEN) ? LEDRED : LEDGREEN;LedFlash(ledFlash, 150);}}elseAlarmStop();}
}static void AlarmDraw(void){if((uint8_t)xTaskGetTickCount() 128)OledShowImage(16, 16, 32, 32, MAIN_MUNE[3][0], 0);// Draw timechar buff[8];sprintf(buff, PSTR(TIME_FORMAT_SMALL), timeDate.time.hour, timeDate.time.mins, timeDate.time.ampm);OledShowStr(60, 20,buff,OLED_8X8);// Draw daystrcpy(buff, days[timeDate.date.day]);OledShowStr(68,36,buff,OLED_8X8);}AlARM中最重要的函数
每次时间或者闹钟响后更新最近一个闹钟。通过计算本周开始到当前闹钟时间总共过去多少分钟最少的就是最近一个闹钟。
void GetNextAlarm(void){uint8_t next NOALARM;uint32_t nextTime (uint32_t)UINT_MAX;// Make sure time is in 24 hour modetime_s timeNow;timeNow.hour timeDate.time.hour;timeNow.ampm timeDate.time.ampm;TimeSetMode(timeNow, TIMEMODE_24HR);// Now in minutes from start of weekuint32_t now toMinutes(timeNow.hour, timeDate.time.mins 1, timeDate.date.day);// Loop through alarmsfor(uint8_t i 0;i ALARM_COUNT; i){// Get alarm dataalarm_s alarm;Alarmget(i, alarm);// Not enabledif(!alarm.enabled)continue;// Loop through daysfor(uint8_t d 0;d 7; d){// Day not enabledif(!AlarmDayEnabled(alarm.days, d))continue;// Alarm time in minutes from start of weekuint32_t alarmTime toMinutes(alarm.hour, alarm.min, d);// Minutes to alarmint timeTo alarmTime - now;// Negative result, must mean alarm time is earlier in the week than now, add a weeks timeif(timeTo 0)timeTo ((6*1440) (23*60) 59); // 10079// Is minutes to alarm less than the last minutes to alarm?if((uint32_t)timeTo nextTime){// This is our next alarmnextTime timeTo;next i;}}}// Set next alarmnextAlarm next;
}