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

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

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

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

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
............ 很久很久沒(méi)有玩8位單板機(jī)了 .... N 年以前用匯編語(yǔ)言玩了一陣朋友送的一個(gè)Z80單板機(jī),做了一個(gè)繼電器溫控的方案后,軟硬件一共500出手掉了。 一直到2009年在上海遇到Zilog 公司創(chuàng)始人,Z80設(shè)計(jì)師 Federico Faggin (F.F.) 后,又重新對(duì)單片機(jī)產(chǎn)生了一點(diǎn)興趣。和F.F 一起用餐時(shí),他告訴我,他的z80 已經(jīng)升級(jí)到 ez80, 可以用 C 語(yǔ)言玩...... 真的好玩嗎? 我在Intel 公司玩了n 年的 C 語(yǔ)言,用來(lái)測(cè)試芯片的,現(xiàn)在可以用C 來(lái)玩 ez80? ...  于是不假思索就向F.F.索要開(kāi)發(fā)套件。F.F. 很大方,當(dāng)場(chǎng)送了一套價(jià)值400 元,包裝精美的套件,看來(lái)他也是有備而來(lái)啊 ... :) ....  回家后搗鼓了一陣,搞了一個(gè)小玩具:躲在蚊帳里用紅外遙控器開(kāi)關(guān)外面的電燈 ... 后來(lái)幾次搬家,把那個(gè)小玩具弄丟了。

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

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


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

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

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

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

void ds1302_init(void)
{
        u8 i=0;
        ds1302_write_byte(0x8E,0X00);
        ds1302_write_byte(0x90,0xA5); // 0xA5 = 1010- 0101, 表示內(nèi)部充電線路選用 一個(gè)二極管和一個(gè)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-串口通信實(shí)驗(yàn)】當(dāng)中的字符接受代碼,使得單片機(jī)能夠從 Windows PC 主機(jī)收取完整的時(shí)間-日期信息:

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


* 在 PC Windows 上寫(xiě)一個(gè)小程序 ( 偷懶的可以用 教程里推薦的串口通訊程序 把時(shí)間-日期數(shù)據(jù) 手工發(fā)給單片機(jī),但無(wú)法和PC 上的時(shí)間準(zhǔn)確同步 )
======================================================================================
//  版權(quán)說(shuō)明: 程序的框架源自 Rahul.S  , 我填寫(xiě)了 main 里面 和 51單片機(jī) 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 上的設(shè)置,在你的PC 要相應(yīng)修改
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ā)送(超時(shí))錯(cuò)誤就放棄了。。。
                        {
                                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 機(jī)需要安裝MSVC 編譯系統(tǒng)( 不需要IDE),才能使用cl.exe

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

【圖片視頻】

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


okay ?

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

Happy Hacking

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

和 Windows PC 時(shí)間同步

和 Windows PC 時(shí)間同步

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)

動(dòng)畫(huà)-同步

動(dòng)畫(huà)-同步

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

動(dòng)畫(huà)-斷電后再上電

動(dòng)畫(huà)-斷電后再上電

評(píng)分

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

查看全部評(píng)分

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

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 手机av在线 | 第四色播日韩第一页 | 国产成人免费在线观看 | 男女羞羞视频网站 | 九九久久久 | 九九久久精品 | 久久久久久综合 | 黄色骚片| 国产精品亚洲综合 | 亚洲性免费| 亚洲高清在线视频 | 黑人巨大精品欧美一区二区免费 | 91在线网站 | 午夜视频一区二区三区 | 国产精品夜间视频香蕉 | cao在线| jizz中国日本 | 婷婷激情综合 | 在线日韩av电影 | 在线观看成人小视频 | 欧美久久国产精品 | 最近日韩中文字幕 | 欧美电影一区 | 97国产精品视频人人做人人爱 | 中文字幕成人av | 9久9久| 国产色黄| 狠狠干天天干 | 日韩精品在线一区 | 国产精品v | 中文字幕一区在线观看视频 | 欧美不卡一区二区三区 | 成人午夜av | av手机在线| 欧美精品一区三区 | 日本五月婷婷 | 久久久久久99 | 亚洲国产欧美一区 | 激情五月婷婷在线 | 色免费在线视频 | 免费黄色a视频 |