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

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