[其他产品] PIC定时器的使用

[复制链接]
794|8
 楼主| peripheral 发表于 2020-8-10 10:17 | 显示全部楼层 |阅读模式

  1.   1 TIM0  查询法使LED一秒闪烁,未使用预分频
  2.   2 #include<pic.h>
  3.   3 #define uint unsigned int
  4.   4 #define uchar unsigned char
  5.   5 #define input  RA3
  6.   6 #define clk  RA5
  7.   7 #define cs_led  RE0
  8.   8 __CONFIG(0x3B31);
  9.   9
  10. 10 void init();
  11. 11 void delay(uint);
  12. 12 void write_164(uchar);
  13. 13 uint intnum1,intnum2;
  14. 14 void main()
  15. 15 {
  16. 16        init();
  17. 17        while(1)
  18. 18        {
  19. 19               if(T0IF==1)//判断中断溢出位是否溢出,TOIF是否溢出和总中断是否开启无关系。
  20. 20               {
  21. 21                      T0IF=0;//需要软件清零
  22. 22                  intnum1++;
  23. 23                      if(intnum1==3906)//一秒钟到了
  24. 24                     {
  25. 25                             intnum1=0;
  26. 26                             intnum2++;
  27. 27                             cs_led=0;
  28. 28                             if(intnum2==1)
  29. 29                             write_164(0xfd);
  30. 30                             if(intnum2==2)
  31. 31                             {
  32. 32                                    intnum2=0;
  33. 33                                    write_164(0xff);
  34. 34                             }
  35. 35                      }                  
  36. 36               }
  37. 37        }
  38. 38 }
  39. 39
  40. 40 void init()
  41. 41 {
  42. 42        TRISA=0b11010111;
  43. 43        TRISE=0b11111110;
  44. 44        OPTION=0x08;//使用内部时钟信号,预分频器分配给WDT模块,相当于不给TM0设置预分频,
  45. 45        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
  46. 46 }
  47. 47 void delay(uint x)
  48. 48 {
  49. 49        uint a,b;
  50. 50        for(a=x;a>0;a--)
  51. 51               for(b=110;b>0;b--);
  52. 52 }
  53. 53
  54. 54 void write_164(uchar dt)
  55. 55 {
  56. 56        uchar i;   
  57. 57        for(i=0;i<8;i++)
  58. 58        {
  59. 59               clk=0;     
  60. 60               if(dt&0x80)
  61. 61                      input=1;
  62. 62               else
  63. 63                      input=0;
  64. 64               dt=dt<<1;                  
  65. 65               clk=1;           
  66. 66        }            
  67. 67 }
  68. 68
  69. 69 TIM0  查询法使LED一秒闪烁,使用预分频
  70. 70 #include<pic.h>
  71. 71 #define uint unsigned int
  72. 72 #define uchar unsigned char
  73. 73 #define input  RA3
  74. 74 #define clk  RA5
  75. 75 #define cs_led  RE0
  76. 76 __CONFIG(0x3B31);
  77. 77
  78. 78 void init();
  79. 79 void delay(uint);
  80. 80 void write_164(uchar);
  81. 81 uint intnum1,intnum2;
  82. 82 void main()
  83. 83 {
  84. 84        init();
  85. 85        while(1)
  86. 86        {
  87. 87               if(T0IF==1)//判断中断溢出位是否溢出,TOIF是否溢出和总中断是否开启无关系。
  88. 88               {
  89. 89                           T0IF=0;//需要软件清零
  90. 90                      TMR0=61;//重新给定时器装初值。
  91. 91                      intnum1++;
  92. 92                      if(intnum1==20)//一秒钟到了
  93. 93                      {
  94. 94                             intnum1=0;
  95. 95                             intnum2++;
  96. 96                             cs_led=0;
  97. 97                             if(intnum2==1)
  98. 98                             write_164(0xfd);
  99. 99                             if(intnum2==2)
  100. 100                             {
  101. 101                                    intnum2=0;
  102. 102                                    write_164(0xff);
  103. 103                             }
  104. 104                      }
  105. 105               }
  106. 106        }
  107. 107 }
  108. 108
  109. 109 void init()
  110. 110 {
  111. 111        TRISA=0b11010111;
  112. 112        TRISE=0b11111110;
  113. 113        OPTION=0x07;//使用内部时钟信号,预分频器分配给TIM0模块,256分频。
  114. 114        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
  115. 115        TMR0=61;//256*Y=50000,=>Y=195,256-195=61,这样就是50ms溢出一次,溢出20次就是1s。
  116. 116 }
  117. 117
  118. 118 void delay(uint x)
  119. 119 {
  120. 120        uint a,b;
  121. 121        for(a=x;a>0;a--)
  122. 122               for(b=110;b>0;b--);
  123. 123 }
  124. 124
  125. 125 void write_164(uchar dt)
  126. 126 {
  127. 127        uchar i;   
  128. 128        for(i=0;i<8;i++)
  129. 129        {
  130. 130               clk=0;     
  131. 131               if(dt&0x80)
  132. 132                      input=1;
  133. 133               else
  134. 134                      input=0;
  135. 135               dt=dt<<1;      
  136. 136               clk=1;           
  137. 137        }            
  138. 138 }
  139. 139
  140. 140 TIM0  中断法使LED一秒闪烁,使用预分频
  141. 141 #include<pic.h>
  142. 142 #define uint unsigned int
  143. 143 #define uchar unsigned char
  144. 144 #define input  RA3
  145. 145 #define clk  RA5
  146. 146 #define cs_led  RE0
  147. 147 __CONFIG(0x3B31);
  148. 148  
  149. 149 void init();
  150. 150 void delay(uint);
  151. 151 void write_164(uchar);
  152. 152 uint intnum1,intnum2;
  153. 153 void main()
  154. 154 {
  155. 155        init();
  156. 156       while(1)
  157. 157        {
  158. 158       if(intnum1==2)//一秒钟到了
  159. 159                      {
  160. 160                             intnum1=0;
  161. 161                             intnum2++;
  162. 162                             cs_led=0;
  163. 163                             if(intnum2==1)
  164. 164                             write_164(0xfd);
  165. 165                             if(intnum2==2)
  166. 166                             {
  167. 167                                    intnum2=0;
  168. 168                                    write_164(0xff);                        
  169. 169                             }                  
  170. 170                      }            
  171. 171        }
  172. 172 }
  173. 173
  174. 174 void init()
  175. 175 {
  176. 176        TRISA=0b11010111;
  177. 177        TRISE=0b11111110;
  178. 178        OPTION=0x07;//使用内部时钟信号,预分频器分配给TIM0模块,256分频。
  179. 179        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
  180. 180        INTCON=0xa0;//GIE=1,开总中断,T0IE=1,开启T0中断,T0IE是TMR0 溢出中断允许位。
  181. 181        TMR0=61;//256*Y=50000,=>Y=195,256-195=61,这样就是50ms溢出一次,溢出20次就是1s。
  182. 182 }
  183. 183
  184. 184 void interrupt time0()
  185. 185
  186. 186 {
  187. 187        T0IF=0;//由于只开启了TMR0中断,所以不用查询是哪个中断,能进来的肯定是TMR0溢出中断,直接将中断溢出标志位清零,
  188. 188        TMR0=61;
  189. 189        intnum1++;
  190. 190 }
  191. 191
  192. 192 void delay(uint x)
  193. 193 {
  194. 194        uint a,b;
  195. 195        for(a=x;a>0;a--)
  196. 196               for(b=110;b>0;b--);
  197. 197 }
  198. 198
  199. 199 void write_164(uchar dt)
  200. 200 {
  201. 201       uchar i;   
  202. 202        for(i=0;i<8;i++)
  203. 203        {
  204. 204               clk=0;            
  205. 205               if(dt&0x80)
  206. 206                      input=1;
  207. 207               else
  208. 208                      input=0;
  209. 209               dt=dt<<1;                          
  210. 210               clk=1;           
  211. 211        }            
  212. 212 }
  213. 213
  214. 214 TMR1 中断法TIM0  中断法使LED一秒闪烁,不设置预分频。
  215. 215 #include<pic.h>
  216. 216 #define uint unsigned int
  217. 217 #define uchar unsigned char
  218. 218 #define input  RA3
  219. 219 #define clk  RA5
  220. 220 #define cs_led  RE0
  221. 221
  222. 222 __CONFIG(0x3B31);
  223. 223
  224. 224  
  225. 225
  226. 226 void init();
  227. 227 void delay(uint);
  228. 228 void write_164(uchar);
  229. 229 uint intnum1,intnum2;
  230. 230 void main()
  231. 231 {
  232. 232        init();
  233. 233        while(1)
  234. 234        {
  235. 235                 if(intnum1==20)//一秒钟到了
  236. 236
  237. 237                      {
  238. 238
  239. 239                             intnum1=0;
  240. 240
  241. 241                             intnum2++;
  242. 242
  243. 243                             cs_led=0;
  244. 244
  245. 245                             if(intnum2==1)
  246. 246
  247. 247                             write_164(0xfd);
  248. 248
  249. 249                             if(intnum2==2)
  250. 250
  251. 251                             {
  252. 252
  253. 253                                    intnum2=0;
  254. 254
  255. 255                                    write_164(0xff);
  256. 256
  257. 257                             
  258. 258
  259. 259                             }                  
  260. 260
  261. 261                      }            
  262. 262
  263. 263        }
  264. 264
  265. 265 }
  266. 266
  267. 267 void init()
  268. 268
  269. 269 {
  270. 270
  271. 271        TRISA=0b11010111;
  272. 272
  273. 273        TRISE=0b11111110;
  274. 274
  275. 275  
  276. 276
  277. 277        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断
  278. 278
  279. 279        PIE1=0x01;//开启定时器1的中断
  280. 280
  281. 281        TMR1L=(65536-50000)%256;
  282. 282
  283. 283        TMR1H=(65536-50000)/256;//进入一次中断,是50ms,
  284. 284
  285. 285  
  286. 286
  287. 287        T1CON=0x01;//不设置预分频,关闭定时器1晶振使能控制位,与外部时钟同步,选择内部时钟,使能定时器1,
  288. 288
  289. 289  
  290. 290
  291. 291 }
  292. 292
  293. 293 void interrupt time1()
  294. 294
  295. 295 {
  296. 296
  297. 297        TMR1IF=0;//将中断溢出标志位清零,
  298. 298
  299. 299        TMR1L=(65536-50000)%256;
  300. 300
  301. 301        TMR1H=(65536-50000)/256;
  302. 302
  303. 303        
  304. 304
  305. 305        intnum1++;
  306. 306
  307. 307 }
  308. 308
  309. 309 void delay(uint x)
  310. 310
  311. 311 {
  312. 312
  313. 313        uint a,b;
  314. 314
  315. 315        for(a=x;a>0;a--)
  316. 316
  317. 317               for(b=110;b>0;b--);
  318. 318
  319. 319  
  320. 320
  321. 321 }
  322. 322
  323. 323 void write_164(uchar dt)
  324. 324
  325. 325 {
  326. 326
  327. 327        uchar i;   
  328. 328
  329. 329        for(i=0;i<8;i++)
  330. 330
  331. 331        {
  332. 332
  333. 333               clk=0;     
  334. 334
  335. 335               
  336. 336
  337. 337               if(dt&0x80)
  338. 338
  339. 339                      input=1;
  340. 340
  341. 341               else
  342. 342
  343. 343                      input=0;
  344. 344
  345. 345               dt=dt<<1;      
  346. 346
  347. 347                     
  348. 348
  349. 349               clk=1;           
  350. 350
  351. 351        }            
  352. 352
  353. 353 }
  354. 354
  355. 355 TMR1 中断法TIM0  中断法使LED400ms闪烁,设置预分频
  356. 356
  357. 357 #include<pic.h>
  358. 358
  359. 359 #define uint unsigned int
  360. 360
  361. 361 #define uchar unsigned char
  362. 362
  363. 363 #define input  RA3
  364. 364
  365. 365 #define clk  RA5
  366. 366
  367. 367 #define cs_led  RE0
  368. 368
  369. 369  
  370. 370
  371. 371 __CONFIG(0x3B31);
  372. 372
  373. 373  
  374. 374
  375. 375 void init();
  376. 376
  377. 377 void delay(uint);
  378. 378
  379. 379 void write_164(uchar);
  380. 380
  381. 381 uint intnum1,intnum2;
  382. 382
  383. 383 void main()
  384. 384
  385. 385 {
  386. 386
  387. 387        init();
  388. 388
  389. 389        while(1)
  390. 390
  391. 391        {
  392. 392
  393. 393        
  394. 394
  395. 395               /*    if(intnum1==20)//一秒钟到了
  396. 396
  397. 397                      {
  398. 398
  399. 399                             intnum1=0;
  400. 400
  401. 401                             intnum2++;
  402. 402
  403. 403                             cs_led=0;
  404. 404
  405. 405                             if(intnum2==1)
  406. 406
  407. 407                             write_164(0xfd);
  408. 408
  409. 409                             if(intnum2==2)
  410. 410
  411. 411                             {
  412. 412
  413. 413                                    intnum2=0;
  414. 414
  415. 415                                    write_164(0xff);
  416. 416
  417. 417                             
  418. 418
  419. 419                             }                  
  420. 420
  421. 421                      }*/         
  422. 422
  423. 423        }
  424. 424
  425. 425 }
  426. 426
  427. 427 void init()
  428. 428
  429. 429 {
  430. 430
  431. 431        TRISA=0b11010111;
  432. 432
  433. 433        TRISE=0b11111110;
  434. 434
  435. 435  
  436. 436
  437. 437        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断
  438. 438
  439. 439        PIE1=0x01;//开启定时器1的中断
  440. 440
  441. 441        TMR1L=(65536-50000)%256;
  442. 442
  443. 443        TMR1H=(65536-50000)/256;//如果不设置预分频,进入一次中断,是50ms,现在设置8倍预分频,进入一次中断是400ms。
  444. 444
  445. 445  
  446. 446
  447. 447        T1CON=0x31;//设置8倍预分频,关闭定时器1晶振使能控制位,与外部时钟同步,选择内部时钟,使能定时器1,
  448. 448
  449. 449  
  450. 450
  451. 451 }
  452. 452
  453. 453 void interrupt time1()
  454. 454
  455. 455 {
  456. 456
  457. 457        TMR1IF=0;//将中断溢出标志位清零,
  458. 458
  459. 459        TMR1L=(65536-50000)%256;
  460. 460
  461. 461        TMR1H=(65536-50000)/256;
  462. 462
  463. 463        
  464. 464
  465. 465        //intnum1++;
  466. 466
  467. 467               intnum2++;
  468. 468
  469. 469                             cs_led=0;
  470. 470
  471. 471                             if(intnum2==1)
  472. 472
  473. 473                             write_164(0xfd);
  474. 474
  475. 475                             if(intnum2==2)
  476. 476
  477. 477                             {
  478. 478
  479. 479                                    intnum2=0;
  480. 480
  481. 481                                    write_164(0xff);
  482. 482
  483. 483                             
  484. 484
  485. 485                             }                  
  486. 486
  487. 487  
  488. 488
  489. 489 }
  490. 490
  491. 491 void delay(uint x)
  492. 492
  493. 493 {
  494. 494
  495. 495        uint a,b;
  496. 496
  497. 497        for(a=x;a>0;a--)
  498. 498
  499. 499               for(b=110;b>0;b--);
  500. 500
  501. 501  
  502. 502
  503. 503 }
  504. 504
  505. 505 void write_164(uchar dt)
  506. 506
  507. 507 {
  508. 508
  509. 509        uchar i;   
  510. 510
  511. 511        for(i=0;i<8;i++)
  512. 512
  513. 513        {
  514. 514
  515. 515               clk=0;     
  516. 516
  517. 517               
  518. 518
  519. 519               if(dt&0x80)
  520. 520
  521. 521                      input=1;
  522. 522
  523. 523               else
  524. 524
  525. 525                      input=0;
  526. 526
  527. 527               dt=dt<<1;      
  528. 528
  529. 529                     
  530. 530
  531. 531               clk=1;           
  532. 532
  533. 533        }            
  534. 534
  535. 535 }
  536. 536
  537. 537 TMR2预分频 后分频      
  538. 538
  539. 539 #include<pic.h>
  540. 540
  541. 541 #define uint unsigned int
  542. 542
  543. 543 #define uchar unsigned char
  544. 544
  545. 545 #define input  RA3
  546. 546
  547. 547 #define clk  RA5
  548. 548
  549. 549 #define cs_led  RE0
  550. 550
  551. 551  
  552. 552
  553. 553 __CONFIG(0x3B31);
  554. 554
  555. 555  
  556. 556
  557. 557 void init();
  558. 558
  559. 559 void delay(uint);
  560. 560
  561. 561 void write_164(uchar);
  562. 562
  563. 563 uint intnum1,intnum2;
  564. 564
  565. 565 void main()
  566. 566
  567. 567 {
  568. 568
  569. 569        init();
  570. 570
  571. 571        while(1)
  572. 572
  573. 573        {
  574. 574
  575. 575        
  576. 576
  577. 577                      if(intnum1==1000)//本来预分频1:1时是200ms到了,现在预分频是4.所以是200*4 ms到了,由于后分频1:2,所以是200*4*2 ms
  578. 578
  579. 579                      {
  580. 580
  581. 581                             intnum1=0;
  582. 582
  583. 583                             intnum2++;
  584. 584
  585. 585                             cs_led=0;
  586. 586
  587. 587                             if(intnum2==1)
  588. 588
  589. 589                             write_164(0xfd);
  590. 590
  591. 591                             if(intnum2==2)
  592. 592
  593. 593                             {
  594. 594
  595. 595                                    intnum2=0;
  596. 596
  597. 597                                    write_164(0xff);
  598. 598
  599. 599                             
  600. 600
  601. 601                             }                  
  602. 602
  603. 603                      }     
  604. 604
  605. 605        }
  606. 606
  607. 607 }
  608. 608
  609. 609 void init()
  610. 610
  611. 611 {
  612. 612
  613. 613        TRISA=0b11010111;
  614. 614
  615. 615        TRISE=0b11111110;
  616. 616
  617. 617  
  618. 618
  619. 619        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断外围功能模块中断
  620. 620
  621. 621        PIE1=0x02;//开启定时器2的中断
  622. 622
  623. 623  
  624. 624
  625. 625        TMR2=56;
  626. 626
  627. 627        T2CON=0x0d;//预分频1:4,使能tmr2计数允许/禁止控制位,预分频1:4后分频1:2,
  628. 628
  629. 629  
  630. 630
  631. 631 }
  632. 632
  633. 633 void interrupt time1()
  634. 634
  635. 635 {
  636. 636
  637. 637        TMR2IF=0;//将中断溢出标志位清零,
  638. 638
  639. 639        TMR2=56;
  640. 640
  641. 641        
  642. 642
  643. 643        intnum1++;
  644. 644
  645. 645                             
  646. 646
  647. 647  
  648. 648
  649. 649 }
  650. 650
  651. 651 void delay(uint x)
  652. 652
  653. 653 {
  654. 654
  655. 655        uint a,b;
  656. 656
  657. 657        for(a=x;a>0;a--)
  658. 658
  659. 659               for(b=110;b>0;b--);
  660. 660
  661. 661  
  662. 662
  663. 663 }
  664. 664
  665. 665 void write_164(uchar dt)
  666. 666
  667. 667 {
  668. 668
  669. 669        uchar i;   
  670. 670
  671. 671        for(i=0;i<8;i++)
  672. 672
  673. 673        {
  674. 674
  675. 675               clk=0;     
  676. 676
  677. 677               
  678. 678
  679. 679               if(dt&0x80)
  680. 680
  681. 681                      input=1;
  682. 682
  683. 683               else
  684. 684
  685. 685                      input=0;
  686. 686
  687. 687               dt=dt<<1;      
  688. 688
  689. 689                     
  690. 690
  691. 691               clk=1;           
  692. 692
  693. 693        }            
  694. 694
  695. 695 }
  696. 696
  697. 697 TMR2预分频 后分频 周期寄存器
  698. 698
  699. 699 #include<pic.h>
  700. 700
  701. 701 #define uint unsigned int
  702. 702
  703. 703 #define uchar unsigned char
  704. 704
  705. 705 #define input  RA3
  706. 706
  707. 707 #define clk  RA5
  708. 708
  709. 709 #define cs_led  RE0
  710. 710
  711. 711  
  712. 712
  713. 713 __CONFIG(0x3B31);
  714. 714
  715. 715  
  716. 716
  717. 717 void init();
  718. 718
  719. 719 void delay(uint);
  720. 720
  721. 721 void write_164(uchar);
  722. 722
  723. 723 uint intnum1,intnum2;
  724. 724
  725. 725 void main()
  726. 726
  727. 727 {
  728. 728
  729. 729        init();
  730. 730
  731. 731        while(1)
  732. 732
  733. 733        {
  734. 734
  735. 735        
  736. 736
  737. 737                      if(intnum1==1000)//本来预分频1:1时是100ms到了,现在预分频是4.所以是100*4 ms到了,由于后分频1:2,所以是100*4*2 ms
  738. 738
  739. 739                      {
  740. 740
  741. 741                             intnum1=0;
  742. 742
  743. 743                             intnum2++;
  744. 744
  745. 745                             cs_led=0;
  746. 746
  747. 747                             if(intnum2==1)
  748. 748
  749. 749                             write_164(0xfd);
  750. 750
  751. 751                             if(intnum2==2)
  752. 752
  753. 753                             {
  754. 754
  755. 755                                    intnum2=0;
  756. 756
  757. 757                                    write_164(0xff);
  758. 758
  759. 759                             
  760. 760
  761. 761                             }                  
  762. 762
  763. 763                      }     
  764. 764
  765. 765        }
  766. 766
  767. 767 }
  768. 768
  769. 769 void init()
  770. 770
  771. 771 {
  772. 772
  773. 773        TRISA=0b11010111;
  774. 774
  775. 775        TRISE=0b11111110;
  776. 776
  777. 777  
  778. 778
  779. 779        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断外围功能模块中断
  780. 780
  781. 781        PIE1=0x02;//开启定时器2的中断
  782. 782
  783. 783  
  784. 784
  785. 785        TMR2=0;
  786. 786
  787. 787        PR2=100;//周期寄存器
  788. 788
  789. 789        T2CON=0x0d;//预分频1:4,使能tmr2计数允许/禁止控制位,预分频1:4后分频1:2,
  790. 790
  791. 791  
  792. 792
  793. 793 }
  794. 794
  795. 795 void interrupt time1()
  796. 796
  797. 797 {
  798. 798
  799. 799        TMR2IF=0;//将中断溢出标志位清零,
  800. 800
  801. 801        //TMR2=56;
  802. 802
  803. 803        
  804. 804
  805. 805        intnum1++;
  806. 806
  807. 807                             
  808. 808
  809. 809  
  810. 810
  811. 811 }
  812. 812
  813. 813 void delay(uint x)
  814. 814
  815. 815 {
  816. 816
  817. 817        uint a,b;
  818. 818
  819. 819        for(a=x;a>0;a--)
  820. 820
  821. 821               for(b=110;b>0;b--);
  822. 822
  823. 823  
  824. 824
  825. 825 }
  826. 826
  827. 827 void write_164(uchar dt)
  828. 828
  829. 829 {
  830. 830
  831. 831        uchar i;   
  832. 832
  833. 833        for(i=0;i<8;i++)
  834. 834
  835. 835        {
  836. 836
  837. 837               clk=0;     
  838. 838
  839. 839               
  840. 840
  841. 841               if(dt&0x80)
  842. 842
  843. 843                      input=1;
  844. 844
  845. 845               else
  846. 846
  847. 847                      input=0;
  848. 848
  849. 849               dt=dt<<1;      
  850. 850
  851. 851                     
  852. 852
  853. 853               clk=1;           
  854. 854
  855. 855        }            
  856. 856
  857. 857 }


 楼主| peripheral 发表于 2020-8-10 10:18 | 显示全部楼层
PIC定时程序

  1 TIM0  查询法使LED一秒闪烁,未使用预分频
  2 #include<pic.h>
  3 #define uint unsigned int
  4 #define uchar unsigned char
  5 #define input  RA3
  6 #define clk  RA5
  7 #define cs_led  RE0
  8 __CONFIG(0x3B31);
  9
10 void init();
11 void delay(uint);
12 void write_164(uchar);
13 uint intnum1,intnum2;
14 void main()
15 {
16        init();
17        while(1)
18        {
19             if(T0IF==1)//判断中断溢出位是否溢出,TOIF是否溢出和总中断是否开启无关系。
20               {
21                      T0IF=0;//需要软件清零
22                      intnum1++;
23                      if(intnum1==3906)//一秒钟到了
24                      {
25                             intnum1=0;
26                             intnum2++;
27                             cs_led=0;
28                             if(intnum2==1)
29                             write_164(0xfd);
30                             if(intnum2==2)
31                             {
32                                   intnum2=0;
33                                    write_164(0xff);                          
34                             }                  
35                      }                     
36               }
37        }
38 }
39
40 void init()
41 {
42        TRISA=0b11010111;
43        TRISE=0b11111110;
44        OPTION=0x08;//使用内部时钟信号,预分频器分配给WDT模块,相当于不给TM0设置预分频,
45        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
46 }
47
48 void delay(uint x)
49 {
50        uint a,b;
51        for(a=x;a>0;a--)
52               for(b=110;b>0;b--);
53 }
54
55 void write_164(uchar dt)
56 {
57        uchar i;   
58        for(i=0;i<8;i++)
59        {
60               clk=0;                  
61               if(dt&0x80)
62                      input=1;
63               else
64                      input=0;
65               dt=dt<<1;                           
66               clk=1;           
67        }            
68 }
69
70 TIM0  查询法使LED一秒闪烁,使用预分频
71 #include<pic.h>
72 #define uint unsigned int
73 #define uchar unsigned char
74 #define input  RA3
75 #define clk  RA5
76 #define cs_led  RE0  
77 __CONFIG(0x3B31);
78 void init();
79 void delay(uint);
80 void write_164(uchar);
81 uint intnum1,intnum2;
82 void main()
83 {
84        init();
85        while(1)
86        {            
87               if(T0IF==1)//判断中断溢出位是否溢出,TOIF是否溢出和总中断是否开启无关系。
88               {
89                      T0IF=0;//需要软件清零
90                      TMR0=61;//重新给定时器装初值。
91                      intnum1++;
92                      if(intnum1==20)//一秒钟到了
93                      {
94                             intnum1=0;
95                             intnum2++;
96                             cs_led=0;
97                             if(intnum2==1)
98                                        write_164(0xfd);
99                             if(intnum2==2)
100                             {
101                                   intnum2=0;
102                                    write_164(0xff);                           
103                             }
104                   }
105               }
106        }
107 }
108
109 void init()
110 {
111        TRISA=0b11010111;
112        TRISE=0b11111110;
113        OPTION=0x07;//使用内部时钟信号,预分频器分配给TIM0模块,256分频。
114        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
115        TMR0=61;//256*Y=50000,=>Y=195,256-195=61,这样就是50ms溢出一次,溢出20次就是1s。
116 }
117
118 void delay(uint x)
119 {
120        uint a,b;
121        for(a=x;a>0;a--)
122               for(b=110;b>0;b--);
123 }
124
125 void write_164(uchar dt)
126 {
127        uchar i;   
128        for(i=0;i<8;i++)
129        {
130               clk=0;               
131               if(dt&0x80)
132                      input=1;
133               else
134                      input=0;
135               dt=dt<<1;                           
136               clk=1;           
137        }            
138 }
139
140 TIM0  中断法使LED一秒闪烁,使用预分频
141 #include<pic.h>
142 #define uint unsigned int
143 #define uchar unsigned char
144 #define input  RA3
145 #define clk  RA5
146 #define cs_led  RE0
147 __CONFIG(0x3B31);
148
149 void init();
150 void delay(uint);
151 void write_164(uchar);
152 uint intnum1,intnum2;
153 void main()
154 {
155        init();
156        while(1)
157        {
158                      if(intnum1==2)//一秒钟到了
159                      {
160                             intnum1=0;
161                             intnum2++;
162                             cs_led=0;
163                             if(intnum2==1)
164                             write_164(0xfd);
165                             if(intnum2==2)
166                             {
167                                   intnum2=0;
168                                    write_164(0xff);                           
169                             }                  
170
171                      }            
172        }
173 }
174
175 void init()
176 {
177        TRISA=0b11010111;
178        TRISE=0b11111110;
179        OPTION=0x07;//使用内部时钟信号,预分频器分配给TIM0模块,256分频。
180        //一个时钟周期是一秒,当不装初值时,256微秒之后溢出,因为时8位定时器。
181        INTCON=0xa0;//GIE=1,开总中断,T0IE=1,开启T0中断,T0IE是TMR0 溢出中断允许位。
182        TMR0=61;//256*Y=50000,=>Y=195,256-195=61,这样就是50ms溢出一次,溢出20次就是1s。
183 }
184
185 void interrupt time0()
186 {
187        T0IF=0;//由于只开启了TMR0中断,所以不用查询是哪个中断,能进来的肯定是TMR0溢出中断,直接将中断溢出标志位清零,
188        TMR0=61;
189        intnum1++;
190 }
191
192 void delay(uint x)
193 {
194        uint a,b;
195        for(a=x;a>0;a--)
196               for(b=110;b>0;b--);
197 }
198
199 void write_164(uchar dt)
200 {
201        uchar i;   
202        for(i=0;i<8;i++)
203        {
204               clk=0;                 
205              if(dt&0x80)
206                      input=1;
207               else
208                      input=0;
209               dt=dt<<1;                           
210               clk=1;           
211        }            
212 }
213
214 TMR1 中断法TIM0  中断法使LED一秒闪烁,不设置预分频。
215 #include<pic.h>
216 #define uint unsigned int
217 #define uchar unsigned char
218 #define input  RA3
219 #define clk  RA5
220 #define cs_led  RE0
221 __CONFIG(0x3B31);
222
223  
224
225 void init();
226 void delay(uint);
227 void write_164(uchar);
228 uint intnum1,intnum2;
229 void main()
230 {
231        init();
232        while(1)
233        {     
234                      if(intnum1==20)//一秒钟到了
235                      {
236                             intnum1=0;
237                             intnum2++;
238                             cs_led=0;
239                             if(intnum2==1)
240                                         write_164(0xfd);
241                             if(intnum2==2)
242                             {
243                                    intnum2=0;
244                                    write_164(0xff);                        
245                             }                  
246                      }            
247        }
248 }
249
250 void init()
251 {
252        TRISA=0b11010111;
253        TRISE=0b11111110;
254        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断
255        PIE1=0x01;//开启定时器1的中断
256        TMR1L=(65536-50000)%256;
257        TMR1H=(65536-50000)/256;//进入一次中断,是50ms,
258        T1CON=0x01;//不设置预分频,关闭定时器1晶振使能控制位,与外部时钟同步,选择内部时钟,使能定时器1,
259 }
260
261 void interrupt time1()
262 {
263        TMR1IF=0;//将中断溢出标志位清零,
264        TMR1L=(65536-50000)%256;
265        TMR1H=(65536-50000)/256;      
266        intnum1++;
267 }
268
269 void delay(uint x)
270 {
271        uint a,b;
272        for(a=x;a>0;a--)
273               for(b=110;b>0;b--);
274 }
275
276 void write_164(uchar dt)
277 {
278        uchar i;   
279        for(i=0;i<8;i++)
280        {
281               clk=0;               
282               if(dt&0x80)
283                     input=1;
284               else
285                      input=0;
286               dt=dt<<1;                           
287               clk=1;           
288        }            
289 }
290
291 TMR1 中断法TIM0  中断法使LED400ms闪烁,设置预分频
292 #include<pic.h>
293 #define uint unsigned int
294 #define uchar unsigned char
295 #define input  RA3
296 #define clk  RA5
297 #define cs_led  RE0
298 __CONFIG(0x3B31);
299
300 void init();
301 void delay(uint);
302 void write_164(uchar);
303 uint intnum1,intnum2;
304 void main()
305 {
306        init();
307        while(1)
308        {                  
309               /*    if(intnum1==20)//一秒钟到了
310                    {
311                             intnum1=0;                                                
312                             intnum2++;
313                             cs_led=0;
314                             if(intnum2==1)
315                             write_164(0xfd);
316                             if(intnum2==2)
317                             {
318                                   intnum2=0;
319                                    write_164(0xff);                           
320                             }                  
321                      }*/         
322        }
323 }
324
325 void init()
326 {
327        TRISA=0b11010111;
328        TRISE=0b11111110;
329        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断
330        PIE1=0x01;//开启定时器1的中断
331        TMR1L=(65536-50000)%256;
332        TMR1H=(65536-50000)/256;//如果不设置预分频,进入一次中断,是50ms,现在设置8倍预分频,进入一次中断是400ms。
333        T1CON=0x31;//设置8倍预分频,关闭定时器1晶振使能控制位,与外部时钟同步,选择内部时钟,使能定时器1,
334 }
335
336 void interrupt time1()
337 {
338        TMR1IF=0;//将中断溢出标志位清零,
339        TMR1L=(65536-50000)%256;
340        TMR1H=(65536-50000)/256;      
341        //intnum1++;
342         intnum2++;
343        cs_led=0;
344         if(intnum2==1)
345              write_164(0xfd);
346          if(intnum2==2)
347             {
348                    intnum2=0;
349                    write_164(0xff);           
350             }                  
351 }
352
353 void delay(uint x)
354 {
355        uint a,b;
356        for(a=x;a>0;a--)
357               for(b=110;b>0;b--);
358 }
359
360 void write_164(uchar dt)
361 {
362        uchar i;   
363        for(i=0;i<8;i++)
364        {                           
365               clk=0;                  
366               if(dt&0x80)
367                      input=1;
368               else                    
369                      input=0;
370               dt=dt<<1;                           
371               clk=1;           
372        }            
373 }
374
375 TMR2预分频 后分频      
376 #include<pic.h>
377 #define uint unsigned int
378 #define uchar unsigned char
379 #define input  RA3
380 #define clk  RA5
381 #define cs_led  RE0
382 __CONFIG(0x3B31);
383
384 void init();
385 void delay(uint);
386 void write_164(uchar);
387 uint intnum1,intnum2;
388 void main()
389 {      
390        init();
391        while(1)
392        {      
393                      if(intnum1==1000)//本来预分频1:1时是200ms到了,现在预分频是4.所以是200*4 ms到了,由于后分频1:2,所以是200*4*2 ms
394                      {
395                             intnum1=0;
396                             intnum2++;
397                             cs_led=0;
398                             if(intnum2==1)
399                             write_164(0xfd);
400                             if(intnum2==2)
401                             {                                 
402                                    intnum2=0;
403                                            write_164(0xff);
404                             }                  
405                      }     
406        }
407 }
408
409 void init()
410 {
411        TRISA=0b11010111;
412        TRISE=0b11111110;
413        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断外围功能模块中断
414        PIE1=0x02;//开启定时器2的中断
415        TMR2=56;
416        T2CON=0x0d;//预分频1:4,使能tmr2计数允许/禁止控制位,预分频1:4后分频1:2,
417 }
418
419 void interrupt time1()
420 {
421        TMR2IF=0;//将中断溢出标志位清零,
422        TMR2=56;      
423        intnum1++;                           
424 }
425
426 void delay(uint x)
427 {
428        uint a,b;
429        for(a=x;a>0;a--)
430               for(b=110;b>0;b--);
431 }
432
433 void write_164(uchar dt)
434 {
435        uchar i;   
436        for(i=0;i<8;i++)
437        {
438               clk=0;            
439               if(dt&0x80)
440                      input=1;
441               else
442                      input=0;
443               dt=dt<<1;                           
444               clk=1;           
445        }            
446 }
447 TMR2预分频 后分频 周期寄存器
448 #include<pic.h>
449 #define uint unsigned int
450 #define uchar unsigned char
451 #define input  RA3
452 #define clk  RA5
453 #define cs_led  RE0
454 __CONFIG(0x3B31);
455 void init();
456 void delay(uint);
457 void write_164(uchar);
458 uint intnum1,intnum2;
459 void main()
460 {
461        init();
462        while(1)
463        {     
464                      if(intnum1==1000)//本来预分频1:1时是100ms到了,现在预分频是4.所以是100*4 ms到了,由于后分频1:2,所以是100*4*2 ms
465                      {
466                             intnum1=0;
467                             intnum2++;
468                             cs_led=0;
469                             if(intnum2==1)
470                                     write_164(0xfd);
471                             if(intnum2==2)
472                             {
473                                    intnum2=0;
474                                    write_164(0xff);                          
475                             }                  
476                      }     
477        }
478 }
479
480 void init()
481 {
482        TRISA=0b11010111;
483        TRISE=0b11111110;
484        INTCON=0xc0;//GIE=1,开总中断,开启第一外设中断外围功能模块中断
485        PIE1=0x02;//开启定时器2的中断
486        TMR2=0;
487        PR2=100;//周期寄存器
488        T2CON=0x0d;//预分频1:4,使能tmr2计数允许/禁止控制位,预分频1:4后分频1:2?
489 }
490
491 void interrupt time1()
492 {
493        TMR2IF=0;//将中断溢出标志位清零,
494        //TMR2=56;      
495        intnum1++;                           
496 }
497
498 void delay(uint x)
499 {
500        uint a,b;
501        for(a=x;a>0;a--)
502               for(b=110;b>0;b--);
503 }
504
505 void write_164(uchar dt)
506 {
507        uchar i;   
508        for(i=0;i<8;i++)
509        {
510               clk=0;                  
511               if(dt&0x80)
512                      input=1;
513               else
514                     input=0;
515               dt=dt<<1;                           
516               clk=1;           
517        }            
518 }
 楼主| peripheral 发表于 2020-8-10 10:18 | 显示全部楼层
所谓定时功能就是通过来自单片机内部的时钟脉冲作计数脉冲,使计数器计数,即每个机器周期计数器加1 ,计数值达到予置值后,定时/计数模块产生溢出。

所谓计数是指对外部事件进行计数。外部事件的发生以输入脉冲表示,因此计数功能的实质就是对外来脉冲进行计数。
 楼主| peripheral 发表于 2020-8-10 10:19 | 显示全部楼层
定时器/ 计数器TMR0 模块的定时工作方式

  对8 位定时器TMR0 来说,不使用分频器时,定时时间的计算公式为:(28 -计数初值)×指令周期

  使用分频器时,定时时间的计算公式为:分频比×(28-计数初值) ×指令周期;分频比取值为2 、4 、8…256。
 楼主| peripheral 发表于 2020-8-10 10:20 | 显示全部楼层
定时器/ 计数器TMR0 模块的定时工作方式

  对8 位定时器TMR0 来说,不使用分频器时,定时时间的计算公式为:(28 -计数初值)×指令周期

  使用分频器时,定时时间的计算公式为:分频比×(28-计数初值) ×指令周期;分频比取值为2 、4 、8…256。
 楼主| peripheral 发表于 2020-8-10 10:20 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| peripheral 发表于 2020-8-10 10:21 | 显示全部楼层
首先强调的是TMR1可以被禁止工作,以降低能耗。要关闭定时/计数模块T M R 1只要将 T M R 1使能位 TMR1ON清0 ,“ 与” 门G1的一个引脚被低电平封锁,就使得累加计数器保持静止状态。对16位定时器TMR1 来说,如选择内部时钟源,则定时时间的计算公式为:

         分频比×(216– 计数初值)  ×指令周期。分频比取值为1 、2 、4、8 。
 楼主| peripheral 发表于 2020-8-10 10:21 | 显示全部楼层
定时器TMR2模块只有一种工作方式,即定时器工作方式.时钟信
号由内部系统时钟4分频后获取,即取自指令周期信号.
(1)用作周期可调的时基发生器:如指令周期为T,分频比为P1,周期寄存器预赋值为PR2 ,则该周期的计算式为:TTMR2=T×P1×(PR2+1)。

(2)用作延时可调的周期性定时器:如指令周期为T,预分频比为P ,周期寄存器预赋值为PR2 ,后分频比为P2,则该超时溢出周期为:TTMR2IF=T×P1×(PR2+1)×P2
(3)用作普通定时器:如指令周期为T,预分频比为P1,则定时时间为P1×(28-X)×T   (以PIC16F877A为例进行的说明)
 楼主| peripheral 发表于 2020-8-10 10:22 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

438

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部