当前位置:   article > 正文

蓝桥杯第十三届单片机国赛程序_第十三届蓝桥杯程序题

第十三届蓝桥杯程序题

写在前面:做完总体来说感觉一年比一年难了(估计是被骂的),虽然十三届用的底层少,但是做起来困难重重。

最难的难点在于定时器安排问题。15F2K60S2系列单片机只有三个定时器,本届题目考到了频率测量、超声波、PWM输出,再加上刷新,每一个都需要一个定时器,比较简单的做法之一是直接用单片机外设PCA来检测超声波,节省定时器资源。(b站上有个up主是切换定时器0计数/定时模式来实现的,这样也可以,但是个人感觉比较麻烦,也容易出现问题)

对于NE555频率测量,要求是P3^4进行脉冲输入,正好是T0输出,所以最好是用定时器0,当然也可以使用其它定时器,这样就需要使用sbit函数定义P3^4引脚,相对比较麻烦。

定时器0:频率计数;定时器1:函数刷新;定时器2:PWM输出。

1、首先是NE555频率测量:

其中TMOD|=0x04为切换定时器为计数模式。

2、其次是PCA实现超声波测量:

(别忘了TX、RX引脚定义)

 

 最后得到的值+3(实际测量在+2.5左右),原因是因为硬件或者程序延时时间等问题有小误差,很多博主和教程里这个地方都有加3,可以自己拿尺子测量一下距离看看是不是这样。

 3、PWM输出

首先看题目:

 首先找到这个电机驱动引脚连接的位置:(不是去找J3哦)

 可以发现它和我们常用的继电器、蜂鸣器在一个地方,这样我们就可以像控制它俩一样控制电机。

输出频率为1khz,那么我们输出信号周期就为1000微秒,分成5份,每份就是200微秒,就可以设置200微秒定时器中断。

 这里每份是200微秒,那么之前我们设置的超声波程序整个过程是24微秒*8=192微秒<200微秒,这样才不会因为关闭中断时间过长造成PWM输出异常。

4、PCF8591

这里我设置采集时关闭中断,完成后才打开,以免影响iic时序。如果不关闭的话,实际采集值会来回跳变(大家可以试一试是不是这样),有的教程和博主教学里面没关,可能是我其它程序设置问题。

注意:设置的外设等刷新时间,应该是满足条件的最大值,以免多次采集造成不良影响。

 自从第十届开始,采取机器阅卷后,就对采集时间等等性能有姚桥,但本届题目并没有和省赛一样设置外设时间刷新要求,原因可能是超声波、频率等等容易冲突的地方太多了,就放宽了条件,所以我们在设置刷新时间,就适当的加长一点。

 

完整题目:

 

 

 

 

 

 

完整程序: 

MAIN.c

  1. #include <Main.h>
  2. #include <IIC.h>
  3. #include "sonic.h"
  4. void Task_Clock(void)
  5. {
  6. Set_HC573(4,LED);
  7. Set_HC573(5,Actuator_Bit);
  8. if(LED_flag==1){if(++LED_tt == 100)
  9. {
  10. LED_tt = 0;
  11. if(LED_Run==1){LED_ON(State3);LED_Run=0;}
  12. else if(LED_Run==0){LED_OFF(State3);LED_Run=1;}}
  13. }
  14. if(++SEG_tt == 50) { SEG_tt = 0; SEG_Ref = 1; }
  15. if(++KEY_tt == 10) { KEY_tt = 0; KeyScan(); }
  16. if(++AD_tt == 300) { AD_tt = 0; AD_Ref = 1; }
  17. if(++LCM_tt == 500) {LCM_tt = 0; LCM_Ref = 1; }
  18. if(++Freq_tt == 1000) {Freq_tt = 0; Freq_Ref = 1; }
  19. }
  20. void main(void)
  21. {
  22. ALL_Init();
  23. if(AT24C02_read(0X64)!=0x80)
  24. {
  25. AT24C02_write(0x64,0x80);Delay_MS(5);
  26. AT24C02_write(0x00,0);Delay_MS(5);
  27. }
  28. else {Cishu = AT24C02_read(0X00); Delay_MS(5);}
  29. LED_ON(1);
  30. AD_read(0X43);
  31. AD_Value = AD_read(0X43);
  32. AD_Value = AD_Value * 1.96;
  33. Timer0Init();
  34. Timer1Init();
  35. Timer2Init();IE2 |= 0X04;
  36. EA = 1; ET1 = 1;
  37. while(1)
  38. {
  39. if(SEG_Ref == 1)
  40. {
  41. SEG_Ref = 0;
  42. SEG_Refresh();
  43. }
  44. if(KEY_Flag == 1)
  45. {
  46. KEY_Flag = 0;
  47. Task_Key();
  48. }
  49. if(AD_Ref == 1)
  50. {
  51. AD_Ref = 0;
  52. AD_Value = AD_read(0X43); //滑动变阻器0X03,光敏电阻0X01
  53. AD_Value = AD_Value * 1.96;
  54. Shidu=0.2*AD_Value;
  55. if(Shidu<=Shidu_para){AD_write(51);LED_OFF(5);}
  56. else if(Shidu>=80){AD_write(255);LED_ON(5);}
  57. else {AD_write((Shidu-80)*4*51/(80-Shidu_para)+5*51);LED_ON(5);}
  58. }
  59. if(LCM_Ref == 1)
  60. {
  61. LCM_Ref = 0;
  62. LCM=Sonic_Measure()+3;
  63. if((LCM>LCM_para*10)&&(LCM_last<=LCM_para*10))
  64. {
  65. Actuator_Bit|=0x10;Cishu=Cishu+1;AT24C02_write(0x00,Cishu);LED_ON(6);
  66. }
  67. else if((LCM>LCM_para*10)&&(LCM_last>LCM_para*10))
  68. {
  69. LED_ON(6);
  70. }
  71. else if(LCM<=LCM_para*10){Actuator_Bit&=~0x10;LED_OFF(6);}
  72. LCM_last=LCM;
  73. }
  74. if(Freq_Ref == 1)
  75. {
  76. Freq_Ref = 0 ;
  77. Freq_Callback_1s();
  78. if(Freq>Freq_para*100)
  79. {
  80. LED_ON(4);
  81. PWM_Deuty_count=4;
  82. }
  83. else
  84. {
  85. LED_OFF(4);
  86. PWM_Deuty_count=1;
  87. }
  88. }
  89. }
  90. }
  91. void Task_Key(void)
  92. {
  93. if(KEY_Value==4)
  94. {
  95. KEY_Value=0;
  96. if(SEG_Show==1){SEG_Show=2;LED_OFF(1);LED_ON(2);}
  97. else if(SEG_Show==2){SEG_Show=3;LED_OFF(2);LED_ON(3);}
  98. else if(SEG_Show==3){SEG_Show=4;LED_OFF(3);State3=1;LED_flag=1;}
  99. else if(SEG_Show==4){SEG_Show=1;LED_flag=0;LED_OFF(State3);LED_ON(1);}
  100. }
  101. if(KEY_Value==5)
  102. {
  103. KEY_Value=0;
  104. if(SEG_Show==4)
  105. {
  106. if(State3==1){State3=2;LED_OFF(1);}
  107. else if(State3==2){State3=3;LED_OFF(2);}
  108. else if(State3==3){State3=1;LED_OFF(3);}
  109. }
  110. }
  111. if(KEY_Value==6){
  112. KEY_Value=0;
  113. if(SEG_Show==4)
  114. {
  115. if(State3==1)
  116. {
  117. Freq_para=Freq_para+5;
  118. if(Freq_para>120)Freq_para=10;
  119. }
  120. else if(State3==2)
  121. {
  122. Shidu_para=Shidu_para+10;
  123. if(Shidu_para>60)Shidu_para=10;
  124. }
  125. else if(State3==3)
  126. {
  127. LCM_para=LCM_para+1;
  128. if(LCM_para>12)LCM_para=1;
  129. }
  130. }
  131. if(SEG_Show==3)
  132. {
  133. if(State2==1)State2=2;
  134. else State2=1;
  135. }
  136. }
  137. if((KEY_Value==7)&&(KEY_Press_TIME<1000))
  138. {
  139. KEY_Value=0;
  140. if(SEG_Show==4)
  141. {
  142. if(State3==1)
  143. {
  144. Freq_para=Freq_para-5;
  145. if(Freq_para<10)Freq_para=120;
  146. }
  147. else if(State3==2)
  148. {
  149. Shidu_para=Shidu_para-10;
  150. if(Shidu_para<10)Shidu_para=60;
  151. }
  152. else if(State3==3)
  153. {
  154. LCM_para=LCM_para-1;
  155. if(LCM_para<1)LCM_para=12;
  156. }
  157. }
  158. if(SEG_Show==1)
  159. {
  160. if(State1==1)State1=2;
  161. else State1=1;
  162. }
  163. }
  164. if((KEY_Value==7)&&(KEY_Press_TIME>=1000))
  165. {
  166. KEY_Value=0;
  167. Cishu=0;
  168. AT24C02_write(0x00,0);
  169. }
  170. }
  171. void SEG_Refresh(void)
  172. {
  173. if(SEG_Show == 1)
  174. {
  175. DigBuf[0] = 22; DigBuf[1] = 21; DigBuf[2] = 21;
  176. if(State1==1)
  177. {
  178. if(Freq>=10000)
  179. {
  180. DigBuf[3]=Freq/10000;
  181. DigBuf[4]=Freq%10000/1000;
  182. DigBuf[5]=Freq%1000/100;
  183. DigBuf[6]=Freq%100/10;
  184. DigBuf[7]=Freq%10;
  185. }
  186. else if((Freq>=1000)&&(Freq<10000))
  187. {
  188. DigBuf[3]=21;
  189. DigBuf[4]=Freq%10000/1000;
  190. DigBuf[5]=Freq%1000/100;
  191. DigBuf[6]=Freq%100/10;
  192. DigBuf[7]=Freq%10;
  193. }
  194. else if((Freq>=100)&&(Freq<1000))
  195. {
  196. DigBuf[3]=21;
  197. DigBuf[4]=21;
  198. DigBuf[5]=Freq%1000/100;
  199. DigBuf[6]=Freq%100/10;
  200. DigBuf[7]=Freq%10;
  201. }
  202. else if((Freq>=10)&&(Freq<100))
  203. {
  204. DigBuf[3]=21;
  205. DigBuf[4]=21;
  206. DigBuf[5]=21;
  207. DigBuf[6]=Freq%100/10;
  208. DigBuf[7]=Freq%10;
  209. }
  210. }
  211. else if(State1==2)
  212. {
  213. DigBuf[3]=21;
  214. DigBuf[4]=21;
  215. if(Freq>=10000)
  216. {
  217. DigBuf[5]=Freq/10000;
  218. DigBuf[6]=Freq/1000%10+10;
  219. DigBuf[7]=Freq/100%10;
  220. }
  221. else if((Freq>=1000)&&(Freq<10000))
  222. {
  223. DigBuf[5]=21;
  224. DigBuf[6]=Freq/1000%10+10;
  225. DigBuf[7]=Freq/100%10;
  226. }
  227. else if((Freq>=100)&&(Freq<1000))
  228. {
  229. DigBuf[5]=21;
  230. DigBuf[6]=10;
  231. DigBuf[7]=Freq/100%10;
  232. }
  233. }
  234. }
  235. else if(SEG_Show == 2)
  236. {
  237. DigBuf[0] = 23; DigBuf[1] = 21;
  238. DigBuf[2] = 21; DigBuf[3] = 21; DigBuf[4] = 21;
  239. DigBuf[5] = 21; DigBuf[6] = Shidu/ 10; DigBuf[7] = Shidu % 10;
  240. }
  241. else if(SEG_Show == 3)
  242. {
  243. DigBuf[0] = 24; DigBuf[1] = 21; DigBuf[2] = 21;
  244. DigBuf[3] = 21; DigBuf[4] = 21;
  245. if(State2==1)
  246. {
  247. if(LCM>=100)
  248. {
  249. DigBuf[5] = LCM/100;
  250. DigBuf[6] = LCM%100/10;
  251. DigBuf[7] = LCM%10;
  252. }
  253. else if((LCM>=10)&&(LCM<100))
  254. {
  255. DigBuf[5] = 21;
  256. DigBuf[6] = LCM%100/10;
  257. DigBuf[7] = LCM%10;
  258. }
  259. else if((LCM>=0)&&(LCM<10))
  260. {
  261. DigBuf[5] = 21;
  262. DigBuf[6] = 21;
  263. DigBuf[7] = LCM%10;
  264. }
  265. }
  266. else if(State2==2)
  267. {
  268. if(LCM>=100)
  269. {
  270. DigBuf[5] = LCM/100+10;
  271. DigBuf[6] = LCM%100/10;
  272. DigBuf[7] = LCM%10;
  273. }
  274. else if((LCM>=10)&&(LCM<100))
  275. {
  276. DigBuf[5] = 10;
  277. DigBuf[6] = LCM%100/10;
  278. DigBuf[7] = LCM%10;
  279. }
  280. else if((LCM>=0)&&(LCM<10))
  281. {
  282. DigBuf[5] = 10;
  283. DigBuf[6] = 0;
  284. DigBuf[7] = LCM%10;
  285. }
  286. }
  287. }
  288. else if(SEG_Show == 4)
  289. {
  290. DigBuf[0]=25;DigBuf[1]=State3;
  291. DigBuf[2]=21;
  292. DigBuf[3]=21;
  293. DigBuf[4]=21;
  294. if(State3==1)
  295. {
  296. if(Freq_para>=100)
  297. {
  298. DigBuf[5]=Freq_para%1000/100;
  299. DigBuf[6]=Freq_para%100/10+10;
  300. DigBuf[7]=Freq_para%10;
  301. }
  302. else
  303. {
  304. DigBuf[5]=21;
  305. DigBuf[6]=Freq_para%100/10+10;
  306. DigBuf[7]=Freq_para%10;
  307. }
  308. }
  309. else if(State3==2)
  310. {
  311. DigBuf[5]=21;
  312. DigBuf[6]=Shidu_para%100/10;
  313. DigBuf[7]=Shidu_para%10;
  314. }
  315. else if(State3==3)
  316. {
  317. DigBuf[5]=21;
  318. DigBuf[6]=LCM_para%100/10+10;
  319. DigBuf[7]=LCM_para%10;
  320. }
  321. }
  322. }
  323. void Delay12us() //@12.000MHz
  324. {
  325. unsigned char i;
  326. _nop_();
  327. _nop_();
  328. i = 33;
  329. while (--i);
  330. }
  331. // 使用PCA模块计时,Sysclk不分频做时钟输入
  332. void Sonic_Init()
  333. {
  334. CMOD = 0x88;
  335. CCON = 0;
  336. CH = 0;
  337. CL = 0;
  338. }
  339. void Sonic_SendTrig()
  340. {
  341. unsigned char i;
  342. // 关中断发驱动波形
  343. EA = 0;
  344. for (i = 0; i < 8; i++) {
  345. TX = 1;
  346. Delay12us();
  347. TX = 0;
  348. Delay12us();
  349. }
  350. EA = 1;
  351. }
  352. unsigned int Sonic_Measure()
  353. {
  354. unsigned char cf = 0;
  355. Sonic_Init();
  356. Sonic_SendTrig();
  357. // 开始计时
  358. CR = 1;
  359. while (RX) {
  360. // 计数器溢出处理
  361. if (CF == 1) {
  362. cf++;
  363. CF = 0;
  364. }
  365. if (cf == 10) {
  366. CR = 0;
  367. return 65535;
  368. }
  369. }
  370. CR = 0;
  371. // (((CH * 256 + CL) * 0.017) / 12:本轮计数的距离
  372. // 92.8427 * cf:溢出计数距离
  373. return (unsigned int ) (((CH * 256 + CL) * 0.017) / 12 + 92.8427 * cf);
  374. }
  375. void KeyScan(void)
  376. {
  377. switch(KeyState)
  378. {
  379. case KEY_Check: if((P30 == 0) || (P31 == 0) || (P32 == 0) || (P33 == 0)) KeyState = KEY_Press;break;
  380. case KEY_Press:
  381. {
  382. if(P30 == 0) KEY_Value = 7;
  383. else if(P31 == 0) KEY_Value = 6;
  384. else if(P32 == 0) KEY_Value = 5;
  385. else if(P33 == 0) KEY_Value = 4;
  386. KeyState = KEY_Release;
  387. KEY_Press_TIME = 10;
  388. }
  389. break;
  390. case KEY_Release:
  391. {
  392. if((P30 == 0) || (P31 == 0) || (P32 == 0) || (P33 == 0))
  393. {
  394. KEY_Press_TIME = KEY_Press_TIME + 10;
  395. }
  396. else
  397. {
  398. KeyState = KEY_Check;
  399. KEY_Flag = 1;
  400. }
  401. }
  402. break;
  403. default: break;
  404. }
  405. }
  406. void Timer2(void) interrupt 12
  407. {
  408. EA=0;
  409. if(PWM_count==0)Actuator_Bit|= 0x20;
  410. else if(PWM_count == PWM_Deuty_count ) { Actuator_Bit&=~0x20; }
  411. else if(PWM_count == 5 ) { PWM_count = 0; Actuator_Bit|= 0x20; }
  412. Set_HC573(5,Actuator_Bit);
  413. EA=1;
  414. PWM_count++;
  415. }
  416. void Timer2Init(void) //200微秒@12.000MHz
  417. {
  418. AUXR |= 0x04; //定时器时钟1T模式
  419. T2L = 0xA0; //设置定时初始值
  420. T2H = 0xF6; //设置定时初始值
  421. AUXR |= 0x10; //定时器2开始计时
  422. }
  423. void Timer1(void) interrupt 3
  424. {
  425. Set_HC573(6,0x00);
  426. Set_HC573(7,tab[DigBuf[DigCom]]);
  427. Set_HC573(6,0x01<<DigCom);
  428. if(++DigCom==8)DigCom=0;
  429. Task_Clock();
  430. }
  431. void Timer1Init(void) //1毫秒@12.000MHz
  432. {
  433. AUXR |= 0x40; //定时器时钟1T模式
  434. TMOD &= 0x0F; //设置定时器模式
  435. TL1 = 0x20; //设置定时初始值
  436. TH1 = 0xD1; //设置定时初始值
  437. TF1 = 0; //清除TF1标志
  438. TR1 = 1; //定时器1开始计时
  439. }
  440. void Timer0Init(void) //@12.000MHz
  441. {
  442. AUXR |= 0x80; //定时器时钟1T模式
  443. TMOD |= 0x04; //设置定时器模式
  444. TL0 = 0x00; //设置定时初始值
  445. TH0 = 0x00; //设置定时初始值
  446. TF0 = 0; //清除TF0标志
  447. }
  448. void Freq_Callback_1s()
  449. {
  450. TR0 = 0;
  451. Freq = TH0 * 256 + TL0;
  452. TL0 = 0x0;
  453. TH0 = 0x0;
  454. TF0 = 0;
  455. TR0 = 1;
  456. }
  457. void All_Init()
  458. {
  459. Set_HC573(5,0x00);
  460. Set_HC573(4,0xff);
  461. Set_HC573(6,0x00);
  462. }
  463. void Set_HC573(unsigned char channel,unsigned char dat)
  464. {
  465. P0=dat;
  466. switch(channel)
  467. {
  468. case 4:
  469. P2=0x80;
  470. break;
  471. case 5:
  472. P2=0xa0;
  473. break;
  474. case 6:
  475. P2=0xc0;
  476. break;
  477. case 7:
  478. P2=0xe0;
  479. break;
  480. }
  481. P2=0;
  482. }
  483. void Delay_MS(unsigned int MS) //@12.000MHz
  484. {
  485. unsigned int k;
  486. unsigned char i, j;
  487. for(k=0;k<MS;k++)
  488. {
  489. i = 12;
  490. j = 169;
  491. do
  492. {
  493. while (--j);
  494. } while (--i);
  495. }
  496. }

MAIN.h程序

  1. #ifndef __MAIN_H__
  2. #define __MAIN_H__
  3. #include <STC15F2K60S2.H>
  4. #include <intrins.h>
  5. sbit TX = P1^0 ;
  6. sbit RX = P1^1 ;
  7. unsigned char LED=0xff;
  8. unsigned char Actuator_Bit = 0X00;
  9. unsigned char code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,\
  10. 0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10,\
  11. 0XBF,0XFF,0x8e,0x89,0x88,0x8c};
  12. #define LED_ON(n) {LED&=~(0x01<<(n-1)); }
  13. #define LED_OFF(n) {LED|=(0x01<<(n-1));}
  14. unsigned char DigCom = 0 ;
  15. unsigned char DigBuf[8] = {21,21,21,21,21,21,21,21};
  16. typedef enum
  17. {
  18. KEY_Check, //检测状态
  19. KEY_Press, //按下状态
  20. KEY_Release, //等待松开状态
  21. Key_Over //按下之后松开,按键结束状态
  22. }KEY_State;
  23. KEY_State KeyState = KEY_Check; //初始设置按键初始化状态为检测状态
  24. unsigned char KEY_Value = 0;
  25. unsigned char KEY_tt = 0; //按键扫描时间计时
  26. unsigned int KEY_Press_TIME = 10; //按键按下时长
  27. bit KEY_Flag = 0; //按键按下又松开之后标识位
  28. unsigned int LED_tt = 0 ;
  29. bit LED_Ref =0;
  30. unsigned int SEG_tt =0;
  31. bit SEG_Ref = 0 ;
  32. unsigned int AD_Value = 0;
  33. unsigned int AD_tt = 0;
  34. bit AD_Ref = 0;
  35. unsigned int LCM_tt = 0 ;
  36. bit LCM_Ref = 0 ;
  37. unsigned int LCM = 0 ;
  38. unsigned int LCM_last=0;
  39. unsigned int xdata PWM_count = 0;
  40. unsigned char xdata PWM_Deuty_count = 0;
  41. unsigned int Freq = 0;
  42. unsigned int Freq_tt = 0;
  43. bit Freq_Ref = 0;
  44. unsigned char SEG_Show = 1 ;
  45. unsigned int Cishu=0;
  46. unsigned char State1=1;
  47. unsigned char State2=1;
  48. unsigned char State3=1;
  49. unsigned char Shidu=0;
  50. unsigned char Freq_para=90;
  51. unsigned char Shidu_para=40;
  52. unsigned char LCM_para=6;
  53. bit LED_flag=0;
  54. bit LED_Run=0;
  55. void Delay_MS(unsigned int MS);
  56. void Set_HC573(unsigned char channel,unsigned char dat);
  57. void ALL_Init(void);
  58. void Timer0Init(void); //1毫秒@12.000MHz
  59. void KeyScan(void);
  60. void Task_Clock(void);
  61. void SEG_Refresh(void);
  62. void Task_Key(void);
  63. void Delay12us(); //@12.000MHz
  64. void Timer1Init(void); //10微秒@12.000MHz
  65. void Sonic_Init() ;
  66. void Sonic_SendTrig() ;
  67. void Freq_Callback_1s() ;
  68. void Timer2Init();
  69. #endif

IIC.c程序

  1. #include <STC15F2K60S2.H>
  2. #include "intrins.h"
  3. //总线引脚定义
  4. sbit sda = P2^1; /* 数据线 */
  5. sbit scl = P2^0; /* 时钟线 */
  6. #define DELAY_TIME 5
  7. //
  8. static void I2C_Delay(unsigned char n)
  9. {
  10. do
  11. {
  12. _nop_();
  13. // _nop_();_nop_();_nop_();_nop_();
  14. // _nop_();_nop_();_nop_();_nop_();_nop_();
  15. // _nop_();_nop_();_nop_();_nop_();_nop_();
  16. }
  17. while(n--);
  18. }
  19. //
  20. void I2CStart(void)
  21. {
  22. sda = 1;
  23. scl = 1;
  24. I2C_Delay(DELAY_TIME);
  25. sda = 0;
  26. I2C_Delay(DELAY_TIME);
  27. scl = 0;
  28. }
  29. //
  30. void I2CStop(void)
  31. {
  32. sda = 0;
  33. scl = 1;
  34. I2C_Delay(DELAY_TIME);
  35. sda = 1;
  36. I2C_Delay(DELAY_TIME);
  37. }
  38. //
  39. void I2CSendByte(unsigned char byt)
  40. {
  41. unsigned char i;
  42. for(i=0; i<8; i++){
  43. scl = 0;
  44. I2C_Delay(DELAY_TIME);
  45. if(byt & 0x80){
  46. sda = 1;
  47. }
  48. else{
  49. sda = 0;
  50. }
  51. I2C_Delay(DELAY_TIME);
  52. scl = 1;
  53. byt <<= 1;
  54. I2C_Delay(DELAY_TIME);
  55. }
  56. scl = 0;
  57. }
  58. //
  59. unsigned char I2CReceiveByte(void)
  60. {
  61. unsigned char da;
  62. unsigned char i;
  63. for(i=0;i<8;i++){
  64. scl = 1;
  65. I2C_Delay(DELAY_TIME);
  66. da <<= 1;
  67. if(sda)
  68. da |= 0x01;
  69. scl = 0;
  70. I2C_Delay(DELAY_TIME);
  71. }
  72. return da;
  73. }
  74. //
  75. unsigned char I2CWaitAck(void)
  76. {
  77. unsigned char ackbit;
  78. scl = 1;
  79. I2C_Delay(DELAY_TIME);
  80. ackbit = sda;
  81. scl = 0;
  82. I2C_Delay(DELAY_TIME);
  83. return ackbit;
  84. }
  85. //
  86. void I2CSendAck(unsigned char ackbit)
  87. {
  88. scl = 0;
  89. sda = ackbit;
  90. I2C_Delay(DELAY_TIME);
  91. scl = 1;
  92. I2C_Delay(DELAY_TIME);
  93. scl = 0;
  94. sda = 1;
  95. I2C_Delay(DELAY_TIME);
  96. }
  97. unsigned char AT24C02_read(unsigned char add)
  98. {
  99. unsigned char da;
  100. I2CStart();
  101. I2CSendByte(0XA0);
  102. I2CWaitAck();
  103. I2CSendByte(add);
  104. I2CWaitAck();
  105. I2CStop();
  106. I2CStart();
  107. I2CSendByte(0XA1);
  108. I2CWaitAck();
  109. da = I2CReceiveByte();
  110. I2CSendAck(1);
  111. I2CStop();
  112. return da;
  113. }
  114. void AT24C02_write(unsigned char add,unsigned char dat)
  115. {
  116. I2CStart();
  117. I2CSendByte(0xA0);
  118. I2CWaitAck();
  119. I2CSendByte(add);
  120. I2CWaitAck();
  121. I2CSendByte(dat);
  122. I2CWaitAck();
  123. I2CStop();
  124. }
  125. unsigned char AD_read(unsigned char add)
  126. {
  127. unsigned char temp;
  128. EA=0;
  129. I2CStart();
  130. I2CSendByte(0X90);
  131. I2CWaitAck();
  132. I2CSendByte(add);
  133. I2CWaitAck();
  134. I2CStop();
  135. I2CStart();
  136. I2CSendByte(0X91);
  137. I2CWaitAck();
  138. temp=I2CReceiveByte();
  139. I2CSendAck(1);
  140. I2CStop();
  141. EA=1;
  142. return temp;
  143. }
  144. void AD_write(unsigned char dat)
  145. {
  146. EA=0;
  147. I2CStart();
  148. I2CSendByte(0X90);
  149. I2CWaitAck();
  150. I2CSendByte(0X40);
  151. I2CWaitAck();
  152. I2CSendByte(dat);
  153. I2CWaitAck();
  154. I2CStop();
  155. EA=1;
  156. }

IIC.h程序

  1. #ifndef _IIC_H
  2. #define _IIC_H
  3. static void I2C_Delay(unsigned char n);
  4. void I2CStart(void);
  5. void I2CStop(void);
  6. void I2CSendByte(unsigned char byt);
  7. unsigned char I2CReceiveByte(void);
  8. unsigned char I2CWaitAck(void);
  9. void I2CSendAck(unsigned char ackbit);
  10. unsigned char AT24C02_read(unsigned char add);
  11. void AT24C02_write(unsigned char add,unsigned char dat);
  12. unsigned char AD_read(unsigned char add);
  13. void AD_write(unsigned char dat);
  14. #endif

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/369469
推荐阅读
相关标签
  

闽ICP备14008679号