本人初学PIC单片机,写了一个数码管动态扫描的小程序。

[复制链接]
 楼主| 发表于 2012-9-5 10:57 | 显示全部楼层 |阅读模式
PS:RA3端口的秒显正常显示,但是数码管显示有问题,百思不得其解,望各位大侠帮助!注:附件是仿真图

  1. #include<pic.h>
  2. #include<math.h>
  3. #include<stdio.h>

  4. __CONFIG(0xe0f1); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡

  5. #define data164 RA4
  6. #define clk164 RA5

  7. #define uchar unsigned char
  8. #define uint unsigned int

  9. #define _nop_() asm("nop")

  10. #define LED RA3

  11. uchar count_10ms=0;
  12. uchar const bit_tab[]={0x80,0x40,0x20,0x01,0x08,0x04,0x02,0x01,0};//位选表,用来选择哪一只数码管进行显示
  13. uchar const seg_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段选表,共阴数码显示码值
  14. uchar disbuf[6]; //定义显示缓冲单元


  15. /******函数定义**************/
  16. void sendbyte1(char byte);
  17. void sendbyte2(char byte);
  18. void conv(int tmp_s,int humi_s);
  19. void display();

  20. /********端口设置函数********/
  21. void port_init( )
  22. {
  23. TRISA=0x07;
  24. TRISB=0x06;
  25. TRISC =0x00; //端口C输出,位选
  26. ADCON1=0x06; //定义RA为IO端口
  27. ANSEL=0x00;
  28. ANSELH=0x00;
  29. }

  30. /*****************显示函数***********************/
  31. void sendbyte1(char byte)
  32. {
  33. unsigned char c;
  34. for(c=0;c<8;c++)
  35. {
  36. if(byte&0x80)
  37. data164=1;
  38. else data164=0;
  39. clk164=0;
  40. _nop_();
  41. clk164=1;
  42. byte<<=1;
  43. }
  44. }

  45. void sendbyte2(char byte)
  46. {
  47. unsigned char c;
  48. for(c=0;c<16;c++)
  49. {
  50. if(byte&0x80)
  51. data164=1;
  52. else data164=0;
  53. clk164=0;
  54. _nop_();
  55. clk164=1;
  56. byte<<=1;
  57. }
  58. }

  59. void conv(int tmp_s,int humi_s)
  60. {
  61. disbuf[0]=tmp_s/100;
  62. disbuf[1]=tmp_s%100/10;
  63. disbuf[2]=tmp_s%10;
  64. disbuf[3]=humi_s/100;
  65. disbuf[4]=humi_s%100/10;
  66. disbuf[5]=humi_s%10;
  67. }

  68. void display()
  69. {
  70. static uchar count=0;
  71. PORTC=bit_tab[8];
  72. switch(count)
  73. {
  74. case 0:sendbyte1(seg_data[disbuf[0]]); PORTC=bit_tab[4];break;
  75. case 1:sendbyte1(seg_data[disbuf[1]]); PORTC=bit_tab[5];break;
  76. case 2:sendbyte1(seg_data[disbuf[2]]); PORTC=bit_tab[6];break;
  77. case 3:sendbyte2(seg_data[disbuf[3]]); PORTC=bit_tab[4];break;
  78. case 4:sendbyte2(seg_data[disbuf[4]]); PORTC=bit_tab[5];break;
  79. case 5:sendbyte2(seg_data[disbuf[5]]); PORTC=bit_tab[6];break;
  80. }
  81. count++;
  82. if(count==6) count=0;
  83. }

  84. /*********定时器0/定时器1初始化函数********/
  85. void timer_init()
  86. {
  87. GIE=1; //开总中断
  88. PEIE=1; //开外围功能模块中断
  89. T0CS=0; //定时器0对内部时钟计数
  90. PSA=0; //分频器分配给TRM0
  91. PS0=1;
  92. PS1=1;
  93. PS2=1; //定时器0分频比为1:256
  94. T0IE=1; //允许TMR0溢出中断
  95. TMR0=248; //TMR0赋初值,定时2ms
  96. T1CKPS0=1;T1CKPS1=1; //定时器1分频比为1:8
  97. TMR1CS=0; //定时器1设置为定时功能
  98. TMR1IE=1; //使能定时器1中断
  99. TMR1ON=1; //启动定时器1
  100. TMR1H=0xfb; //置计数值高位,定时时间为10ms
  101. TMR1L=0x1e; //置计数值低位
  102. }

  103. /********中断服务程序********/
  104. void interrupt ISR(void)
  105. {
  106. if (TMR0IF==1)
  107. {
  108. TMR0IF=0; //清TMR1溢出中断标志位
  109. TMR0=248; //TMR0赋初值,定时2ms
  110. display(); //调显示函数
  111. }
  112. if (TMR1IF==1)
  113. {
  114. TMR1IF=0; //清TMR1溢出中断标志位
  115. TMR1H=0xfb; //重置计数值,定时时间为10ms
  116. TMR1L=0x1e; //重置计数值
  117. count_10ms++; //10ms计数器加1
  118. if(count_10ms>=100)
  119. {
  120. LED=~LED;
  121. count_10ms = 0; //计数100次后恰好为1s,此时10ms计数器清零
  122. }
  123. }
  124. }


  125. /*************************主函数****************************/
  126. void main( )
  127. {
  128. port_init();
  129. LED=1;
  130. timer_init(); //调定时器T0、T1初始化函数
  131. while(1)
  132. {
  133. conv(123,456); //调走时转换函数
  134. }
  135. }

本帖子中包含更多资源

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

×
发表于 2012-9-5 11:55 | 显示全部楼层
if (TMR0IF==1)
if (TMR1IF==1)
这两行有问题,在PIC中判断中断源必须和中断容许位一起判断才行。

例如:if(TMR0IE&&TMR0IF){}
 楼主| 发表于 2012-9-5 12:28 | 显示全部楼层
2# yewuyi 还有一个问题是74HC164级联显示两个数码管的问题,一个164发送数据我知道怎么处理如:
  • void sendbyte1(char byte)
  • {
  • unsigned char c;
  • for(c=0;c<8;c++)
  • {
  • if(byte&0x80)
  • data164=1;
  • else data164=0;
  • clk164=0;
  • _nop_();
  • clk164=1;
  • byte<<=1;
  • }
  • }
,但是多个一起是怎么处理发送数据的呐?不知道我源程序中那样写对不对?请指教?
发表于 2012-9-5 13:46 | 显示全部楼层
2# yewuyi  还有一个问题是74HC164级联显示两个数码管的问题,一个164发送数据我知道怎么处理如: void sendbyte1(char byte) { unsigned char c; for(c=0;c
xppx1987 发表于 2012-9-5 12:28


1个发送8次移位,两个发送16次移位
发表于 2012-9-5 20:16 | 显示全部楼层
if (TMR0IF==1)
if (TMR1IF==1)
这两行有问题,在PIC中判断中断源必须和中断容许位一起判断才行。

例如:if(TMR0IE&&TMR0IF){}
yewuyi 发表于 2012-9-5 11:55


终于抓到斑竹一个小尾巴,PIC16里面只有Timer0才需要这样,Timer1是可以STOP的。
发表于 2012-9-6 08:58 | 显示全部楼层
终于抓到斑竹一个小尾巴,PIC16里面只有Timer0才需要这样,Timer1是可以STOP的。
NE5532 发表于 2012-9-5 20:16



你讲讲,俺还真没发现哪里说错了呢。
发表于 2012-9-6 10:01 | 显示全部楼层
Timer1可以STOP的,STOP了就不会产生IF标志了。
 楼主| 发表于 2012-9-6 11:06 | 显示全部楼层
4# yewuyi 版主老师,好像不需要这样,程序最后验证通过了,最后发现了问题是RA4脚直接连74ls164的数据端,而RA4输出时必须接一个上拉电阻才可以输出高电平。
 楼主| 发表于 2012-9-6 11:08 | 显示全部楼层
7# NE5532 小弟也不是很清楚需不需要这样,不过最后程序验证通过了,定时扫描功能也实现了,是RA4端口接164端口的问题
发表于 2012-9-6 15:06 | 显示全部楼层
Timer1可以STOP的,STOP了就不会产生IF标志了。
NE5532 发表于 2012-9-6 10:01


他那个代码里面T1一直没有被关闭
发表于 2012-9-6 15:15 | 显示全部楼层
;P但是你回帖说的是“在PIC中”而不是在他的代码中哈。
发表于 2012-9-6 15:50 | 显示全部楼层
各种小辫各种牛角~:lol
发表于 2012-9-6 16:13 | 显示全部楼层
这个不算牛角吧,T0就必须这样判断了。我就在上面遭过的。
发表于 2012-9-6 16:34 | 显示全部楼层
;P但是你回帖说的是“在PIC中”而不是在他的代码中哈。
NE5532 发表于 2012-9-6 15:15


:L ,口误口误。。。
 楼主| 发表于 2012-9-6 16:59 | 显示全部楼层
14# yewuyi 但是奇怪的是程序最后通过了,我没有按版主老师这样修改,只是将74ls164的数据端从RA4改到其他IO口就行,定时功能也实现了啊?不解?
发表于 2012-9-6 17:48 | 显示全部楼层
14# yewuyi  但是奇怪的是程序最后通过了,我没有按版主老师这样修改,只是将74ls164的数据端从RA4改到其他IO口就行,定时功能也实现了啊?不解?
xppx1987 发表于 2012-9-6 16:59


不这么写可能会出错,但未必会一定出错,如果你有足够的分析能力保证不出错,你也可以不判断容许位,但何必写这么一个提心吊胆的代码呢?
 楼主| 发表于 2012-11-15 08:49 | 显示全部楼层
搞定!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

153

帖子

2

粉丝
快速回复 返回顶部 返回列表