打印

新手编写的数码管扫描程序(内附仿真和程序)

[复制链接]
2571|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 xppx1987 于 2012-9-10 15:24 编辑

本人前两天发过数码管动态扫描的帖子,问题还是没有解决,显示问题:后面一个四位一体的数码管的第二个和第三个管子均不能正常显示(怀疑74HC164送段选出问题)!今天附上完整仿真图和程序,望各位指出错误!注:1、需要说明的是两个四位一体的共阴极数码管是共用的位选端口,占用C端口的低四位!2、连接数码管的位选端口的三极管的C级若去掉上拉电阻则不能正常显示,请问什么原因?小弟看见有的电路图没有加上拉电阻也行。
#include<pic.h>  
#include<math.h>
#include<stdio.h>      
  
__CONFIG(0xe0f1); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡 //__CONFIG(HS&WDTDIS&LVPDIS);
#define data164 RA3
#define clk164 RA5
#define uchar unsigned char
#define uint unsigned int

#define  _nop_()  asm("nop")
uchar count_10ms=0;
float wendu,shidu;
uint temp=123,humi=456;
uchar const bit_tab[]={0x80,0x40,0x20,0x01,0x08,0x04,0x02,0x01,0};//位选表,用来选择哪一只数码管进行显示
uchar const seg_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段选表,共阴数码显示码值
uchar disbuf[6];  //定义显示缓冲单元

/******函数定义**************/
void sendbyte1(char byte);
void sendbyte2(char byte);
void conv(int tmp_s,int humi_s);
void display();

/********端口设置函数********/
void port_init( )
{
TRISA=0x07;
TRISB=0x06;
TRISC =0x00;  //端口C输出,位选
ADCON1=0x06;  //定义RA为IO端口
ANSEL=0x00;
ANSELH=0x00;
}

/*****************显示函数***********************/
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;
}
}

void sendbyte2(char byte)
{
unsigned char  c;
for(c=0;c<16;c++)
{
  if(byte&0x80)
  data164=1;
  else data164=0;   
  clk164=0;
  _nop_();
  clk164=1;
  byte<<=1;
}
}

void conv(int tmp_s,int humi_s)
{
    disbuf[0]=tmp_s/100;
    disbuf[1]=tmp_s%100/10;
    disbuf[2]=tmp_s%10;
    disbuf[3]=humi_s/100;
    disbuf[4]=humi_s%100/10;
    disbuf[5]=humi_s%10;  
}
void display()
{
static uchar count=0;
PORTC=bit_tab[8];
switch(count)
{
   case 0:sendbyte1(seg_data[disbuf[0]]);PORTC=bit_tab[4];break;
   case 1:sendbyte1(seg_data[disbuf[1]]);PORTC=bit_tab[5];break;
   case 2:sendbyte1(seg_data[disbuf[2]]);PORTC=bit_tab[6];break;
   case 3:sendbyte2(seg_data[disbuf[3]]);PORTC=bit_tab[4];break;
   case 4:sendbyte2(seg_data[disbuf[4]]);PORTC=bit_tab[5];break;
   case 5:sendbyte2(seg_data[disbuf[5]]);PORTC=bit_tab[6];break;
}
count++;
if(count==6) count=0;
}
/*********定时器0/定时器1初始化函数********/
void  timer_init()
{
GIE=1;     //开总中断
PEIE=1;    //开外围功能模块中断
T0CS=0;    //定时器0对内部时钟计数
PSA=0;    //分频器分配给TRM0
PS0=1;
PS1=1;
PS2=1;     //定时器0分频比为1:256
T0IE=1;    //允许TMR0溢出中断
TMR0=248;    //TMR0赋初值,定时2ms
T1CKPS0=1;T1CKPS1=1;  //定时器1分频比为1:8
TMR1CS=0;    //定时器1设置为定时功能
TMR1IE=1;    //使能定时器1中断
TMR1ON=1;    //启动定时器1
TMR1H=0xfb;    //置计数值高位,定时时间为10ms
TMR1L=0x1e;    //置计数值低位
}
/********中断服务程序********/
void interrupt ISR(void)
{   
if(TMR0IF==1)
{
  TMR0IF=0;   //清TMR1溢出中断标志位
  TMR0=248;                       //TMR0赋初值,定时2ms
  display();   //调显示函数
}
if(TMR1IF==1)
{
  TMR1IF=0;   //清TMR1溢出中断标志位
  TMR1H=0xfb;   //重置计数值,定时时间为10ms
  TMR1L=0x1e;   //重置计数值
  count_10ms++;  //10ms计数器加1
  if(count_10ms>=100)  
  {
    count_10ms = 0;   //计数100次后恰好为1s,此时10ms计数器清零
  }
}
}

/*************************主函数****************************/
void main( )
{
   port_init();
   timer_init();           //调定时器T0、T1初始化函数
   while(1)
  {
      conv(temp,humi); //调走时转换函数
   }
}
沙发
兰天白云| | 2012-9-10 16:20 | 只看该作者
三极管的驱动电路有问题,再改改

使用特权

评论回复
板凳
xppx1987|  楼主 | 2012-9-10 16:36 | 只看该作者
2# 兰天白云 请教一下哪里有问题?是不是集电极不加上拉电阻?但是如果去掉上拉电阻后,数码管显示的完全是乱码啊!

使用特权

评论回复
地板
XIEYUANBIN| | 2012-9-11 11:52 | 只看该作者
基极加限流电阻,集电极也同样要加......哥啊,这电路没法看,惨

使用特权

评论回复
5
maktin2| | 2012-9-11 12:02 | 只看该作者
mk

使用特权

评论回复
6
兰天白云| | 2012-9-13 15:31 | 只看该作者

参考电路

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

153

帖子

2

粉丝