I2C.c
上传用户:xs588588
上传日期:2021-03-30
资源大小:242k
文件大小:5k
源码类别:

DSP编程

开发平台:

C/C++

  1. #include "I2C.h"
  2. void I2C_Initial( void )
  3. {
  4.     P1DIR |= SCL; //将SCL管脚(P1.3)设置为输出管脚
  5.     I2C_Set_sck_low();
  6.     I2C_STOP();
  7.     Delay_ms(10);
  8.     return;
  9. }
  10. void I2C_Set_sda_high( void )
  11. {
  12.     P1DIR |= SDA; //将SDA设置为输出模式
  13.     P1OUT |= SDA; //SDA管脚输出为高电平
  14.     
  15.     _NOP();
  16.     _NOP();
  17.     return;
  18. }
  19. void I2C_Set_sda_low ( void )
  20. {
  21.     P1DIR |= SDA; //将SDA设置为输出模式
  22.     P1OUT &= ~(SDA); //SDA管脚输出为低电平
  23.     
  24.     _NOP();
  25.     _NOP();
  26.     return;
  27. }
  28. void I2C_Set_sck_high( void )
  29. {
  30.     P1DIR |= SCL; //将SCL设置为输出模式
  31.     P1OUT |= SCL; //SCL管脚输出为高电平
  32.     
  33.     _NOP();
  34.     _NOP();
  35.     return;
  36. }
  37. void I2C_Set_sck_low ( void )
  38. {
  39.     P1DIR |= SCL; //将SCL设置为输出模式
  40.     P1OUT &= ~(SCL); //SCL管脚输出为低电平
  41.     
  42.     _NOP();
  43.     _NOP();
  44.     return;
  45. }
  46. int  I2C_GetACK(void)
  47. {
  48.     int nTemp = 0;
  49.     int j;
  50.     
  51.     _NOP();
  52.     _NOP();
  53.     I2C_Set_sck_low();
  54.     for(j = 30;j > 0;j--);
  55.     P1DIR &= ~(SDA); //将SDA设置为输入方向
  56.     //I2C_Set_sda_high();
  57.     I2C_Set_sck_high();
  58.     
  59.     for(j = 30;j > 0;j--);
  60.     nTemp = (int)(P1IN & SDA); //获得数据
  61.     
  62.     I2C_Set_sck_low();
  63.     
  64.     return (nTemp & SDA);
  65. }
  66. void I2C_SetACK(void)
  67. {   
  68.     I2C_Set_sck_low();
  69.     I2C_Set_sda_low();
  70.     I2C_Set_sck_high();
  71.     I2C_Set_sck_low();
  72.     return;
  73. }
  74. void I2C_SetNAk(void)
  75. {
  76.     I2C_Set_sck_low();
  77.     I2C_Set_sda_high();
  78.     I2C_Set_sck_high();
  79.     I2C_Set_sck_low();
  80.     return;
  81. }
  82. void I2C_START(void)
  83. {
  84.     int i;
  85.     
  86.     I2C_Set_sda_high();
  87.     for(i = 5;i > 0;i--);
  88.     I2C_Set_sck_high();
  89.     for(i = 5;i > 0;i--);
  90.     I2C_Set_sda_low();
  91.     for(i = 5;i > 0;i--);
  92.     I2C_Set_sck_low();
  93.     return;
  94. }
  95. void I2C_STOP(void)
  96. {
  97.     int i;
  98.     
  99.     I2C_Set_sda_low();
  100.     for(i = 5;i > 0;i--);
  101.     I2C_Set_sck_low();
  102.     for(i = 5;i > 0;i--);
  103.     I2C_Set_sck_high();
  104.     for(i = 5;i > 0;i--);
  105.     I2C_Set_sda_high();
  106.     for(i = 5;i > 0;i--);
  107.     I2C_Set_sck_low();
  108.     Delay_ms(10); //延迟一点时间
  109.     
  110.     return;
  111. }
  112. void I2C_TxByte(int nValue)
  113. {
  114.     int i;
  115.     int j;
  116.     
  117.     for(i = 0;i < 8;i++)
  118.     {
  119.      if(nValue & 0x80)
  120.          I2C_Set_sda_high();
  121.      else
  122.          I2C_Set_sda_low();
  123.      for(j = 30;j > 0;j--);
  124.      I2C_Set_sck_high();
  125.      nValue <<= 1;
  126.      for(j = 30;j > 0;j--);
  127.      I2C_Set_sck_low();
  128.     }
  129.     
  130.     return;
  131. }
  132. /////////////////////////////////////////////
  133. // 接收是从 LSB 到 MSB 的顺序
  134. int  I2C_RxByte(void)
  135. {
  136.     int nTemp = 0;
  137.     int i;
  138.     int j;
  139.     
  140.     I2C_Set_sda_high();
  141.     
  142.     P1DIR &= ~(SDA); //将SDA管脚设置为输入方向
  143.     _NOP();
  144.     _NOP();
  145.     _NOP();
  146.     _NOP();
  147.     for(i = 0;i < 8;i++)
  148.     {
  149.      I2C_Set_sck_high();
  150.     
  151.      if(P1IN & SDA)
  152.      {
  153.          nTemp |= (0x01 << i);
  154.      }
  155.      for(j = 30;j > 0;j--);
  156.      I2C_Set_sck_low();
  157.     }
  158.     
  159.     return nTemp;
  160. }
  161. void I2C_Write(char nAddr,char nValue)
  162. {
  163. int nTemp = 0xA0;//写命令
  164. // 启动数据总线
  165. I2C_START();
  166. // 发送控制字节
  167. I2C_TxByte(nTemp);
  168. // 等待 ACK
  169. nTemp = I2C_GetACK();
  170. // 发送地址字节
  171. I2C_TxByte(nAddr);
  172. // 等待 ACK
  173. nTemp = I2C_GetACK();
  174. // 发送数据字节
  175. I2C_TxByte(nValue);
  176. // 等待 ACK
  177. nTemp = I2C_GetACK();
  178. // 停止总线
  179. I2C_STOP();
  180.         return;
  181. }
  182. int PageWrite(char nAddr,char pBuf[])
  183. {
  184. int i;
  185. int nTemp = 0xA0;//写命令
  186. // 启动数据总线
  187. I2C_START();
  188. // 发送控制字节
  189. I2C_TxByte(nTemp);
  190. // 等待 ACK
  191. nTemp = I2C_GetACK();
  192. if(nTemp & BIT3) return 0;
  193. // 发送地址字节
  194. I2C_TxByte(nAddr);
  195. // 等待 ACK
  196. nTemp = I2C_GetACK();
  197. if(nTemp & BIT3) return 0;
  198. // 发送数据字节
  199. for(i = 0; i < 8;i++)
  200. {
  201. I2C_TxByte(pBuf[0]);
  202. // 等待 ACK
  203. nTemp = I2C_GetACK();
  204. if(nTemp & BIT3) return 0;
  205. }
  206. // 停止总线
  207. I2C_STOP();
  208.     return (nTemp & SDA);
  209. }
  210. char I2C_Read(int nAddr)
  211. {
  212.         int nRes = -1;
  213. //写命令
  214. int nTemp = 0xA0;
  215. // 启动数据总线
  216. I2C_START();
  217. // 发送控制字节
  218. I2C_TxByte(nTemp);
  219. // 等待 ACK
  220. nTemp = I2C_GetACK();
  221. // 发送地址字节
  222. I2C_TxByte(nAddr);
  223. // 等待 ACK
  224. nTemp = I2C_GetACK();
  225. // 启动数据总线
  226. I2C_START();
  227. // 发送控制字节
  228. nTemp = 0xA1;
  229. I2C_TxByte(nTemp);
  230. // 等待 ACK
  231. nTemp = I2C_GetACK();
  232. //读取数据
  233.     nRes = I2C_RxByte();
  234. // 停止总线
  235. I2C_STOP();
  236. //成功返回
  237. return nRes;
  238. }
  239. int ReadSeq(char nAddr, char nValue[], int nLen)
  240. {
  241. int i;
  242. //写命令
  243. int nTemp = 0xA0;
  244. // 启动数据总线
  245. I2C_START();
  246. // 发送控制字节
  247. I2C_TxByte(nTemp);
  248. // 等待 ACK
  249. nTemp = I2C_GetACK();
  250. if(nTemp & BIT3) return 0;
  251. // 发送地址字节
  252. I2C_TxByte(nAddr);
  253. // 等待 ACK
  254. nTemp = I2C_GetACK();
  255. if(nTemp & BIT3) return 0;
  256. // 启动数据总线
  257. I2C_START();
  258. // 发送控制字节
  259. nTemp = 0xA1;
  260. I2C_TxByte(nTemp);
  261. // 等待 ACK
  262. nTemp = I2C_GetACK();
  263. if(nTemp & BIT3) return 0;
  264. //读取数据
  265. for(i = 0; i < nLen; i++)
  266. {
  267. //读一个字节数据
  268. nValue[i] = I2C_RxByte();
  269. //发送ACK
  270. I2C_SetACK();
  271. }    
  272. // 停止总线
  273. I2C_STOP();
  274. //成功返回
  275. return 1;
  276. }
  277. void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
  278. {
  279.     unsigned long nCount;
  280.     int i;
  281.     unsigned long j;
  282.     nCount = 2667;
  283.     for(i = nValue;i > 0;i--)
  284.     {
  285.      for(j = nCount;j > 0;j--);
  286.     }
  287.     return;
  288. }
  289. void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
  290. {
  291.     int nCount;
  292.     int i;
  293.     int j;
  294.     nCount = 3;
  295.     for(i = nValue;i > 0;i--)
  296.     {
  297.      for(j = nCount;j > 0;j--);
  298.     }
  299.     return;
  300. }