![]() |
這種斷電換檔的手電筒爛大街了,給你個思路,單片機的RAM數據可以在極低的電壓下保持數據不變。斷電后單片機不工作了,但是RAM數據還是能保存一會的。起不到精準控制,但是實現簡單的手電筒換擋功能還行。 |
lkc8210 發表于 2024-8-22 09:20 您好,代碼已經實現了. 想問下您, P32引腳那個電容需要怎么處理嗎? P32 - 22uf電容- gnd 中間是否需要并聯電阻? 減速掉電? 或者二極管之類的處理 |
lkc8210 發表于 2024-8-22 09:20 弄好了.我在P32加了個電容到負極. 現在可以實現我說的那個功能了 超強 ![]() |
lkc8210 發表于 2024-8-22 09:20 您的代碼我之前不能換擋是因為沒有加 eeprom擦除 現在在寫前面加一句 IapErase(EEPROMId); 就好了 但是就一直換擋,關開一次就換一次檔.不能保存當前檔位 還有哪里需要糾正嗎 |
lkc8210 發表于 2024-8-21 11:11 您這個是不是電路上還有要求啊? P32 我原本接的按鍵 |
lkc8210 發表于 2024-8-22 09:20 哥,我好像有一點點懂了. 我一直糾結程序上的問題. 剛剛我試了一個很垃圾的手電.好像不是代碼上的問題. 就是那個電容的問題. 我那個垃圾手電,我把電容用鉛筆涂黑了(就是短路了) 現在不能換擋,一直是那個檔位. 好像換擋取決于那個電容.. 電容的大小決定關機再開機多久時間換擋. |
vb2002 發表于 2024-8-21 22:01 我那個只是示范,你還要加上之前的EEPRom循環讀寫的代碼 |
vb2002 發表于 2024-8-21 22:51 我沒寫過這種代碼,但是有了具體思路不是很簡單的事情嗎?按鍵判斷的代碼本站也有很多的 |
yaosongjin 發表于 2024-8-21 08:38 就是代碼不會弄呢 可以給個代碼嗎? 實現半按換擋 我這個麻煩死了 |
lkc8210 發表于 2024-8-21 11:11 按您的代碼現在一直是亮度5,可以點亮 但是不能換擋. 能幫看看嗎? 是我沒有上真機實驗嗎? 我用的開發板弄的
|
vb2002 發表于 2024-8-20 18:47 我的代碼是檢測P32腳電容的電平來判斷掉電時間的 |
vb2002 發表于 2024-8-20 18:49 你可能沒搞清楚程序運行的邏輯,按照這個電路來操作的話: 1.上電后MCU復位進入工作狀態 2.當按下電源開關后MCU開始記錄4腳電平保持的時間 3.假如維持的低電平為500MS又變高了,就切換模式或者亮度之類的功能并且寫入內存 4.假如維持的電平超過500MS說明是手電要關機,就不再做任何處理 5.如果要做雙擊的話,同樣在按鍵處理這一塊想辦法 |
yaosongjin 發表于 2024-8-20 17:39 主要是代碼方面弄不好.
|
![]() |
vb2002 發表于 2024-8-20 16:51 MCU第4腳用于判斷開關狀態。 |
5fee380a84e8dab4c9fc65f1daf0e8ca.png (60.68 KB, 下載次數: 21)
vb2002 發表于 2024-8-20 16:42 為啥不加電容? |
yaosongjin 發表于 2024-8-20 15:55 如果設置睡眠模式,是不是10uf可以堅持很久很久? 甚至都不用eeprom都行了? 就是這個斷電判斷不會弄 |
倒不如關機后短按開機、開機后短按切換亮度、長按關機。。。 |
人中狼 發表于 2024-8-20 13:05 我能想通,但是代碼搞不定. 標志位就是斷電那個狀態怎么讀取出來. 之前有人發了一個帖子,,當時我還不懂啥意思,都已經斷電了.為啥還要在斷電的時候開啟睡眠模式. 現在懂了.是讓電容繼續給單片機供電 |
咋看都象是一個按鍵實現開機、關機、調亮度的功能。。。 |
lkc8210 發表于 2024-8-20 14:22 試了,試出來就是普通的eeprom讀寫switch里面的循環. 沒有加電容實現不了那個半按.. |
樓主可以在MCU供電腳串一個二極管,MCU供電加個幾微法的大電容,加二極管的目的就是防止開關斷開后電容給后級供電,只要滿足電容只給MCU供電,即使外部電源斷了,幾微法的電容也可以維持幾秒鐘時間,這時候你就可以做些判斷保存數據的動作 |
vb2002 發表于 2024-8-20 10:42 試了我的代碼了嗎? |
感覺你這個想復雜了吧,跟普通手電操作一樣,只不過增加一個標志而已 |
vb2002 發表于 2024-8-20 10:42 斷電了,單片機就沒有用了,就沒有"斷電時間"這個概念了 如果要有記憶功能,就只能是重新關機開機,再關機開機換擋 沒有別的選擇了,除非換開關種類 |
Y_G_G 發表于 2024-8-19 13:03 手電開關有兩種. 你說的那種是電子開關的.可以長期不斷電.不設計eeprom也可以保存檔位 我說的這個是機械開關,就是開關裝在尾部,依靠斷電通電來開關手電的 市面銷售的開關邏輯是, 123檔,現在我調到2檔,關機,下次開機也是2檔. 如果想換擋,就開機關機(時間低于500ms就換擋到3檔) 如果超過500ms就還是2檔 現在我能實現的就是,開機 2檔,超過3秒就eeprom保存當前2檔,,如果開機3秒內在關機開機.那就進行換擋. 雖然都能達到目的, 但是我這個有點麻煩,如果開機超過3秒后,需要換擋,必須重新關機開機,再關機開機換擋. 如果您感興趣,發視頻給您看看? |
首先,你要清楚你的要求是什么,在我的印象中,沒有什么手電是對關機斷電時長有要求的 按照正常的實際情況操作是這樣的: 1,先看你18650是怎么接在電路上的,如果是焊線的,那就不需要用到EEPROM,直接保存到一個全局變量就可以了,如果涉及充電,這個變量就得有三個工作模式:1點燈,2充電,3關機 STC進入掉電模式,喚醒后全局變量的值是不會變的 2,如果電池是可以拿出來的那種,那就是每次按下按鍵,點燈模式切換后就把點燈模式保存到EEPROM,下次開機時,先讀取EEPROM的模式,再進行點燈 但有一點要記得,STC的是"EEPROM"是FLASH,不是像24C01那種的,百度一下就知道了 |
明日之星8 發表于 2024-8-16 16:41 這個不符合實際情況啊 實際情況就是一個18650電池, 加一個燈珠,中間有個驅動. 再要去弄其他電池麻煩哦. |
本帖最后由 明日之星8 于 2024-8-16 17:38 編輯 加二極管和電池(比如2032電池),檢測到無外接供電時單片機 就進入掉電模式,同時打開掉電喚醒定時器并計時。 比如STC8H1K08可以做到2微安,2032電池可以連續計時三到五年以上, 時間誤差不到10% 有RTC功能的單片機(比如STC8H1K08T),外接32k晶振可以做到相對精確的計時。 |
飛云居士 發表于 2024-8-15 12:35 感覺這個像是ai寫的. 而且里面提到的是3秒 |
根據提供的描述,我們需要編寫一段C51代碼來實現以下功能: 按下開關開機,再次按下關機,這個過程中PWM亮度保持不變,即只讀取EEPROM中的值。 如果在開機狀態下,半按(斷電時間小于500ms)則進入下一個狀態,切換PWM的占空比,實現4個檔位的循環切換。 如果關機時長大于3秒,則寫入當前的PWM占空比到EEPROM;如果小于3秒,則寫入新的EEPROM值。 如果關機后馬上開機,不進行任何操作。 下面是一段簡化的C51代碼示例,用于實現上述功能。請注意,這只是一個基礎示例,實際應用中可能需要根據具體的硬件和EEPROM庫進行調整。 #include <reg51.h> #define PWM_PIN P1 // 假設PWM控制引腳連接到P1端口 #define BUTTON_PIN P3_2 // 假設按鈕連接到P3.2端口 #define EEPROM_ADDR 0x30 // 假設EEPROM寫入地址 unsigned char pwm_duty = 10; // PWM占空比 unsigned char pwm_level = 0; // 當前PWM級別 unsigned char eeprom_value = 0; // 從EEPROM讀取的值 bit is_power_on = 0; // 電源狀態標志 void DelayMs(unsigned int ms) { // 延時函數,需要根據實際的晶振頻率調整 // 這里只是一個示例,具體實現需要根據硬件來編寫 } void SetPWM(unsigned char duty) { // 設置PWM占空比的函數 // 這里只是一個示例,具體實現需要根據硬件來編寫 } void EEPROMWrite(unsigned char addr, unsigned char value) { // 寫入EEPROM的函數 // 這里只是一個示例,具體實現需要根據EEPROM庫來編寫 EERDB = value; // 設置EEPROM數據寄存器 EEMPE = 1; // 允許EEPROM編程 EENH = 0; // 選擇高8位地址 EEL = 1; // 選擇低8位地址 EEAR = addr; // 設置EEPROM地址寄存器 EEWE = 1; // 寫入使能 EEWE = 0; // 清除寫入使能 } unsigned char EEPROMRead(unsigned char addr) { // 從EEPROM讀取的函數 EEAR = addr; // 設置EEPROM地址寄存器 EEN2 = 1; // 啟用EEPROM EEN1 = 1; EEN0 = 1; unsigned char value = EERDB; // 讀取數據 EEN2 = 0; EEN1 = 0; EEN0 = 0; return value; } void main() { SetPWM(eeprom_value); // 初始設置PWM為EEPROM中的值 while(1) { if (!BUTTON_PIN) { // 檢測按鈕是否被按下 DelayMs(20); // 消抖 if (!BUTTON_PIN) { if (is_power_on) { // 關機操作 unsigned int shutdown_time = 0; while (!BUTTON_PIN) { shutdown_time++; if (shutdown_time > 3000) { // 大于3秒 EEPROMWrite(EEPROM_ADDR, pwm_duty); break; } } SetPWM(0); // 關閉PWM is_power_on = 0; } else { // 開機操作 is_power_on = 1; SetPWM(pwm_duty); // 根據EEPROM設置PWM } } } else { if (is_power_on) { // 半按操作,切換PWM占空比 DelayMs(500); // 等待500ms if (BUTTON_PIN) { pwm_level++; if (pwm_level > 3) { pwm_level = 0; } pwm_duty = (pwm_duty + 20) % 101; // 增加20%,循環4個級別 SetPWM(pwm_duty); } } } } } |
vb2002 發表于 2024-8-13 10:01
|
lkc8210 發表于 2024-8-12 10:30 能否提供一份代碼? 我做的另一個手電是 要開機3秒才能判定是否eeprom保存 |
wufa1986 發表于 2024-8-12 08:09 可以提供一份代碼給我嗎? 謝謝 |
wufa1986 發表于 2024-8-12 08:09 用哪個比較方便呢? 我見很多手電用的都是九齊或者應廣 |
如果要測關機時間就要加電容電阻來檢測掉電時間 上電時引腳輸入模式,檢測電容電平, 檢測完后引腳轉為輸出模式對電容充電 電容并聯一個電阻來讓電容在關電時放電 |
我做過電筒一段時間,這個需要硬件判斷關機時間,STC做這種功能不是很方便,需要的硬件比較多 |