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

QQ登錄

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

搜索
查看: 2735|回復(fù): 14
收起左側(cè)

STC8A單片機(jī)用I2C擴(kuò)展IO口芯片不知道問(wèn)題出在哪里,新年快樂(lè)

[復(fù)制鏈接]
ID:1022674 發(fā)表于 2023-1-29 18:34 | 顯示全部樓層 |閱讀模式
這個(gè)程序就是測(cè)試一下單片機(jī)的I2C程序,能不能和IO口擴(kuò)展芯片通訊使用。
各位大老,不知道問(wèn)題出在哪里,燒進(jìn)去沒(méi)反應(yīng),接觸單片機(jī)時(shí)間不長(zhǎng),望大老有時(shí)間幫忙看看,在這里謝謝了!新年快樂(lè)!

單片機(jī)源程序如下:
  1. #include<reg52.h>
  2. #include "intrins.h"
  3. #define unit unsigned int
  4. #define uchar unsigned char
  5.         
  6. #define I2CCFG          (*(unsigned char volatile xdata *)0xfe80)
  7. #define I2CMSCR         (*(unsigned char volatile xdata *)0xfe81)
  8. #define I2CMSST         (*(unsigned char volatile xdata *)0xfe82)
  9. #define I2CSLCR         (*(unsigned char volatile xdata *)0xfe83)
  10. #define I2CSLST         (*(unsigned char volatile xdata *)0xfe84)
  11. #define I2CSLADR        (*(unsigned char volatile xdata *)0xfe85)
  12. #define I2CTXD          (*(unsigned char volatile xdata *)0xfe86)
  13. #define I2CRXD          (*(unsigned char volatile xdata *)0xfe87)

  14. #define  i2cl  0x44          //定義前提命令 -發(fā)送低8位IO口數(shù)據(jù)
  15. #define  i2ch  0x46         //定義前提命令 -發(fā)送高8位IO口數(shù)據(jù)

  16. unsigned int u=0;v=0;x=0; y=0; m=0;w=0;
  17. static unsigned char  a,b,d,e,f,g,h,i,c,i2clh,i2cdata;

  18. sfr     P0M0        =   0x94;
  19. sfr     P0M1        =   0x93;
  20. sfr     P1M0        =   0x92;
  21. sfr     P1M1        =   0x91;
  22. sfr     P2M0        =   0x96;
  23. sfr     P2M1        =   0x95;
  24. sfr     P3M0        =   0xb2;
  25. sfr     P3M1        =   0xb1;
  26. sfr     P4M0        =   0xb4;
  27. sfr     P4M1        =   0xb3;
  28. sfr     P5M0        =   0xca;
  29. sfr     P5M1        =   0xc9;
  30. sfr     P6M0        =   0xcc;
  31. sfr     P6M1        =   0xcb;
  32. sfr     P7M0        =   0xe2;
  33. sfr     P7M1        =   0xe1;


  34. sfr  P4  = 0xc0;
  35. sfr  P5  = 0xc8;
  36. sfr  P6  = 0xe8;
  37. sfr  P7  = 0xf8;


  38. sfr     P_SW2       =   0xba;

  39. sbit k1=P7^3;                    //高/低位數(shù)據(jù)選擇開(kāi)關(guān)
  40. sbit k2=P2^0;                    //點(diǎn)動(dòng)測(cè)試開(kāi)關(guān),數(shù)據(jù)有變化I2C就發(fā)送新的數(shù)據(jù)到IO擴(kuò)展IC
  41. sbit k14=P4^2;                  //清零開(kāi)關(guān)

  42. bit busy;                            //I2C中斷標(biāo)志位

  43. void timer0Init()                //中斷時(shí)間計(jì)數(shù)器函數(shù)
  44. {
  45. TMOD|=0x01;
  46. TH0=0xFF;
  47. TL0=0xA3;
  48. ET0=1;
  49. EA=1;
  50. TR0=1;
  51. }

  52. void Timer0() interrupt 1               //程序運(yùn)行依賴-中斷函數(shù)
  53. {
  54.                           TH0=0xFF;
  55.                           TL0=0xA3;
  56.                
  57.                           y++;               
  58.                           u++;               
  59.                           v++;               
  60.                           ys++;
  61.                                                    
  62.                           if(k2==0||k14==0)
  63.                             {x++; }                                                                                                                                       
  64. }

  65. void I2C_Isr() interrupt 24                        //I2C中斷函數(shù)-清零
  66. {
  67.     char store;

  68.     store = P_SW2;
  69.     P_SW2 |= 0x80;
  70.     if (I2CMSST & 0x40)
  71.     {
  72.         I2CMSST &= ~0x40;                       //清中斷標(biāo)志
  73.         busy = 0;
  74.     }
  75.     P_SW2 = store;
  76. }

  77. //_______________________________       I2C各命令子函數(shù)
  78. void Start()
  79. {
  80.     busy = 1;
  81.     I2CMSCR = 0x81;                             //發(fā)送START命令
  82.     while (busy);
  83. }

  84. void SendData(char dat)
  85. {
  86.     I2CTXD = dat;                               //寫數(shù)據(jù)到數(shù)據(jù)緩沖區(qū)
  87.     busy = 1;
  88.     I2CMSCR = 0x82;                             //發(fā)送SEND命令
  89.     while (busy);
  90. }

  91. void RecvACK()
  92. {
  93.     busy = 1;
  94.     I2CMSCR = 0x83;                             //發(fā)送讀ACK命令
  95.     while (busy);
  96. }

  97. void Stop()
  98. {
  99.     busy = 1;
  100.     I2CMSCR = 0x86;                             //發(fā)送STOP命令
  101.     while (busy);
  102. }
  103. //_________________________

  104. void i2c(char aa,char  bb)         //數(shù)據(jù)發(fā)送完整流程函數(shù)
  105. {
  106.         Start();                        //啟動(dòng)
  107.         SendData(aa);              //發(fā)數(shù)據(jù)1  --設(shè)置命令
  108.         RecvACK();                  //應(yīng)答1
  109.         SendData(bb);              //發(fā)數(shù)據(jù)2  --驅(qū)動(dòng)數(shù)據(jù)
  110.         RecvACK();                  //應(yīng)答2
  111.         Stop();                          //停止
  112. }

  113. void cx1()
  114. {
  115.         e=c;f=d;
  116.         
  117.         if(k1==0)                                                         //高8位數(shù)據(jù)+1
  118.           {if(k2==0&&x>50){while(!k2);c++;x=0;}}       //x>50-為開(kāi)關(guān)消抖

  119.         if(k1==1)                                                        //低8位數(shù)據(jù)+1
  120.           {if(k2==0&&x>50){while(!k2);d++;x=0;}}                                

  121.         if(k14==0&&x>50)                    //按鍵清零
  122.           {while(!k14);c=d=e=f=x=0;}        
  123.                         
  124.         if(e!=c){i2c(i2cl,c);}                       //高8位數(shù)據(jù)有變化就發(fā)送到IO擴(kuò)展芯片
  125.         
  126.         if(f!=d){i2c(i2ch,d);}                 //低8位數(shù)據(jù)有變化就發(fā)送到IO擴(kuò)展芯片
  127.                         
  128.         if(c>8){c=e=0;}      //超過(guò)8位,清零
  129.                         
  130.         if(d>8){d=f=0;}      //超過(guò)8位,清零
  131. }

  132. main()
  133. {
  134.          
  135.         timer0Init();
  136.         
  137.          
  138.   P_SW2 = 0x90;                             //使能I2C主機(jī)模式-并配置I2C腳位
  139.   I2CCFG = 0xe0;                              //使能I2C主機(jī)模式
  140.   I2CMSST = 0x00;

  141.   i2c(0x48,0x10);                             //IO擴(kuò)展芯片配置清零
  142.          
  143.   P0=P1=P6=0x00; P2=P7=0x0F; P3=0xE2; P4=0x06;P5=0x03;
  144.          
  145.     P0M0 = 0x00;                                //設(shè)置P0.0~P0.7為準(zhǔn)雙向口模式
  146.     P0M1 = 0x00;
  147.     P1M0 = 0x00;                                //設(shè)置P1.0~P1.7為準(zhǔn)雙向口模式
  148.     P1M1 = 0x00;
  149.     P2M0 = 0x00;                                //設(shè)置P2.0~P2.7為準(zhǔn)雙向口模式
  150.     P2M1 = 0x00;
  151.     P3M0 = 0x00;                                //設(shè)置P3.0~P3.7為準(zhǔn)雙向口模式
  152.     P3M1 = 0x00;
  153.     P4M0 = 0x00;                                //設(shè)置P4.0~P4.7為準(zhǔn)雙向口模式
  154.     P4M1 = 0x00;
  155.     P5M0 = 0x00;                                //設(shè)置P5.0~P5.7為準(zhǔn)雙向口模式
  156.     P5M1 = 0x00;
  157.     P6M0 = 0x00;                                //設(shè)置P6.0~P6.7為準(zhǔn)雙向口模式
  158.     P6M1 = 0x00;
  159.     P7M0 = 0x00;                                //設(shè)置P7.0~P7.7為準(zhǔn)雙向口模式
  160.     P7M1 = 0x00;
  161.     a=0;
  162.     b=0;
  163.     c=0;
  164.     i=0;

  165.    while(1)
  166.   {                  
  167.          cx1();
  168.   }
  169. }        
復(fù)制代碼

兩線遠(yuǎn)程 IO 擴(kuò)展芯片 CH423.pdf

203.17 KB, 下載次數(shù): 6

回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-29 18:38 | 顯示全部樓層
調(diào)試時(shí),發(fā)現(xiàn)會(huì)在Start()啟動(dòng)函數(shù)下, while (busy); 這里卡住,難道是沒(méi)有進(jìn)入I2C中斷里清零?如果是這樣,那為什么沒(méi)有進(jìn)入I2C中斷呢?希望各位大老指教!新年快樂(lè)!
回復(fù)

使用道具 舉報(bào)

ID:401564 發(fā)表于 2023-1-29 21:47 | 顯示全部樓層
新手別搞這些量大的代碼
STC8A不需要端口擴(kuò)展,你用都用不完
如果是想學(xué)習(xí)一下IIC,那就必須得是24C01不可了
單片機(jī)學(xué)習(xí)本身就是通過(guò)抄別人的代碼來(lái)提升自己,從而達(dá)到別人也要抄你代碼的高度
回復(fù)

使用道具 舉報(bào)

ID:1034262 發(fā)表于 2023-1-29 23:16 | 顯示全部樓層
示波器先看一下I2C有輸出嗎?
直接測(cè)試STC官方例程可以嗎?
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-30 09:46 | 顯示全部樓層
Y_G_G 發(fā)表于 2023-1-29 21:47
新手別搞這些量大的代碼
STC8A不需要端口擴(kuò)展,你用都用不完
如果是想學(xué)習(xí)一下IIC,那就必須得是24C01不可 ...

哦,謝謝!受教了。新年快樂(lè)!
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-30 09:47 | 顯示全部樓層
coody_sz 發(fā)表于 2023-1-29 23:16
示波器先看一下I2C有輸出嗎?
直接測(cè)試STC官方例程可以嗎?

我測(cè)一下,謝謝!新年快樂(lè)!
回復(fù)

使用道具 舉報(bào)

ID:1010435 發(fā)表于 2023-1-30 10:49 | 顯示全部樓層
建議先用針腳模擬I2C,網(wǎng)上大把的成品函數(shù),理解各個(gè)函數(shù)的作用和時(shí)序后,再用硬件I2C驅(qū)動(dòng),
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-30 14:42 | 顯示全部樓層
mtt661 發(fā)表于 2023-1-30 10:49
建議先用針腳模擬I2C,網(wǎng)上大把的成品函數(shù),理解各個(gè)函數(shù)的作用和時(shí)序后,再用硬件I2C驅(qū)動(dòng),

模擬I2C,之前有試過(guò),現(xiàn)在想用單片機(jī)的硬件I2C試試,問(wèn)題好像是數(shù)據(jù)不發(fā)送,也進(jìn)不了I2C的中斷函數(shù),然后卡在那里。
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-30 14:50 | 顯示全部樓層
wjq0312 發(fā)表于 2023-1-30 09:47
我測(cè)一下,謝謝!新年快樂(lè)!

沒(méi)有輸出,官方示例也沒(méi)有輸出,問(wèn)題好像是數(shù)據(jù)命令不發(fā)送,然后就不會(huì)有中斷請(qǐng)求,所以就進(jìn)不了I2C的中斷函數(shù),然后卡在那里。真奇怪,給發(fā)送緩沖區(qū)數(shù)據(jù)為什么不會(huì)發(fā)送。
回復(fù)

使用道具 舉報(bào)

ID:624769 發(fā)表于 2023-1-30 23:07 | 顯示全部樓層
wjq0312 發(fā)表于 2023-1-30 14:50
沒(méi)有輸出,官方示例也沒(méi)有輸出,問(wèn)題好像是數(shù)據(jù)命令不發(fā)送,然后就不會(huì)有中斷請(qǐng)求,所以就進(jìn)不了I2C的中 ...

具體型號(hào),具體版本,
STC8A  分  STC8A8K64D4(新)    和  STC8A8K64S4A12(舊) 這兩種
實(shí)際使用中 STC8A8K64D4(新)  有部分芯片,使用 I2C 中斷方式  會(huì)莫名失敗。即開(kāi)了中斷I2C 就不工作。或者,會(huì)莫名不觸發(fā)中斷,但是查詢方式一切正常。 而 STC8A8K64S4A12(舊) 則沒(méi)有這個(gè)問(wèn)題。假如你用的STC8A8K64D4(新) 建議你直接改成查詢方式操作,看你的代碼,你中斷方式 也是傻等,和查詢其實(shí)沒(méi)有差別。
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-31 10:49 | 顯示全部樓層
188610329 發(fā)表于 2023-1-30 23:07
具體型號(hào),具體版本,
STC8A  分  STC8A8K64D4(新)    和  STC8A8K64S4A12(舊) 這兩種
實(shí)際使用中 STC8A8 ...

哦,好的,謝謝大老!新年快樂(lè)!
回復(fù)

使用道具 舉報(bào)

ID:1022674 發(fā)表于 2023-1-31 11:06 | 顯示全部樓層
188610329 發(fā)表于 2023-1-30 23:07
具體型號(hào),具體版本,
STC8A  分  STC8A8K64D4(新)    和  STC8A8K64S4A12(舊) 這兩種
實(shí)際使用中 STC8A8 ...

就是你說(shuō)的STC8A8K64D4這個(gè)型號(hào),謝謝解惑!
回復(fù)

使用道具 舉報(bào)

ID:975054 發(fā)表于 2023-8-31 14:53 | 顯示全部樓層
今天碰到個(gè)問(wèn)題還沒(méi)解決:
之前一直用20腳的STC8G1K08的I2C很正常;
近來(lái)簡(jiǎn)化為8腳STC8G1K08A后,就不正常!說(shuō)明如下:
選I2C腳為P54P55(設(shè)置為開(kāi)漏串300Ω到I2C外設(shè),特殊原因,我MCU電池供電,I2C模塊3.3V,得匹配), 引腳功能切換設(shè)置P_SW2 |= 0X10,按手冊(cè)應(yīng)該沒(méi)錯(cuò),其他初始化及外設(shè)一概沒(méi)變;I2C就是不能正常運(yùn)行。
回復(fù)

使用道具 舉報(bào)

ID:975054 發(fā)表于 2023-9-1 18:34 | 顯示全部樓層
ax6808 發(fā)表于 2023-8-31 14:53
今天碰到個(gè)問(wèn)題還沒(méi)解決:
之前一直用20腳的STC8G1K08的I2C很正常;
近來(lái)簡(jiǎn)化為8腳STC8G1K08A后,就不正常 ...

今天再次摸查情況: STC8的I2C時(shí)鐘腳我設(shè)為開(kāi)漏輸出禁止輸入了,外部有10K上拉電阻, 原來(lái)是:我設(shè)置為允許輸入后,I2C居然能正常工作了。之前I2C和MCU電平匹配設(shè)為雙向置1時(shí),這個(gè)腳可以禁止輸入的。
回復(fù)

使用道具 舉報(bào)

ID:975054 發(fā)表于 2023-9-2 19:30 | 顯示全部樓層
ax6808 發(fā)表于 2023-9-1 18:34
今天再次摸查情況: STC8的I2C時(shí)鐘腳我設(shè)為開(kāi)漏輸出禁止輸入了,外部有10K上拉電阻, 原來(lái)是:我設(shè)置為允許輸 ...

看了有關(guān)文章,啟發(fā)很大!總之:而腳都得默認(rèn)允許輸入!
之前我MCU有硬件I2C口,只接一個(gè)共用3.3V電源的從機(jī),MCU二腳可設(shè)置為雙向置1,SCL可以禁止輸入,工作很正常的(其實(shí)可能不夠可靠)。后來(lái)改為不共用電源后,已設(shè)置為開(kāi)漏,外部有上拉電阻,結(jié)果就不正常了。后來(lái)檢查發(fā)現(xiàn)這種情況SCL就得設(shè)置回默認(rèn)的允許輸入才行!可能是有些代碼變了響應(yīng)不及時(shí),SCL禁止輸入主機(jī)就探測(cè)不到被拉低了所以出錯(cuò)!
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表