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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索

PIC16F873A單片機eeprom 24C02-24C64數據抄寫程序求助

查看數: 2710 | 評論數: 7 | 收藏 0
關燈 | 提示:支持鍵盤翻頁<-左 右->
    組圖打開中,請稍候......
發布時間: 2021-9-6 21:05

正文摘要:

   網上找的,PIC16F873A單片機eeprom 24C02-24C64數據抄寫程序,用MPLAB IDE編譯,報告一大堆錯誤,求助大蝦幫忙看看這個匯編程序到底錯在哪里?程序如下: ;****************I2C總線EPROM數據抄寫程序** ...

回復

ID:155507 發表于 2021-9-8 18:58
我給你來個 C 程序試試



  1. #include <pic.h>           //調用PIC16F87XA單片機的頭文件

  2. //根據選項,配置字應該如下所示:
  3. //__CONFIG(HS&WRTEN&WDTDIS&BOREN&PWRTDIS&UNPROTECT&DUNPROT&DEBUGDIS&LVPDIS);

  4. //實際使用中,這樣太麻煩,對于默認選項,我們將其忽略掉:
  5. __CONFIG(HS&WDTDIS&LVPDIS);

  6. //---------------------------------------
  7. //1602液晶相關I/O設置
  8. #define E   RB3            //1602液晶的E腳接在RB3口上
  9. #define RW  RB4            //1602液晶的RW腳接在RB4口上
  10. #define RS  RB5            //1602液晶的RS腳接在RB5口上
  11. //---------------------------------------

  12. //---------------------------------------
  13. //軟件模擬IIC相關I/O設置
  14. #define SCL   RC3      //AT24C02的 SCL 引腳接于單片機的RC3引腳上
  15. #define SDA   RC4      //AT24C02的 SDA 引腳接于單片機的RC4引腳上
  16. //---------------------------------------

  17. //---------------------------------------
  18. //1602液晶寄存器設置
  19. unsigned char DISbuf;     //設置8位的unsigend char型寄存器用來暫存1602要顯示的內容
  20. //---------------------------------------



  21. void Delay(void)
  22. {
  23.      unsigned char k;      //定義一個8位寄存器用來做延時用
  24.      for(k=0;k<50;k++);    //延時約50微秒
  25. }



  26. void IICstart(void)
  27. {
  28.      SDA=1;                //先將SDA=1,以準備在SCL=1時,將SDA=0
  29.      SCL=1;                //時鐘總線拉高
  30.      Delay();              //調用延時函數,略作延時
  31.      SDA=0;                //SCL=1時,將SDA拉低即產生啟動信號
  32.      Delay();              //調用延時函數,略作延時
  33.      SCL=0;                //將SCL=0,完成啟動信號操作
  34.      Delay();              //調用延時函數,略作延時
  35. }



  36. void IICstop(void)
  37. {
  38.      SDA=0;                //先將SDA=0,以準備在SCL=1時,將SDA=1
  39.      SCL=1;                //時鐘總線拉高
  40.      Delay();              //調用延時函數,略作延時
  41.      SDA=1;                //SCL=1時,將SDA拉高即產生停止信號
  42.      Delay();              //調用延時函數,略作延時
  43.      SCL=0;                //將SCL=0,完成啟動信號操作
  44.      Delay();              //調用延時函數,略作延時
  45. }



  46. void Write1Byte(unsigned char Buf1)
  47. {
  48.      unsigned char k;      //1個字節要分8次寫入,需要定義一個寄存器用來計數
  49.      for(k=0;k<8;k++)      //做一個8次的循環,每次寫入1位,需要寫8次
  50.      {
  51.          if(Buf1&0x80)     //從最高位開始寫
  52.          {
  53.              SDA=1;        //如果欲寫入數據為1,就將數據線置1
  54.          }
  55.          else
  56.          {
  57.              SDA=0;        //如果欲寫入數據為0,就將數據線寫0
  58.          }
  59.          asm("NOP");       //略做延時
  60.          asm("NOP");       //略做延時
  61.          SCL=1;            //時鐘線做一個上升沿,將一位數據寫入
  62.          Buf1=Buf1<<1;     //數據左移一位,將下次要寫入的位數據移到最高位
  63.          asm("NOP");       //略做延時
  64.          SCL=0;            //將SCL=0,以準備通過上升沿將數據寫入
  65.          asm("NOP");       //略做延時
  66.      }
  67.      TRISC4=1;             //將RC4(SDA)設置為輸入狀態
  68.      asm("NOP");           //略做延時
  69.      SCL=1;                //將SCL=1,做個上升沿準備讀應答信號
  70.      asm("NOP");           //略做延時
  71.      asm("NOP");           //略做延時
  72.      SCL=0;                //將SCL=0,結束應答信號讀操作
  73.      TRISC4=0;             //將RC4(SDA)恢復為輸出狀態
  74. }



  75. unsigned char Read1Byte(void)
  76. {
  77.      unsigned char k;      //1個字節要分8次讀出,需要定義一個寄存器用來計數
  78.      unsigned char t=0;    //定義一個寄存器用保存讀出數據
  79.      TRISC4=1;             //將RC4(SDA)設置為輸入狀態
  80.      for(k=0;k<8;k++)      //做一個8次的循環,每次讀入1位,需要讀8次
  81.      {
  82.          t=t<<1;           //數據左移一位,空出最低位以準備保存讀入的一位數據
  83.          SCL=1;            //將SCL=1,做個上升沿準備讀一位數據
  84.          asm("NOP");       //略做延時
  85.          asm("NOP");       //略做延時
  86.          if(SDA==1)        //讀一位數據,并判斷
  87.          {
  88.              t=t|0x01;     //如果讀入數據為1,就將接收緩沖區最低一位置1
  89.          }
  90.          else
  91.          {
  92.              t=t&0xfe;     //如果讀入數據為0,就將接收緩沖區最低一位寫0
  93.          }
  94.          SCL=0;            //SCL恢復為0,結束一位數據讀操作
  95.          asm("NOP");       //略做延時
  96.          asm("NOP");       //略做延時
  97.      }
  98.      TRISC4=0;             //將RC4(SDA)恢復為輸出狀態
  99.      return t;             //將讀入的一個字節返回
  100. }



  101. void WriteAT24C02(unsigned char Address,unsigned char Databuf)
  102. {                          //直接調用本函數即可對AT24C02的Address地址寫Databuf
  103.     IICstart();            //IIC啟動信號

  104.     Write1Byte(0xA0);      //發送AT24C02的器件地址和寫信號

  105.     Write1Byte(Address);   //發送地址

  106.     Write1Byte(Databuf);   //發送數據

  107.     IICstop();             //產生IIC停止信號
  108. }



  109. unsigned ReadAT24C02(unsigned char Address)
  110. {                          //直接調用本函數即可從AT24C02的Address地址讀出數據返回
  111.     unsigned char buf;     //定義一個寄存器用來暫存讀出的數據
  112.     IICstart();            //IIC啟動信號

  113.     Write1Byte(0xA0);      //發送AT24C02的器件地址和寫信號

  114.     Write1Byte(Address);   //發送地址

  115.     IICstart();            //IIC啟動信號

  116.     Write1Byte(0xA1);      //發送AT24C02的器件地址和讀信號

  117.     buf=Read1Byte();//讀一個字節數據

  118.     IICstop();             //產生IIC停止信號

  119.     return(buf);           //將讀出數據返回
  120. }



  121. void Delay1602(unsigned int t)
  122. {
  123.      unsigned int k;      //定義一個16位寄存器用來做延時用
  124.      for(k=0;k<t;k++);    //延時
  125. }



  126. void LCD1602_busy(void)
  127. {
  128.      TRISD7=1;            //將RD7口設置為輸入口,為讀做準備
  129.      RS=0;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入
  130.      RW=1;                //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入
  131.      E=1;                 //RS=0、RW=1、E=1時,忙信號輸出到DB7,由RD7讀入
  132.      while(RD7==1);       //由RD7讀入1,表示1602液晶忙,需要等待
  133.      E=0;                 //讀完以后,恢復E的電平
  134.      TRISD7=0;            //將RD7口設置為輸出口
  135. }



  136. void LCD1602_Write_com(unsigned char combuf)
  137. {
  138.      RS=0;                //選擇指令寄存器
  139.      RW=0;                //選擇寫狀態
  140.      PORTD=combuf;        //將命令字通過RD口送至DB
  141.      E=1;                 //E高電平將命令字寫入1602液晶
  142.      asm("NOP");          //添加一個空操作,使高電平至少維持1us
  143.      E=0;                 //寫完以后,恢復E的電平
  144. }



  145. void LCD1602_Write_com_busy(unsigned char combuf)
  146. {
  147.      LCD1602_busy();            //調用忙檢測函數
  148.      LCD1602_Write_com(combuf); //調用忙檢測函數
  149. }



  150. void LCD1602_Write_data_busy(unsigned char databuf)
  151. {
  152.      LCD1602_busy();      //調用忙檢測函數
  153.      RS=1;                //選擇數據寄存器
  154.      RW=0;                //選擇寫狀態
  155.      PORTD=databuf;        //將命令字通過RD口送至DB
  156.      E=1;                 //E高電平將命令字寫入1602液晶
  157.      asm("NOP");          //添加一個空操作,使高電平至少維持1us
  158.      E=0;                 //寫完以后,恢復E的電平
  159. }



  160. void LCD1602_Write_address(unsigned char x,unsigned char y)
  161. {
  162.      x&=0x0f;             //列地址限制在0-15間
  163.      y&=0x01;             //行地址限制在0-1間
  164.      if(y==0)             //如果是第一行
  165.          LCD1602_Write_com_busy(x|0x80);        //將列地址寫入
  166.      else                 //如果是第二行
  167.          LCD1602_Write_com_busy((x+0x40)|0x80); //將列地址寫入
  168. }



  169. void LCD1602_init(void)
  170. {
  171.      Delay1602(1500);          //調用延時函數
  172.      LCD1602_Write_com(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  173.      Delay1602(500);           //調用延時函數
  174.      LCD1602_Write_com(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  175.      Delay1602(500);           //調用延時函數
  176.      LCD1602_Write_com(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  177.      LCD1602_Write_com_busy(0x38);  //8位數據總線,兩行顯示模式,5*7點陣顯示
  178.      LCD1602_Write_com_busy(0x08);  //顯示功能關,無光標
  179.      LCD1602_Write_com_busy(0x01);  //清屏
  180.      LCD1602_Write_com_busy(0x06);  //寫入新的數據后,光標右移,顯示屏不移動
  181.      LCD1602_Write_com_busy(0x0C);  //顯示功能開,無光標
  182. }



  183. void LCD1602_Disp(unsigned char x,unsigned char y,unsigned char buf)
  184. {
  185.      LCD1602_Write_address(x,y);    //先將地址信息寫入
  186.      LCD1602_Write_data_busy(buf);  //再寫入要顯示的數據
  187. }



  188. void main(void)            //主函數,單片機開機后就是從這個函數開始運行
  189. {

  190.     TRISB=0B11000111;      //初始化RB7-RB0的輸入輸出方向
  191.     TRISC=0B11100111;      //初始化RC7-RC0的輸入輸出方向
  192.     TRISD=0B00000000;      //初始化RD7-RD0的輸入輸出方向
  193.     PORTB=0B00000000;      //初始化RB7-RB0的數值
  194.     PORTC=0B00000000;      //初始化RC7-RC0的數值
  195.     PORTD=0B00000000;      //初始化RD7-RD0的數值

  196.     LCD1602_init();        //調用1602液晶初始化函數

  197.         DISbuf=ReadAT24C02(0x18);   //從AT24C02中地址0X18讀取數據
  198.           DISbuf++;                         //讀出數據+1
  199.           WriteAT24C02(0x18,DISbuf);  //將+1后的數據保存到0X18中

  200.         LCD1602_Disp(0,0,'-');   //-
  201.         LCD1602_Disp(1,0,'-');   //-
  202.         LCD1602_Disp(2,0,'A');   //A
  203.         LCD1602_Disp(3,0,'T');   //T
  204.         LCD1602_Disp(4,0,'2');   //2
  205.         LCD1602_Disp(5,0,'4');   //4   
  206.         LCD1602_Disp(6,0,'C');   //C         
  207.         LCD1602_Disp(7,0,'0');   //0
  208.         LCD1602_Disp(8,0,'2');   //2

  209.         LCD1602_Disp(10,0,'T');  //T
  210.         LCD1602_Disp(11,0,'E');  //E
  211.         LCD1602_Disp(12,0,'S');  //S
  212.         LCD1602_Disp(13,0,'T');  //T
  213.         LCD1602_Disp(14,0,'-');   //-
  214.         LCD1602_Disp(15,0,'-');   //-

  215.         LCD1602_Disp(0,1,'B');   //B
  216.         LCD1602_Disp(1,1,'o');   //o
  217.         LCD1602_Disp(2,1,'o');   //o
  218.         LCD1602_Disp(3,1,'t');   //t
  219.    
  220.         LCD1602_Disp(5,1,'t');   //t         
  221.         LCD1602_Disp(6,1,'i');   //i
  222.         LCD1602_Disp(7,1,'m');   //m
  223.         LCD1602_Disp(8,1,'e');   //e
  224.         LCD1602_Disp(9,1,'s');   //s
  225.         LCD1602_Disp(10,1,':');   //:
  226.   
  227.         LCD1602_Disp(12,1,DISbuf/100+0x30);            //顯示百位
  228.         LCD1602_Disp(13,1,(DISbuf%100)/10+0x30); //顯示十位
  229.         LCD1602_Disp(14,1,DISbuf%10+0x30);            //顯示個位
  230.     while(1)               //死循環,單片機初始化后,將一直運行這個死循環
  231.     {

  232.     }
  233. }
復制代碼
ID:624769 發表于 2021-9-8 16:36
shumivan 發表于 2021-9-8 16:03
怎么還在用匯編,我已經全忘完了,只會C了

要提高編程能力,匯編是必須要學會的, 可以平時不用, 但必須要會, debug的時候,有問題,看一眼編譯出來的匯編,立馬就能明白是什么原因造成的,不會的話,會走很多彎路, 然后,C語言里不好控制的時序問題,進到匯編跟砍瓜切菜一樣。
程序主體都用C, 有些地方(尤其是涉及底層操作的地方)用點匯編,我覺得還是比較有必要的。
ID:81196 發表于 2021-9-8 16:03
怎么還在用匯編,我已經全忘完了,只會C了
ID:655665 發表于 2021-9-7 22:21
Y_G_G 發表于 2021-9-6 22:29
學PIC的本來就少,你還是用匯編的,而且一個漢字注釋都沒有,你覺得別人能看明白?
這是我以前寫的24C02的驗證 ...

謝謝您的回復,受教了。最近在寫E2PROM復制器的程序,就是將兩個24C32,將其中一個里面的數據,通過單片機復制到另一個里面去,可總是寫不好,思路一直混亂。請大神給指點個好的思路,按您的思路,我在重新寫程序。
ID:96682 發表于 2021-9-6 22:32
代碼不全吧
ID:401564 發表于 2021-9-6 22:29
學PIC的本來就少,你還是用匯編的,而且一個漢字注釋都沒有,你覺得別人能看明白?
這是我以前寫的24C02的驗證程序,已經在開發板上實際驗證過的,你對比一下吧
我已經好久沒有用PIC匯編了,指令都快忘記完了

    #include <p16f877a.inc>        ;包含了PIC16F877A的寄存器聲稱文件
    __CONFIG _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _BOREN_ON & _LVP_OFF & _CPD_OFF & _WRT_OFF & _CP_OFF;配置設置生成的代碼

    CBLOCK  020H                ;定義連續變量
    COUNT                        ;計數用的
    DEL1                        ;用在延時子程序中
    DEL2                        ;用在延時子程序中
    DEL3                        ;
    DISP_ADDR                        ;顯示地址用寄存器
    DISP_DATA                        ;顯示數據用寄存器
    LED_1                        ;七段碼的個位
    LED_10                        ;七段碼的十位
    LED_100                        ;七段碼的百位
    DIV_DATA                        ;除法用寄存器
    DATA_BUF                        ;數據寫入和讀出用的緩沖器
    SESHI                        ;測試用寄存器
    ENDC                        ;結束定義
#define    S1        PORTB,0                ;按置S1
#define    S2        PORTB,1                ;按置S2
#define    S3        PORTB,2                ;按置S3
#define           COM0        PORTD,0                ;
#define           COM1        PORTD,1                ;
#define           COM2        PORTD,2                ;
#define           COM3        PORTD,3                ;定義幾個顯示的RA端口
#define            CY        STATUS,0        ;C為標志位,減法有借位=0,無借位=1
#define            SCL        PORTD,4                ;時鐘信號線
#define            SDA        PORTD,7                ;數據信號線
#define            SDA_C   TRISD,7        ;數據方向控制寄存器   
          
        ORG        00H                ;
        NOP                        ;這條指令是仿真要有的
        GOTO        MAIN                ;跳過中斷子程序       
        ORG        020H                ;
MAIN        BSF        STATUS,RP0        ;RP0=1,RP1=0,指令選擇BANK1
        BCF        STATUS,RP1        ;
;===============================================================================       
;以下是針對BANK1的操作==========================================================
        MOVLW   0FFH                ;
        MOVWF        TRISB                ;PORTB        作為輸入
        BCF        OPTION_REG,7        ;啟用RB的上拉電阻
        BCF        INTCON,3        ;
        MOVLW        00H                ;
        MOVWF        TRISC                ;PORTC        作為輸出-數據
        MOVWF        TRISD                ;PORTD        作為輸出-位選
        CLRF        TRISE                ;RD工作于正常的IO模式
;以下是針對BANK0的操作==========================================================
        BCF        STATUS,RP0        ;選擇BANK0
        CLRF        PORTC                ;
        CLRF        PORTD
;===============================================================================
        MOVLW        D'123'                ;默認數據是000
        MOVWF        DISP_DATA
        MOVLW        D'8'                ;默認地址是0
        MOVWF        DISP_ADDR
;===============================================================================       
LOOP        BTFSS        S1        ;按鍵1是1就跳過下一條指令
        CALL        S1_DISP        ;調用S1處理程序
        BTFSS        S2        ;S2沒有按下就跳過下一條指令
        CALL        S2_DISP        ;按下就調用S2處理子程序
        BTFSS        S3        ;S3沒有按下就跳過下一條指令
        CALL        S3_DISP        ;按下就中用S3處理子程序
        CALL        DISPLAY        ;顯示
        GOTO        LOOP        ;主程序在這循環
;===============================================================================       
READ_DATA;讀出一個字節----------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;            1
        BCF        SDA            ;SDA1>>0,起始信號
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A0H            ;0A0H為寫命令,完整的輸入8個位的地址
        CALL        WRITE_BYTE  ;寫入"寫"模式指令
        MOVFW        DISP_ADDR   ;寫入地址
        CALL        WRITE_BYTE  ;
        ;-----------------------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;               
        BCF        SDA            ;SDA1>>0,起始信號
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A1H            ;0A1H為讀命令,完整的輸入8個位的地址
        CALL        WRITE_BYTE  ;寫入"寫"模式指令
        CALL        READ_BYTE   ;讀出一個字節
        MOVWF        DISP_DATA
        ;-----------------------------------------------------------------------
        BCF        SCL            ;
        BCF        SDA            ;SDA0
        BSF        SCL            ;
        BSF        SDA            ;SDA0>>1,停止信號
        BCF        SCL            ;
        BCF        SDA
        RETURN
;===============================================================================
WRITE_DATA;寫入一個字節---------------------------------------------------------
        BCF        SCL            ;
        BSF        SDA            ;SDA1
        BSF        SCL            ;            1
        BCF        SDA            ;SDA1>>0,起始信號
        BCF        SCL            ;
        ;-----------------------------------------------------------------------
        MOVLW        0A0H            ;0A0H為寫命令,完整的輸入8個位的地址
        CALL        WRITE_BYTE  ;寫入"寫"模式指令
        MOVFW        DISP_ADDR   ;寫入地址
        CALL        WRITE_BYTE  ;
        MOVFW        DISP_DATA
        CALL        WRITE_BYTE
;-----------------------------------------------------------------------
        BCF        SCL            ;
        BCF        SDA            ;SDA0
        BSF        SCL            ;
        BSF        SDA            ;SDA0>>1,停止信號
        BCF        SCL            ;
        BCF        SDA
        RETURN
;===============================================================================
READ_BYTE;讀一個字節處理程序***************************************************
            BSF                STATUS,RP0  ;選擇BANK1
            BSF                SDA_C            ;SDA作為輸入
            BCF                STATUS,RP0  ;選擇BANK0
            MOVLW        D'8'
            MOVWF        COUNT            ;要讀出的字節是8
            BCF                SCL            ;時鐘0
R_B_LOOP    BCF                CY            ;
            BSF                SCL            ;時鐘上升沿
            BTFSC        SDA            ;是0就跳過下一條指令
            BSF                CY            ;是1,置位緩沖器的0位
            RLF                DATA_BUF,F  ;左移一次,從最高位開始讀出
            BCF                SCL            ;時鐘下降
            DECFSZ        COUNT,F            ;檢測是否完成了8個字節
            GOTO        R_B_LOOP    ;
            MOVFW        DATA_BUF    ;讀取到的數據保存到W
            BSF                STATUS,RP0  ;選擇BANK1
            BCF                SDA_C            ;SDA作為輸出
            BSF                SDA            ;
            BSF                SCL            ;
            BCF                SCL            ;
            BCF                SDA            ;
            BCF                STATUS,RP0  ;選擇BANK0
RETURN
;===============================================================================
WRITE_BYTE;寫入一個字節*********************************************************
            BSF                STATUS,RP0  ;選擇BANK1
            BCF                SDA_C            ;SDA作為輸出
            BCF                STATUS,RP0  ;選擇BANK0
            MOVWF        DATA_BUF    ;
            MOVLW        D'8'            ;
            MOVWF        COUNT            ;
            BCF                SCL            ;時鐘0
W_B_LOOP    BCF                SDA            ;清除輸出線
            BTFSC        DATA_BUF,7  ;最高位如果是0就跳過下一條指令
            BSF                SDA            ;最高位是1,置位D_I
            CALL        DELAY_5MS   ;延時5mS
            BSF                SCL            ;時鐘上升
            CALL        DELAY_5MS
            BCF                SCL            ;時鐘下降
            CALL        DELAY_5MS
            RLF                DATA_BUF,F  ;左移一次,
            DECFSZ        COUNT,F            ;檢測是否傳送完成8個字節
            GOTO        W_B_LOOP    ;沒有,跳去循環
            ;應答---------------------------------------------------------------
            BSF                SDA
            BSF                STATUS,RP0  ;選擇BANK1
            BSF                SDA_C            ;SDA作為輸入
            BCF                STATUS,RP0  ;選擇BANK0
            BSF                SCL            ;
            CALL        DELAY_5MS   ;延時5mS
            BTFSC        SDA            ;SDA為0就跳過下一條指令
            GOTO        $-1            ;SDA為1,跳動循環
            BSF                STATUS,RP0  ;選擇BANK1
            BCF                SDA_C            ;SDA作為輸出
            BCF                STATUS,RP0  ;選擇BANK0
            BCF                SCL            ;
            BCF                SDA
RETURN
;===============================================================================
;按一下,數據顯示就加1               
S1_DISP;S1處理程序**************************************************************
            BTFSS        S1
            GOTO        $-1
            INCF        DISP_DATA,F ;數據加1,保存到F
            CALL        WRITE_DATA  ;寫入數據
            CALL        DELAY_5MS
            CALL        READ_DATA   ;再讀出數據
RETURN
;===============================================================================       
S2_DISP;S2處理程序**************************************************************
            BTFSS        S2
            GOTO        $-1
            DECF        DISP_DATA,F ;數據減1,保存到F
            CALL        WRITE_DATA  ;寫入數據
            CALL        DELAY_5MS
            CALL        READ_DATA   ;再讀出數據
RETURN
;===============================================================================
;按一下,地址就加1,最大顯示到9   
S3_DISP        ;S2處理程序*************************************************************
            BTFSS        S3
            GOTO        $-1
            INCF        DISP_ADDR,F        ;地址的值加1
            MOVLW        D'10'                ;10傳送到W
            SUBWF        DISP_ADDR,W        ;地址-W,結果保存到W
            BTFSC        CY                ;c進位為1,地址的值就是大于等于9了
            CLRF        DISP_ADDR        ;地址清零
            CALL        READ_DATA        ;再讀出數據
RETURN
;===============================================================================
;顯示程序***********************************************************************       
DISPLAY            BCF                STATUS,RP0  ;選擇BANK0
            CLRF        LED_1
            CLRF        LED_10
            CLRF        LED_100
;除法部分-----------------------------------------------------------------------   
            MOVFW        DISP_DATA   ;送顯示數據到W
DIV_100            MOVWF        DIV_DATA    ;W的值保存到寄存器
            MOVLW        D'100'            ;W等于100
            SUBWF        DIV_DATA,W  ;數據減去100,結果保存在W
            BTFSS        STATUS,C    ;C是1就跳過下一條指令,C=1,F就是大,還可以再減法
            GOTO        DIV_10            ;C=0,F已經小于100,跳轉到減10
            INCF        LED_100,F   ;F大,百位加1
            GOTO        DIV_100            ;再去減一次
;-------------------------------------------------------------------------------            
DIV_10            MOVLW        D'10'            ;W等于10
            SUBWF        DIV_DATA,W  ;DIV_DATRA-10=
            BTFSS        STATUS,C    ;C=1,DIV_DATA就比W大
            GOTO        DIV_1            ;
            INCF        LED_10,F    ;
            MOVWF        DIV_DATA    ;W數據保存到寄存器
            GOTO        DIV_10            ;
;-------------------------------------------------------------------------------            
DIV_1            MOVFW        DIV_DATA
            MOVWF        LED_1
;顯示部分-----------------------------------------------------------------------
            MOVFW        LED_1            ;數據送到W
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;W送到端口
            BCF                COM0            ;低電平,亮燈
            CALL        DELAY_5MS   ;延時5mS
            BSF                COM0            ;高電平,關燈
        ;-----------------------------------------------------------------------
            MOVFW        LED_10            ;
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM1            ;
            CALL        DELAY_5MS   ;
            BSF                COM1            ;
        ;-----------------------------------------------------------------------
            MOVFW        LED_100            ;
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM2            ;
            CALL        DELAY_5MS   ;
            BSF                COM2            ;
        ;-----------------------------------------------------------------------
            MOVFW        DISP_ADDR   ;顯示地址
            CALL        TAB_LED            ;查表
            MOVWF        PORTC            ;
            BCF                COM3            ;
            CALL        DELAY_5MS   ;
            BSF                COM3            ;
        ;-----------------------------------------------------------------------       
RETURN                                    ;
;===============================================================================
;5mS延時程序********************************************************************
DELAY_5MS   MOVLW        3H
            MOVWF        DEL3
            MOVLW        D'2'            ;
            MOVWF        DEL1            ;
LOOP_5MS1   MOVLW        D'1'            ;
            MOVWF        DEL2            ;
LOOP_5MS2   DECFSZ        DEL2,F            ;
            GOTO        LOOP_5MS2   ;100x2=200uS
            DECFSZ        DEL1,F            ;
            GOTO        LOOP_5MS1   ;
            DECFSZ        DEL3
            GOTO        LOOP_5MS1   ;       
RETURN                                    ;             
;===============================================================================
;BCD碼的表**********************************************************************
TAB_LED            
            ADDWF        PCL,F        ;把W的內容疊加到PCL程序計數器上
            RETLW        0FCH        ;0
            RETLW        060H        ;1
            RETLW        0DAH        ;2
            RETLW        0F2H        ;3
            RETLW        066H        ;4
            RETLW        0B6H        ;5
            RETLW        0BEH        ;6
            RETLW        0E0H        ;7
            RETLW        0FEH        ;8
            RETLW        0F6H        ;9
            END

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品久久久久久吹潮 | 中国美女av| 夜夜精品浪潮av一区二区三区 | 久久手机视频 | 久久伊人精品一区二区三区 | 黄网免费看 | 一级做a爰片久久毛片免费看 | 在线免费观看黄a | 久色| 成人国产精品久久久 | 国产精品久久久久久久免费观看 | 亚洲一卡二卡 | 久久婷婷色 | 99re在线播放 | 国产精品一区二区福利视频 | 久久a久久 | 日本特黄a级高清免费大片 国产精品久久性 | 久久亚| 欧美日韩在线视频一区二区 | 日日草夜夜草 | 欧美日韩午夜精品 | 欧美国产日韩精品 | 欧美精品一二区 | 在线a视频网站 | 久久久久成人精品亚洲国产 | 日韩电影中文字幕 | 成人免费一区二区三区视频网站 | 91久久精品一区二区三区 | 久久久www成人免费无遮挡大片 | 国产成人午夜精品影院游乐网 | 欧美一级二级在线观看 | 亚洲中午字幕 | 99精品视频在线观看免费播放 | 欧美αv | 日韩精品在线免费观看视频 | 婷婷丁香在线视频 | 国产日产久久高清欧美一区 | 黄色片在线网站 | 91一区二区三区 | 亚洲在线一区 | 在线看黄免费 |