您的位置 首页 开关

Cortex-M3 (NXP LPC1788)之IIC使用–PCA9532进行IO扩展和LED亮度操控

PCA9532是一个I2C接口的设备,可以用于IO的扩展和LED的亮度调节。它内部集成了振荡器,可以输出2路用户可编程的PWM波,周期从6.58m…

PCA9532是一个I2C接口的设备,能够用于IO的扩展和LED的亮度调理。它内部集成了振荡器,能够输出2路用户可编程的PWM波,周期从6.58ms到1.69S。16路的输出,能够设置成输出凹凸电平以及PWM波输出。

做为从设备,他的8位地址的高四位固定为1100,最低位为数据的方向位,剩余的3位有硬件连线确认他的地址。PCA9532共有10个寄存器来装备他的输出状况。

其间INPUT0 INPUT1在管脚装备成一般IO时分用于读入IO脚的状况。PSC0 PWM0 PSC1 PWM1用于设置两路PWM波的周期和占空比。LS0~LS3用于挑选每个管脚的功用,包含通用LED OFF、LED ON、 PWM0、 PWM1。

知道了需求装备的寄存器,那怎样经过I2C通讯来装备这几个寄存器呢?当LPC1788宣布PCA9532的地址得到应对后,需求发送一个字节的数据用于装备操控寄存器,他们第四位为B3~B0位,比方发送的字节第4位为0,即B3~B0为0则他接下去收到的数据用来装备INPUT0。装备寄存器的第4位为AI,即autoincrease,一共接纳到一个字节的装备数据后,是否主动的将B3~B0加1,便利装备下一个表中的寄存器。

开发板上的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进入主发送形式
  28. while(!(rI2C0CONSET&(0x1<<3)));//开端条件发送完结
  29. rI2C0CONCLR=0x1<<5;//铲除STA标志
  30. return(rI2C0STAT&0xF8);
  31. }
  32. voidI2C0_Stop()
  33. {
  34. rI2C0CONCLR=0x1<<5;//铲除STA标志
  35. rI2C0CONSET|=0x1<<4;//发送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)));//发送完数据得到了应对
  43. return(rI2C0STAT&0xF8);
  44. }
  45. unsignedcharI2C0_GetByte(unsignedchar*data,unsignedcharack_flag)
  46. {
  47. if(ack_flag)
  48. {
  49. rI2C0CONSET|=0x1<<2;//主接纳形式,接纳到一个字节回来应对
  50. }
  51. else
  52. {
  53. rI2C0CONCLR=0x1<<2;//主接纳形式,接纳最终一个字节时,不回来应对
  54. }
  55. rI2C0CONCLR=0x1<<3;//铲除SI标志
  56. while(!(rI2C0CONSET&(0x1<<3)));//发送完数据得到了应对
  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操控铲除寄存器为只读,因而不能进行|=操作,不然状况寄存器的值反常。不知道为什么不是发生反常复位,之前EEPROM也对只读寄存器进行该操作会发生体系反常进入反常中断。
2,在主发送形式切换到主接纳形式的过程中,一定要先铲除SI标志。开端没留意,发送重复开端一共后的状况一直是0x28,把这个重复开端标志单数据发送?

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/265735.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部