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

DSP编程

开发平台:

C/C++

  1. #include "I2C.h"
  2. void I2C_Initial( void )
  3. {
  4.     P1DIR |= BIT2; //将SCL管脚(P1.2)设置为输出管脚
  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. /////////////////////////////////////////////
  162. // 接收是从 MSB 到 LSB 的顺序
  163. int  I2C_RxByteHiToLow(void)
  164. {
  165.     int nTemp = 0;
  166.     int i;
  167.     int j;
  168.     
  169.     I2C_Set_sda_high();
  170.     
  171.     P1DIR &= ~(SDA); //将SDA管脚设置为输入方向
  172.     _NOP();
  173.     _NOP();
  174.     _NOP();
  175.     _NOP();
  176.     for(i = 0;i < 8;i++)
  177.     {
  178.      I2C_Set_sck_high();
  179.     
  180.      if(P1IN & SDA)
  181.      {
  182.          nTemp |= (0x01 << (8-i));
  183.      }
  184.      for(j = 30;j > 0;j--);
  185.      I2C_Set_sck_low();
  186.     }
  187.     
  188.     return nTemp;
  189. }
  190. int WriteSingleByte(char nAddr,char nValue)
  191. {
  192. int nTemp = 0xA0;//写命令
  193. // 启动数据总线
  194. I2C_START();
  195. // 发送控制字节
  196. I2C_TxByte(nTemp);
  197. // 等待 ACK
  198. nTemp = I2C_GetACK();
  199. if(nTemp & BIT3) return 0;
  200. // 发送地址字节
  201. I2C_TxByte(nAddr);
  202. // 等待 ACK
  203. nTemp = I2C_GetACK();
  204. if(nTemp & BIT3) return 0;
  205. // 发送数据字节
  206. I2C_TxByte(nValue);
  207. // 等待 ACK
  208. nTemp = I2C_GetACK();
  209. if(nTemp & BIT3) return 0;
  210. // 停止总线
  211. I2C_STOP();
  212.     return (nTemp & SDA);
  213. }
  214. int PageWrite(char nAddr,char pBuf[])
  215. {
  216. int i;
  217. int nTemp = 0xA0;//写命令
  218. // 启动数据总线
  219. I2C_START();
  220. // 发送控制字节
  221. I2C_TxByte(nTemp);
  222. // 等待 ACK
  223. nTemp = I2C_GetACK();
  224. if(nTemp & BIT3) return 0;
  225. // 发送地址字节
  226. I2C_TxByte(nAddr);
  227. // 等待 ACK
  228. nTemp = I2C_GetACK();
  229. if(nTemp & BIT3) return 0;
  230. // 发送数据字节
  231. for(i = 0; i < 8;i++)
  232. {
  233. I2C_TxByte(pBuf[0]);
  234. // 等待 ACK
  235. nTemp = I2C_GetACK();
  236. if(nTemp & BIT3) return 0;
  237. }
  238. // 停止总线
  239. I2C_STOP();
  240.     return (nTemp & SDA);
  241. }
  242. int ReadRandom(char nAddr, char *nValue)
  243. {
  244. //写命令
  245. int nTemp = 0xA0;
  246. // 启动数据总线
  247. I2C_START();
  248. // 发送控制字节
  249. I2C_TxByte(nTemp);
  250. // 等待 ACK
  251. nTemp = I2C_GetACK();
  252. if(nTemp & BIT3) return 0;
  253. // 发送地址字节
  254. I2C_TxByte(nAddr);
  255. // 等待 ACK
  256. nTemp = I2C_GetACK();
  257. if(nTemp & BIT3) return 0;
  258. // 启动数据总线
  259. I2C_START();
  260. // 发送控制字节
  261. nTemp = 0xA1;
  262. I2C_TxByte(nTemp);
  263. // 等待 ACK
  264. nTemp = I2C_GetACK();
  265. if(nTemp & BIT3) return 0;
  266. //读取数据
  267.     *nValue = I2C_RxByte();
  268. // 停止总线
  269. I2C_STOP();
  270. //成功返回
  271. return 1;
  272. }
  273. int ReadSeq(char nAddr, char nValue[], int nLen)
  274. {
  275. int i;
  276. //写命令
  277. int nTemp = 0xA0;
  278. // 启动数据总线
  279. I2C_START();
  280. // 发送控制字节
  281. I2C_TxByte(nTemp);
  282. // 等待 ACK
  283. nTemp = I2C_GetACK();
  284. if(nTemp & BIT3) return 0;
  285. // 发送地址字节
  286. I2C_TxByte(nAddr);
  287. // 等待 ACK
  288. nTemp = I2C_GetACK();
  289. if(nTemp & BIT3) return 0;
  290. // 启动数据总线
  291. I2C_START();
  292. // 发送控制字节
  293. nTemp = 0xA1;
  294. I2C_TxByte(nTemp);
  295. // 等待 ACK
  296. nTemp = I2C_GetACK();
  297. if(nTemp & BIT3) return 0;
  298. //读取数据
  299. for(i = 0; i < nLen; i++)
  300. {
  301. //读一个字节数据
  302. nValue[i] = I2C_RxByte();
  303. //发送ACK
  304. I2C_SetACK();
  305. }    
  306. // 停止总线
  307. I2C_STOP();
  308. //成功返回
  309. return 1;
  310. }
  311. void Delay_ms(unsigned long nValue)//毫秒为单位,8MHz为主时钟
  312. {
  313.     unsigned long nCount;
  314.     int i;
  315.     unsigned long j;
  316.     nCount = 2667;
  317.     for(i = nValue;i > 0;i--)
  318.     {
  319.      for(j = nCount;j > 0;j--);
  320.     }
  321.     return;
  322. }
  323. void Delay_us(unsigned long nValue)//微秒为单位,8MHz为主时钟
  324. {
  325.     int nCount;
  326.     int i;
  327.     int j;
  328.     nCount = 3;
  329.     for(i = nValue;i > 0;i--)
  330.     {
  331.      for(j = nCount;j > 0;j--);
  332.     }
  333.     return;
  334. }
  335. void Init_CLK(void)
  336. {
  337.     unsigned int i;
  338.     BCSCTL1 = 0X00; //将寄存器的内容清零
  339. //XT2震荡器开启
  340. //LFTX1工作在低频模式
  341. //ACLK的分频因子为1
  342.     do 
  343.     {
  344. // 清除OSCFault标志
  345.     IFG1 &= ~OFIFG;    
  346.     for (i = 0x20; i > 0; i--);                
  347.     }
  348.     while ((IFG1 & OFIFG) == OFIFG);// 如果OSCFault =1   
  349. //将寄存器的内容清零
  350.     BCSCTL2 = 0X00;
  351. //MCLK的时钟源为TX2CLK,分频因子为1
  352.     BCSCTL2 += SELM1;
  353. //SMCLK的时钟源为TX2CLK,分频因子为1
  354.     BCSCTL2 += SELS;
  355. }