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

標題: 為PZ-51單板機上的實時時鐘加裝后備紐扣電池,和Windows時間同步 [打印本頁]

作者: samuelni    時間: 2024-9-3 22:41
標題: 為PZ-51單板機上的實時時鐘加裝后備紐扣電池,和Windows時間同步
............ 很久很久沒有玩8位單板機了 .... N 年以前用匯編語言玩了一陣朋友送的一個Z80單板機,做了一個繼電器溫控的方案后,軟硬件一共500出手掉了。 一直到2009年在上海遇到Zilog 公司創始人,Z80設計師 Federico Faggin (F.F.) 后,又重新對單片機產生了一點興趣。和F.F 一起用餐時,他告訴我,他的z80 已經升級到 ez80, 可以用 C 語言玩...... 真的好玩嗎? 我在Intel 公司玩了n 年的 C 語言,用來測試芯片的,現在可以用C 來玩 ez80? ...  于是不假思索就向F.F.索要開發套件。F.F. 很大方,當場送了一套價值400 元,包裝精美的套件,看來他也是有備而來啊 ... :) ....  回家后搗鼓了一陣,搞了一個小玩具:躲在蚊帳里用紅外遙控器開關外面的電燈 ... 后來幾次搬家,把那個小玩具弄丟了。

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

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


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

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

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

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

void ds1302_init(void)
{
        u8 i=0;
        ds1302_write_byte(0x8E,0X00);
        ds1302_write_byte(0x90,0xA5); // 0xA5 = 1010- 0101, 表示內部充電線路選用 一個二極管和一個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 字節時間-日期數據(7 Byte RTC 寄存器數據 + 2 Byte 通信結束標志)
  {
    ds1302_write_byte(0x8E,0X00);        // 準備更新 ds1302 RTC 當中的 時間-日期數據
    for(i=0;i<7;i++)
    {
      ds1302_write_byte(gWRITE_RTC_ADDR[ i],UART_RX_BUF[ i]);  // 逐字節更新 ....      
    }
   ds1302_write_byte(0x8E,0X80);  //禁止寫RTC,主要是防止管腳上偶發信號【噪音,毛刺】意外破壞RTC 里面的內容
   beep_alarm(50,15);         // 給一個完成任務的蜂鳴器提示。。。 可有可無。。。。
   key_value = 13;// effectively jump to key-13 process,這個key_value 變量的來源是有故事的,以后再講吧。
   UART_RX_STA=0;////清除標記,以便下次接受新的 日期-時間更新數據
}


* 在 PC Windows 上寫一個小程序 ( 偷懶的可以用 教程里推薦的串口通訊程序 把時間-日期數據 手工發給單片機,但無法和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 以上發送(超時)錯誤就放棄了。。。
                        {
                                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 可執行文件. 你的PC 機需要安裝MSVC 編譯系統( 不需要IDE),才能使用cl.exe

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

【圖片視頻】

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


okay ?

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

Happy Hacking

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

和 Windows PC 時間同步

和 Windows PC 時間同步

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

夾住Vcc1 管腳

夾住Vcc1 管腳

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

背面的鋰電池

背面的鋰電池

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

動畫-同步

動畫-同步

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

動畫-斷電后再上電

動畫-斷電后再上電





歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 天天草天天爱 | 日韩精品免费在线观看 | 久久久久久网站 | 一级毛片大全免费播放 | 婷婷午夜天 | 精品乱人伦一区二区三区 | 日日夜夜免费精品 | 日韩成人免费视频 | 欧美日韩一区二区三区四区 | 国产美女免费视频 | 日韩精品一区二区三区在线播放 | 日韩在线xx | 欧美成人手机视频 | 亚洲专区在线 | 国产偷录视频叫床高潮对白 | 91精品国产91久久久久福利 | 黄色免费在线观看 | 97av在线| 国产精品亚洲综合 | 一级黄色毛片免费 | 久久久久无码国产精品一区 | 久久亚洲国产 | 黄色高清视频 | 国产999精品久久久久久 | 人人九九| 成人自拍av | 亚洲视频在线看 | 成人二区| 欧美专区在线视频 | 日本视频免费 | 日韩一区二区福利视频 | 国产午夜精品理论片a大结局 | 日本精品一区二区三区视频 | 免费观看一级毛片 | caoporn国产精品免费公开 | 亚洲欧美自拍偷拍视频 | 午夜影院在线视频 | 亚洲精品一区二区三区在线 | 精品在线免费观看视频 | 欧美三级三级三级爽爽爽 | 国产成人精品一区二区三区在线观看 |