新聞中心

        EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > Cortex-M3 (NXP LPC1788)之IIC應用--PCA9532進行IO擴展和LED亮度控制

        Cortex-M3 (NXP LPC1788)之IIC應用--PCA9532進行IO擴展和LED亮度控制

        作者: 時間:2016-11-19 來源:網絡 收藏
        PCA9532是一個I2C接口的設備,可以用于IO的擴展和LED的亮度調節(jié)。它內部集成了振蕩器,可以輸出2路用戶可編程的PWM波,周期從6.58ms到1.69S。16路的輸出,可以設置成輸出高低電平以及PWM波輸出。

        做為從設備,他的8位地址的高四位固定為1100,最低位為數據的方向位,剩下的3位有硬件連線確定他的地址。PCA9532共有10個寄存器來配置他的輸出狀態(tài)。

        本文引用地址:http://www.104case.com/article/201611/318456.htm

        其中INPUT0 INPUT1在管腳配置成普通IO時候用于讀入IO腳的狀態(tài)。PSC0 PWM0 PSC1 PWM1用于設置兩路PWM波的周期和占空比。LS0~LS3用于選擇每個管腳的功能,包括通用LED OFF、LED ON、 PWM0、 PWM1。

        知道了需要配置的寄存器,那怎么通過I2C通信來配置這幾個寄存器呢?當LPC1788發(fā)出PCA9532的地址得到應答后,需要發(fā)送一個字節(jié)的數據用于配置控制寄存器,他們第四位為B3~B0位,比如發(fā)送的字節(jié)第4位為0,即B3~B0為0則他接下去收到的數據用來配置INPUT0。配置寄存器的第4位為AI,即autoincrease,表示接收到一個字節(jié)的配置數據后,是否自動的將B3~B0加1,方便配置下一個表中的寄存器。

        開發(fā)板上的PCA9532的電路圖如下

        程序中配置LED0~7為GPIO用于檢測按鍵,LED8~LED11配置成PWM輸出,將LED RED做出漸亮漸暗的效果,LED12~LED15根據按鍵值設置成LED ON 或LED OFF。按鍵值讀取PCA9532的INPUT0得到。程序如下

        1. #definePCLK60000000
        2. #defineI2C0SCK100000
        3. #definePCA9532_ADDRESS0x60
        4. #definerI2C0CONSET(*(volatileunsigned*)(0x4001C000))
        5. #definerI2C0CONCLR(*(volatileunsigned*)(0x4001C018))
        6. #definerI2C0STAT(*(volatileunsigned*)(0x4001C004))
        7. #definerI2C0DAT(*(volatileunsigned*)(0x4001C008))
        8. #definerI2C0SCLH(*(volatileunsigned*)(0x4001C010))
        9. #definerI2C0SCLL(*(volatileunsigned*)(0x4001C014))
        10. #definerIOCON_P0_27(*(volatileunsigned*)(0x4002C06C))
        11. #definerIOCON_P0_28(*(volatileunsigned*)(0x4002C070))
        12. #definerPCONP(*(volatileunsigned*)(0x400FC0C4))
        13. unsignedcharconfig[11],read_data[1];
        14. voidI2C0_Init()
        15. {
        16. rIOCON_P0_27=(rIOCON_P0_27&(~0x7))|0x1;//I2C0_SDA
        17. rIOCON_P0_28=(rIOCON_P0_28&(~0x7))|0x1;//I2C0_SCL
        18. rPCONP|=0x1<<7;//I2C0PowerEnable
        19. rI2C0SCLH=PCLK/I2C0SCK/2;//setI2C0frequency100khz
        20. rI2C0SCLL=PCLK/I2C0SCK/2;
        21. rI2C0CONSET|=0x1<<6;//I2C接口使能
        22. rI2C0CONCLR=0x1<<3|0x1<<5;//清除SISTA
        23. }
        24. unsignedcharI2C0_Start()
        25. {
        26. rI2C0CONCLR=0x1<<3;//清除SI標志
        27. rI2C0CONSET|=0x1<<5;//置位STA進入主發(fā)送模式
        28. while(!(rI2C0CONSET&(0x1<<3)));//起始條件發(fā)送完成
        29. rI2C0CONCLR=0x1<<5;//清除STA標志
        30. return(rI2C0STAT&0xF8);
        31. }
        32. voidI2C0_Stop()
        33. {
        34. rI2C0CONCLR=0x1<<5;//清除STA標志
        35. rI2C0CONSET|=0x1<<4;//發(fā)送STO標志
        36. rI2C0CONCLR=0x1<<3;//清除SI標志
        37. }
        38. unsignedcharI2C0_SentByte(unsignedchardata)
        39. {
        40. rI2C0DAT=data;
        41. rI2C0CONCLR=0x1<<3;//清除SI標志
        42. while(!(rI2C0CONSET&(0x1<<3)));//發(fā)送完數據得到了應答
        43. return(rI2C0STAT&0xF8);
        44. }
        45. unsignedcharI2C0_GetByte(unsignedchar*data,unsignedcharack_flag)
        46. {
        47. if(ack_flag)
        48. {
        49. rI2C0CONSET|=0x1<<2;//主接收模式,接收到一個字節(jié)返回應答
        50. }
        51. else
        52. {
        53. rI2C0CONCLR=0x1<<2;//主接收模式,接收最后一個字節(jié)時,不返回應答
        54. }
        55. rI2C0CONCLR=0x1<<3;//清除SI標志
        56. while(!(rI2C0CONSET&(0x1<<3)));//發(fā)送完數據得到了應答
        57. *data=(unsignedchar)rI2C0DAT;
        58. return(rI2C0STAT&0xF8);
        59. }
        60. intI2C0_MasterTransfer(unsignedcharslave_address,unsignedchar*transfer_data,unsignedinttransfer_count,
        61. unsignedchar*receive_data,unsignedintreceive_count)
        62. {
        63. unsignedcharstatus;
        64. unsignedinti;
        65. status=I2C0_Start();
        66. while(status!=0x08);
        67. status=I2C0_SentByte(slave_address<<1);
        68. while(status!=0x18);
        69. for(i=0;i
        70. {
        71. status=I2C0_SentByte(*(transfer_data+i));
        72. while(status!=0x28);
        73. }
        74. if(receive_data!=(void*)0&&receive_count!=0)
        75. {
        76. //進入主接收模式
        77. status=I2C0_Start();
        78. while(status!=0x10);
        79. status=I2C0_SentByte((slave_address<<1)|0x1);
        80. while(status!=0x40);
        81. for(i=0;i
        82. {
        83. if(i
        84. {
        85. status=I2C0_GetByte(receive_data,1);
        86. while(status!=0x50);
        87. }
        88. else
        89. {
        90. status=I2C0_GetByte(receive_data,0);
        91. while(status!=0x58);
        92. }
        93. receive_data++;
        94. }
        95. }
        96. I2C0_Stop();
        97. return1;
        98. }
        99. voidPCA9532_Config()
        100. {
        101. config[0]=0x1<<4;//讀寫控制寄存器后低四位自動增加
        102. config[1]=0;//input0
        103. config[2]=0;//input1
        104. config[3]=0;//PSC0PWM0的周期6.5ms
        105. config[4]=0;//PWM0PWM0占空比設置成0%
        106. config[5]=0;//PSC1PWM1的周期為6.5ms
        107. config[6]=0;//PWM1PWM1占空比設置成0%
        108. config[7]=0;//LS0
        109. config[8]=0;//LS1LED0~7設置成GPIOS
        110. config[9]=0xFA;//LS211111010,LED8,9->blinksPWM0;LED10,11->blinksPWM1
        111. config[10]=0;//LS3LED12~LED15,LEDoff
        112. }
        113. intmain(void)
        114. {
        115. unsignedcharflag=1,data=0;
        116. unsignedinti;
        117. I2C0_Init();
        118. PCA9532_Config();
        119. while(1)
        120. {
        121. I2C0_MasterTransfer(PCA9532_ADDRESS,config,sizeof(config),0,0);
        122. I2C0_MasterTransfer(PCA9532_ADDRESS,&data,1,read_data,1);
        123. if(flag)
        124. {
        125. config[4]++;
        126. config[6]++;
        127. }
        128. else
        129. {
        130. config[4]--;
        131. config[6]--;
        132. }
        133. if(config[4]==255||config[4]==0)
        134. {
        135. flag=!flag;
        136. }
        137. for(i=0;i<4;i++)
        138. {
        139. if(read_data[0]&(0x1<
        140. {
        141. config[10]&=~(0x3<<(i*2));
        142. }
        143. else
        144. {
        145. config[10]|=(0x1<<(i*2));
        146. }
        147. }
        148. }
        149. }



        程序調試過程中遇到如下問題,要注意:
        1,I2C控制清除寄存器為只讀,因此不能進行|=操作,否則狀態(tài)寄存器的值異常。不知道為什么不是產生異常復位,之前EEPROM也對只讀寄存器進行該操作會產生系統(tǒng)異常進入異常中斷。
        2,在主發(fā)送模式切換到主接收模式的過程中,一定要先清除SI標志。開始沒注意,發(fā)送重復起始表示后的狀態(tài)一直是0x28,把這個重復起始標志單數據發(fā)送?


        評論


        相關推薦

        技術專區(qū)

        關閉
        主站蜘蛛池模板: 庆安县| 河北省| 乐东| 江门市| 黎平县| 三明市| 静宁县| 绩溪县| 宜宾县| 景泰县| 海阳市| 东方市| 文昌市| 灵武市| 黄大仙区| 大同县| 灵石县| 青冈县| 泊头市| 庆阳市| 商水县| 宁波市| 白银市| 福海县| 祁东县| 枣强县| 临洮县| 梅河口市| 宁国市| 石渠县| 浦东新区| 广汉市| 深州市| 舞钢市| 白朗县| 房产| 九江县| 九江市| 忻城县| 台江县| 旬阳县|