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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2399|回復: 4
打印 上一主題 下一主題
收起左側

關于單片機UART和IIC EEPROM和UART的應用,有一些疑惑,請各位朋友幫忙指點一下

[復制鏈接]
跳轉到指定樓層
樓主
ID:415088 發表于 2020-5-28 17:13 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
80黑幣
用串口調試助手,將數據通過UART下發到單片機當中, 并且存儲到EEPROM中, 然后將電源關掉, 重新上電讀取EEPROM的數據并數碼管上顯示出來,但是我現在數據發送單片機也接收了,就是無法存儲到EEPROM中,望各位朋友幫忙指點一下,謝謝!

以下是單片機代碼:

----------------------------------------------------------
  1. #include <reg52.h>
  2. #include <intrins.h>

  3. #define I2CDelay() {_nop_();_nop_();_nop_();_nop_();}
  4. sbit I2C_SCL = P0^6;
  5. sbit I2C_SDA = P0^7;

  6. unsigned char ucDataOneTab[10] = {0x3f,0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f,0x6f};
  7. unsigned char ucDataTwoTab[8] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F};
  8. unsigned char disbuf[8] = {0x3f,0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07};

  9. sbit LED_SMG_RCK = P1^0;
  10. sbit LED_SMG_SCK = P1^1;
  11. sbit LED_SMG_DATA = P1^4;

  12. unsigned char RxdByte;

  13. //數碼管顯示函數
  14. void Send_data_smg(unsigned int uiDataOne,unsigned int uiDataTwo)
  15. {
  16.         unsigned char i;
  17.         
  18.         LED_SMG_RCK = 0;
  19.         for(i=0; i<8; i++)
  20.         {
  21.                 LED_SMG_SCK = 0;
  22.                 if(0 != (uiDataOne&0x80))
  23.                 {
  24.                         LED_SMG_DATA = 1;
  25.                 }
  26.                 else
  27.                 {
  28.                         LED_SMG_DATA = 0;
  29.                 }
  30.                 LED_SMG_SCK = 1;
  31.                 uiDataOne <<= 1;
  32.         }
  33.         
  34.         for(i=0; i<8; i++)
  35.         {
  36.                 LED_SMG_SCK = 0;
  37.                 if(0 != (uiDataTwo&0x80))
  38.                 {
  39.                         LED_SMG_DATA = 1;
  40.                 }
  41.                 else
  42.                 {
  43.                         LED_SMG_DATA = 0;
  44.                 }
  45.                 LED_SMG_SCK = 1;
  46.                 uiDataTwo <<= 1;
  47.         }
  48.         LED_SMG_RCK = 1;        
  49. }

  50. /* 產生總線起始信號 */
  51. void I2CStart()
  52. {
  53.         I2C_SDA = 1; //首先確保 SDA、 SCL 都是高電平
  54.         I2C_SCL = 1;
  55.         I2CDelay();
  56.         I2C_SDA = 0; //先拉低 SDA
  57.         I2CDelay();
  58.         I2C_SCL = 0; //再拉低 SCL
  59. }

  60. /* 產生總線停止信號 */
  61. void I2CStop()
  62. {
  63.         I2C_SCL = 0; //首先確保 SDA、 SCL 都是低電平
  64.         I2C_SDA = 0;
  65.         I2CDelay();
  66.         I2C_SCL = 1; //先拉高 SCL
  67.         I2CDelay();
  68.         I2C_SDA = 1; //再拉高 SDA
  69.         I2CDelay();
  70. }

  71. /* I2C 總線寫操作, dat-待寫入字節,返回值-從機應答位的值 */
  72. bit I2CWrite(unsigned char dat)
  73. {
  74.         bit ack; //用于暫存應答位的值
  75.         unsigned char mask; //用于探測字節內某一位值的掩碼變量
  76.         for (mask=0x80; mask!=0; mask>>=1) //從高位到低位依次進行
  77.         {
  78.                 if ((mask&dat) == 0) //該位的值輸出到 SDA 上
  79.                         I2C_SDA = 0;
  80.                 else
  81.                         I2C_SDA = 1;
  82.                
  83.                 I2CDelay();
  84.                 I2C_SCL = 1; //拉高 SCL
  85.                 I2CDelay();
  86.                 I2C_SCL = 0; //再拉低 SCL,完成一個位周期
  87.         }
  88.         I2C_SDA = 1; //8 位數據發送完后,主機釋放 SDA,以檢測從機應答
  89.         I2CDelay();
  90.         I2C_SCL = 1; //拉高 SCL
  91.         ack = I2C_SDA; //讀取此時的 SDA 值,即為從機的應答值
  92.         I2CDelay();
  93.         I2C_SCL = 0; //再拉低 SCL 完成應答位,并保持住總線
  94.         return (~ack); //應答值取反以符合通常的邏輯:
  95.         //0=不存在或忙或寫入失敗, 1=存在且空閑或寫入成功
  96. }


  97. /* I2C 總線讀操作,并發送非應答信號,返回值-讀到的字節 */
  98. unsigned char I2CReadNAK()
  99. {
  100.         unsigned char mask;
  101.         unsigned char dat;
  102.         I2C_SDA = 1; //首先確保主機釋放 SDA
  103.         for (mask=0x80; mask!=0; mask>>=1) //從高位到低位依次進行
  104.         {
  105.                 I2CDelay();
  106.                 I2C_SCL = 1; //拉高 SCL
  107.                 if(I2C_SDA == 0) //讀取 SDA 的值
  108.                         dat &= ~mask; //為 0 時, dat 中對應位清零
  109.                 else
  110.                         dat |= mask; //為 1 時, dat 中對應位置 1
  111.                 I2CDelay();
  112.                 I2C_SCL = 0; //再拉低 SCL,以使從機發送出下一位
  113.         }
  114.         I2C_SDA = 1; //8 位數據發送完后,拉高 SDA,發送非應答信號
  115.         I2CDelay();
  116.         I2C_SCL = 1; //拉高 SCL
  117.         I2CDelay();
  118.         I2C_SCL = 0; //再拉低 SCL 完成非應答位,并保持住總線
  119.         return dat;
  120. }

  121. /* I2C 總線讀操作,并發送應答信號,返回值-讀到的字節 */
  122. unsigned char I2CReadACK()
  123. {
  124.         unsigned char mask;
  125.         unsigned char dat;
  126.         I2C_SDA = 1; //首先確保主機釋放 SDA
  127.         for (mask=0x80; mask!=0; mask>>=1) //從高位到低位依次進行
  128.         {
  129.         I2CDelay();
  130.         I2C_SCL = 1; //拉高 SCL
  131.         if(I2C_SDA == 0) //讀取 SDA 的值
  132.                 dat &= ~mask; //為 0 時, dat 中對應位清零
  133.         else
  134.                 dat |= mask; //為 1 時, dat 中對應位置 1
  135.         I2CDelay();
  136.         I2C_SCL = 0; //再拉低 SCL,以使從機發送出下一位
  137.         }
  138.         I2C_SDA = 0; //8 位數據發送完后,拉低 SDA,發送應答信號
  139.         I2CDelay();
  140.         I2C_SCL = 1; //拉高 SCL
  141.         I2CDelay();
  142.         I2C_SCL = 0; //再拉低 SCL 完成應答位,并保持住總線
  143.         
  144.         return dat;
  145. }

  146. /* 讀取 EEPROM 中的一個字節, addr-字節地址 */
  147. unsigned char E2ReadByte(unsigned char addr)
  148. {
  149.         unsigned char dat;
  150.         I2CStart();
  151.         I2CWrite(0x50<<1); //尋址器件,后續為寫操作
  152.         I2CWrite(addr); //寫入存儲地址
  153.         I2CStart(); //發送重復啟動信號
  154.         I2CWrite((0x50<<1)|0x01); //尋址器件,后續為讀操作
  155.         dat = I2CReadNAK(); //讀取一個字節數據
  156.         I2CStop();
  157.         return dat;
  158. }

  159. /* 向 EEPROM 中寫入一個字節, addr-字節地址 */
  160. void E2WriteByte(unsigned char addr, unsigned char dat)
  161. {
  162.         I2CStart();
  163.         I2CWrite(0x50<<1); //尋址器件,后續為寫操作
  164.         I2CWrite(addr); //寫入存儲地址
  165.         I2CWrite(dat); //寫入一個字節數據
  166.         I2CStop();
  167. }

  168. void Delay1ms(unsigned int i)
  169. {
  170.     int j;
  171.     for(; i>0; i--)
  172.          {
  173.          for(j = 0; j < 110; j++);
  174.     }
  175. }

  176. void ConfigUart(unsigned int baud)
  177. {
  178.         SCON = 0x50;
  179.         TMOD &= 0x0F;
  180.         TMOD |= 0x20;
  181.         TH1 = 256 - (11059200/12/32)/baud;
  182.         TL1 = TH1;
  183.         TR1 = 1;
  184.         ET1 = 0;
  185.         ES = 1;
  186. }

  187. void main()
  188. {
  189.         unsigned char dat;
  190.         unsigned char i;
  191.         unsigned char str[5];
  192.         
  193.         EA = 1;
  194.         ConfigUart(9600);
  195.         
  196.         RxdByte = E2ReadByte(0x20);
  197.         Delay1ms(100);
  198.                
  199.         str[0] = (RxdByte/100);
  200.         str[1] = (RxdByte/10%10);
  201.         str[2] = (RxdByte%10);
  202.         
  203.         //dat++;
  204.         E2WriteByte(0x20,RxdByte);//將數據存儲到E2PROM中
  205.         disbuf[2] = ucDataOneTab[str[2]];
  206.         disbuf[1] = ucDataOneTab[str[1]];
  207.         disbuf[0] = ucDataOneTab[str[0]];
  208.         
  209.         while(1)
  210.         {
  211.                 for(i=0; i<8; i++)
  212.                 {
  213.                         Send_data_smg(disbuf[i],ucDataTwoTab[i]);
  214.                         Delay1ms(1);
  215.                 }               
  216.         }
  217. }

  218. /* UART中斷服務函數 */
  219. void InterruptUART() interrupt 4
  220. {
  221.     if (RI)  //接收到字節
  222.     {
  223.         RI = 0;          //手動清零接收中斷標志位
  224.         RxdByte = SBUF;  //接收到的數據保存到接收字節變量中
  225.                          //用以提示用戶輸入的信息是否已正確接收
  226.           SBUF = RxdByte;
  227.     }
  228.     if (TI)  //字節發送完畢
  229.     {
  230.         TI = 0;  //手動清零發送中斷標志位
  231.     }
  232. }
復制代碼





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

使用道具 舉報

沙發
ID:415088 發表于 2020-5-28 19:25 | 只看該作者
/* UART中斷服務函數 */
void InterruptUART() interrupt 4
{
    if (RI)  //接收到字節
    {
        RI = 0;          //手動清零接收中斷標志位
        RxdByte = SBUF;  //接收到的數據保存到接收字節變量中
                         //用以提示用戶輸入的信息是否已正確接收
                SBUF = RxdByte;
                E2WriteByte(0x10,RxdByte);
    }
    if (TI)  //字節發送完畢
    {
        TI = 0;  //手動清零發送中斷標志位
    }
}
這樣子就可以了
回復

使用道具 舉報

板凳
ID:282850 發表于 2020-5-29 10:13 | 只看該作者
細看了E2WriteByte在main中只調了一次。加在UART中解決了,無問題?
回復

使用道具 舉報

地板
ID:415088 發表于 2020-6-1 21:57 | 只看該作者
f556 發表于 2020-5-29 10:13
細看了E2WriteByte在main中只調了一次。加在UART中解決了,無問題?

但是我加在中斷接收里面后,確實是可以達到我的題目要求了
回復

使用道具 舉報

5#
ID:801878 發表于 2020-7-13 19:31 | 只看該作者
加一個中斷 {     if (RI)  //接收到字節     {         RI = 0;          //手動清零接收中斷標志位         RxdByte = SBUF;  //接收到的數據保存到接收字節變量中                          //用以提示用戶輸入的信息是否已正確接收                 SBUF = RxdByte;                 E2WriteByte(0x10,RxdByte);
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 天天天天操| 综合九九 | 粉嫩av在线 | 亚洲天堂一区 | 二区视频 | 日韩av在线一区 | 日本精品一区二区三区视频 | 亚洲精品美女在线观看 | 国产精品一二区 | 欧美视频一区 | 精品视频一区二区三区在线观看 | 国产精品久久亚洲 | 亚州中文| 超碰国产在线 | 黄视频网址 | 久久久久国产精品人 | 成人免费激情视频 | 国产男女猛烈无遮掩视频免费网站 | 99精品热视频 | 久久男人天堂 | 免费国产一区 | 欧美一区二区大片 | 久久大陆| 欧美日韩在线视频一区 | 国产精品一区二区在线 | 91久操视频| 中文字幕在线一区二区三区 | av网站免费看 | 五月天婷婷激情 | 在线播放中文字幕 | 波多野结衣先锋影音 | 日韩欧美在线视频播放 | 日日干日日射 | 91久久| 九色在线观看 | 精品国产伦一区二区三区观看体验 | 久久久久91 | 在线日韩视频 | 久久69精品久久久久久久电影好 | 夜夜干夜夜操 | 成人在线国产 |