久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 775|回復: 0
打印 上一主題 下一主題
收起左側(cè)

為PZ-51單板機上的實時時鐘加裝后備紐扣電池,和Windows時間同步

[復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:1130439 發(fā)表于 2024-9-3 22:41 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
............ 很久很久沒有玩8位單板機了 .... N 年以前用匯編語言玩了一陣朋友送的一個Z80單板機,做了一個繼電器溫控的方案后,軟硬件一共500出手掉了。 一直到2009年在上海遇到Zilog 公司創(chuàng)始人,Z80設計師 Federico Faggin (F.F.) 后,又重新對單片機產(chǎn)生了一點興趣。和F.F 一起用餐時,他告訴我,他的z80 已經(jīng)升級到 ez80, 可以用 C 語言玩...... 真的好玩嗎? 我在Intel 公司玩了n 年的 C 語言,用來測試芯片的,現(xiàn)在可以用C 來玩 ez80? ...  于是不假思索就向F.F.索要開發(fā)套件。F.F. 很大方,當場送了一套價值400 元,包裝精美的套件,看來他也是有備而來啊 ... :) ....  回家后搗鼓了一陣,搞了一個小玩具:躲在蚊帳里用紅外遙控器開關外面的電燈 ... 后來幾次搬家,把那個小玩具弄丟了。

時鐘  tick tick 一晃一晃離開8080/z80/8051 的時代已經(jīng)40多年了,全球 ARM core 的單片機和開發(fā)板大行其道,卻發(fā)現(xiàn)國內(nèi)還有大量資源和時間投在了學習51 單板機上面。的確,工業(yè)級性能的805x 還有很多應用場合,但對于所謂的【創(chuàng)客】,基于ARM core 的系統(tǒng)其實性價比和可玩性更高。但如果你確認是做電子電氣自動化工程師的料,就花點時間玩一下51吧。。。不過網(wǎng)上【巨量】的視頻講座和學習材料,對真正希望學好單片機的同學其實幫助并不大:一則內(nèi)容拖沓,二則組織混亂,三則浪費時間最終把【玩興】消磨掉而圓不了工程師的夢。 也許講者是有開發(fā)經(jīng)驗的,甚至是開發(fā)的高手,但未必是【講學】的行家 ?

.....我肯定在暗示你,我即是開發(fā)高手又是講解大師.... Follow ME ....


閑話少敘,我們先來 hack 普中-51 單板機(A2 型)上 RTC 芯片 DS 1302, 把這款板子上的這個設計【缺陷】hack 掉,讓板子能夠真正做到(斷電后也能) 實時計時(包括 日月天-星期)....

【免責聲明:你如果按照本貼改動你板子上的軟硬件,貼主對可能產(chǎn)生的任何損害一概不負任何法律責任 】

材料和工具:
* 一顆3V 可充電 鋰電池(例如 ML 2032)
* 兩根杜邦線
* 一個微型芯片管腳夾具 (我犧牲了一個 用在數(shù)字邏輯儀上的測試夾具)
* 電焊等
* 普中-51 單板機的官方電氣線路圖、說明書

步驟:
* 斷電
* 鋰電池 (+)極和DS 1302 的VCC1 連接。板子原來設計是VCC1 懸空,(板子正反面都)沒有引出,供大家玩一下。
* 鋰電池 (- )極和板子的 GND 連接
   (注:“連接” , 可以理解為焊接、夾接等等任何你認為方便的線路導通連接 ....  DS 1302 貼裝芯片的管腳間距較小,焊接需要很好的焊接工具和水                 平,我就偷懶了,用數(shù)字邏輯儀上的測試夾具夾一下 )
* 上電
* 修改(官方)【21-DS1302時鐘實驗】示例程序當中的 void ds1302_init(void) 函數(shù),在其中加上 涓流充電寄存器的相關設置:

void ds1302_init(void)
{
        u8 i=0;
        ds1302_write_byte(0x8E,0X00);
        ds1302_write_byte(0x90,0xA5); // 0xA5 = 1010- 0101, 表示內(nèi)部充電線路選用 一個二極管和一個2K 歐姆的電阻                                                      // 由此限定最大充電電流約為 2.2mA  (  ~ = ( 5V - 0.7V)/2K Ohm  = 2.15 mA
        for(i=0;i<7;i++)
        {
                ds1302_write_byte(gWRITE_RTC_ADDR[ i],gDS1302_TIME[ i]);        
        }
        ds1302_write_byte(0x8E,0X80);        //disable write...
}


* 修改(官方)【 18-串口通信實驗】當中的字符接受代碼,使得單片機能夠從 Windows PC 主機收取完整的時間-日期信息:

if(UART_RX_STA&0x8000)//判斷串口是否收到完整的 9 字節(jié)時間-日期數(shù)據(jù)(7 Byte RTC 寄存器數(shù)據(jù) + 2 Byte 通信結(jié)束標志)
  {
    ds1302_write_byte(0x8E,0X00);        // 準備更新 ds1302 RTC 當中的 時間-日期數(shù)據(jù)
    for(i=0;i<7;i++)
    {
      ds1302_write_byte(gWRITE_RTC_ADDR[ i],UART_RX_BUF[ i]);  // 逐字節(jié)更新 ....      
    }
   ds1302_write_byte(0x8E,0X80);  //禁止寫RTC,主要是防止管腳上偶發(fā)信號【噪音,毛刺】意外破壞RTC 里面的內(nèi)容
   beep_alarm(50,15);         // 給一個完成任務的蜂鳴器提示。。。 可有可無。。。。
   key_value = 13;// effectively jump to key-13 process,這個key_value 變量的來源是有故事的,以后再講吧。
   UART_RX_STA=0;////清除標記,以便下次接受新的 日期-時間更新數(shù)據(jù)
}


* 在 PC Windows 上寫一個小程序 ( 偷懶的可以用 教程里推薦的串口通訊程序 把時間-日期數(shù)據(jù) 手工發(fā)給單片機,但無法和PC 上的時間準確同步 )
======================================================================================
//  版權說明: 程序的框架源自 Rahul.S  , 我填寫了 main 里面 和 51單片機 UART - RTC 通信的具體代碼
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <Windows.h>
#include <stdio.h>

unsigned char decToBcd(WORD dec)   
{
        return ( (dec/10)*16 + dec%10);
}
void main(void)
{

HANDLE hComm;                          // Handle to the Serial port

char   ComPortName[] = "\\\\.\\COM13"; // Name of the Serial port(May Change) to be opened, COM13 是我的PC 上的設置,在你的PC 要相應修改
BOOL   Status;
SYSTEMTIME localDateTime;
int i=0,j=0;

        printf("\n\n +==========================================+");
        printf("\n |  Serial Transmission (Win32 API)         |");
        printf("\n +==========================================+\n");
        /*----------------------------------- Opening the Serial Port --------------------------------------------*/

        hComm = CreateFile( ComPortName,     // Name of the Port to be Opened
                GENERIC_READ | GENERIC_WRITE,   // Read/Write Access
                0,                                 // No Sharing, ports cant be shared
                NULL,                           // No Security
                OPEN_EXISTING,           // Open existing port only
                0,                                 // Non Overlapped I/O
                NULL);                          // Null for Comm Devices

        if (hComm == INVALID_HANDLE_VALUE)
                printf("\n   Error! - Port %s can't be opened", ComPortName);
        else
                printf("\n   Port %s Opened\n ", ComPortName);


        /*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/

        DCB dcbSerialParams = { 0 };    // Initializing DCB structure
        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);

        Status = GetCommState(hComm, &dcbSerialParams);     //retreives  the current settings

        if (Status == FALSE)
                printf("\n   Error! in GetCommState()");

        dcbSerialParams.BaudRate = CBR_9600;      // Setting BaudRate = 9600
        dcbSerialParams.ByteSize = 8;             // Setting ByteSize = 8
        dcbSerialParams.StopBits = 1;                          // Setting StopBits = 1
        dcbSerialParams.Parity   = NOPARITY;      // Setting Parity = None

        Status = SetCommState(hComm, &dcbSerialParams);  //Configuring the port according to settings in DCB

        if (Status == FALSE)
        {
                printf("\n   Error! in Setting DCB Structure");
        }
        else
        {
                printf("\n   Setting DCB Structure Successfull\n");
                printf("\n       BaudRate = %d", dcbSerialParams.BaudRate);
                printf("\n       ByteSize = %d", dcbSerialParams.ByteSize);
                printf("\n       StopBits = %d", dcbSerialParams.StopBits);
                printf("\n       Parity   = %d", dcbSerialParams.Parity);
        }

        /*------------------------------------ Setting Timeouts --------------------------------------------------*/

        COMMTIMEOUTS timeouts = { 0 };

        timeouts.ReadIntervalTimeout         = 50;
        timeouts.ReadTotalTimeoutConstant    = 50;
        timeouts.ReadTotalTimeoutMultiplier  = 10;
        timeouts.WriteTotalTimeoutConstant   = 50;
        timeouts.WriteTotalTimeoutMultiplier = 10;

        if (SetCommTimeouts(hComm, &timeouts) == FALSE)
                printf("\n   Error! in Setting Time Outs\n");
        else
                printf("\n\n   Setting Serial Port Timeouts Successfully\n\n");


        /*----------------------------- Writing a Character to Serial Port----------------------------------------*/
        char   lpBuffer[] = { 0x11, 0x11, 0x11, 0x12, 0x12, 0x06, 0x24,0x0D, 0x0A};

        DWORD  dNoOFBytestoWrite;              // No. of bytes to write into the port
        DWORD  dNoOfBytesWritten = 0;          // No. of bytes written to the port

        dNoOFBytestoWrite = sizeof(lpBuffer); // Calculating the no of bytes to write into the port

        GetLocalTime(&localDateTime);
        lpBuffer[3] = decToBcd(localDateTime.wDay);
        lpBuffer[4] = decToBcd(localDateTime.wMonth);
        lpBuffer[5] = decToBcd(localDateTime.wDayOfWeek);
        lpBuffer[6] = decToBcd(((localDateTime.wYear) % 100));
        lpBuffer[2] = decToBcd(localDateTime.wHour);
        lpBuffer[1] = decToBcd(localDateTime.wMinute);
        lpBuffer[0] = decToBcd(localDateTime.wSecond);

        for (;;)
        {
                Status = WriteFile(hComm,// Handle to the Serialport
                        &lpBuffer[ i],        // Data to be written to the port
                        dNoOFBytestoWrite,   // No. of bytes to write into the port
                        &dNoOfBytesWritten,  // No. of bytes written to the port
                        NULL);

                if (Status == TRUE)
                {
                        i++;
                        if( i > dNoOFBytestoWrite)
                        {
                                printf("%d bytes sent to the port...done!",dNoOFBytestoWrite);
                                break;
                        }
                        j = 0;
                        continue;
                }

                else
                {
                        //printf("\n\n   Error %d in Writing to Serial Port",GetLastError());
                        j++;
                        if( j > 10 ) // 10 以上發(fā)送(超時)錯誤就放棄了。。。
                        {
                                printf("%d times failed to send byte[%d]=%2x... give up and quit!\n",j,i, lpBuffer[ i]);                                break;
                        }
                }

        }

        CloseHandle(hComm);//Closing the Serial Port
        printf("\n ============port %s closed=============\n", ComPortName);
        //_getch();
}

============================================================================

在 Windows 命令窗口下 用 cl 命令編譯-鏈接成 .exe 可執(zhí)行文件. 你的PC 機需要安裝MSVC 編譯系統(tǒng)( 不需要IDE),才能使用cl.exe

* 運行單片機的 UART 數(shù)據(jù)接受等待循環(huán)代碼,同時在PC 端運行上面提到的windows 程序,51端收到數(shù)據(jù)后跳出循環(huán),在LED 數(shù)碼管上顯示和PC 端同步的時間日期即可 。。。。

【圖片視頻】

一圖(姐)百訥, 大家看看圖片和視頻吧 。。。但這個(老古董 ... 還在用 Flash 插件... :))網(wǎng)站好像沒有辦法從我的PC 上傳mp4 視頻... 剛注冊沒有幾天,還不會玩這個網(wǎng)站,多多包涵啊。


okay ?

肯定有不少同學還沒有完全看懂、讀懂,我抽空整理一下單片機一端混亂、隨手涂鴉的原代碼, 加上注釋后給大家抄一抄 .... :)

Happy Hacking

51hei圖片_20240903211531.jpg (312.42 KB, 下載次數(shù): 11)

和 Windows PC 時間同步

和 Windows PC 時間同步

51hei圖片_20240903211630.jpg (389.24 KB, 下載次數(shù): 8)

夾住Vcc1 管腳

夾住Vcc1 管腳

51hei圖片_20240903213021.jpg (427.17 KB, 下載次數(shù): 9)

背面的鋰電池

背面的鋰電池

WeChat_20240903211753.gif (1.07 MB, 下載次數(shù): 9)

動畫-同步

動畫-同步

1.gif (918.78 KB, 下載次數(shù): 10)

動畫-斷電后再上電

動畫-斷電后再上電

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 少妇久久久 | 日韩欧美福利视频 | 在线色网| 国产精品海角社区在线观看 | 九九热这里 | 精品一区二区三区av | 久久网日本| 国产精品视频播放 | 久久久91 | 亚洲专区在线 | 一区二区三区四区视频 | 91精品国产乱码久久久久久久 | 日韩av电影院 | www成人免费视频 | 密桃av| 亚洲网在线 | 欧美国产一区二区三区 | 成人午夜在线观看 | 手机在线不卡av | 午夜欧美 | 国产丝袜一区二区三区免费视频 | 欧美一区二区三区大片 | 成人av高清| 在线播放国产视频 | 国产精品免费大片 | 日韩成人一区 | 99视频在线看 | 中文字幕一区二区三区不卡 | 成人免费视频一区 | 免费一区二区 | 久久国内 | 色吊丝在线 | 欧美在线视频一区二区 | 成人在线中文字幕 | 浴室洗澡偷拍一区二区 | 欧美在线一区二区三区 | 久久尤物免费一区二区三区 | 亚洲欧美日韩高清 | 欧美成人一区二区 | 精品综合网 | 国产人免费人成免费视频 |