416112364 发表于 2021-11-30 09:15

AD数码管显示异常

#include <pic.h>
#include <math.h>
//#include <myfuncs1.h>
//#include <seg74.h>
#include <htc.h>
#define SEG_BITSEL_PORT PORTD                   //位选端口
#define SEG_BITSEL_PORT_DIR TRISD               //位选端口的方向寄存器
#define SEG_FONT_PORT PORTC                     //字形输出端口
#define SEG_FONT_PORT_DIR TRISC               //字形输出端口的方向寄存器
#define DLY_MS 67
const char Seg7TableN[]={0b11000000,0b11111001,0b10100100,0b10110000,0b10011001,0b10010010,0b10000010,0b11111000,0b10000000,0b10010000};

__CONFIG(FOSC_HS & WDTE_ON & PWRTE_OFF & BOREN_ON & LVP_ON & CPD_OFF & WRT_OFF & CP_OFF);
unsigned int g_ADRTable = {0};
unsigned char g_Count=0;
bit OverFlag = 0;//12位转换次数完成标志位清零;
void delayms (int ms);
void DisplayData (unsigned int iData);
interrupt ISR (void)
{
    if ( ADIE && ADIF)
    {
       ADIF = 0;
       g_ADRTable=(((unsigned int)ADRESH)<<8)+ADRESL;
       g_Count++;
       if(g_Count==12)
       {
         g_Count =0;
         OverFlag=1;//
       }
       else
       {
         GO_DONE = 1;//启动AD
       }      
    }
    else
       {
         while(1);
       }
}
void main(void)
{
    //voidDisplayData();
    char i=0,j=0;
    int tmp = 0;//
    int adc_v = 0;
    TRISA0 = 1;
    SEG_BITSEL_PORT_DIR = 0;//位选端口的方向寄存器,确定输出端口
    SEG_FONT_PORT_DIR = 0;//字形输出端口的方向寄存器,确定输出端口
    ADFM = 1;
    PCFG3:PCFG0 = 0000;
    ADCON0 = 0B11000001;
    ADIE = 1;
    ADIF = 0;
    PEIE = 1;
    GIE = 1;
    for(i=0;i<15;i++)
    {

    }
    GO_DONE = 1;
    while(GO_DONE)
    {
      if(OverFlag==1)
      {
            for(i=0;i<12;i++)//冒泡法排序
            {
                for(j=i+1;j<12;j++)
                {
                  if(g_ADRTable > g_ADRTable)
                  {
                        tmp = g_ADRTable;
                        g_ADRTable = g_ADRTable;
                        g_ADRTable = tmp;
                  }
                }   
            }
      tmp = 0;
      for(i=2;i<10;i++)
      {
            tmp = tmp + g_ADRTable;            
      }
      tmp = tmp >>3;//将数按照 2进制像右移动.每向右移动一位,相当于 除2的n次幂
      adc_v = tmp;
      adc_v = ((long)adc_v*5000/1023);
      OverFlag = 0;
      GO_DONE = 1;
      }
      DisplayData(adc_v);
    }
}
void DisplayData (unsigned int iData )
{
    char i=0,j=0;//
    char k = 0,NumStr[ 5 ]={0,0,0,0,0};
    NumStr=iData / 1000;//取整
    NumStr=iData % 1000/100;
    NumStr=iData % 100/10;
    NumStr=iData % 10;
    for(i=0;i<10;i++)
    {
      SEG_BITSEL_PORT = k =0X01;
      for(j=0;j<=4;j++)
      {
            SEG_BITSEL_PORT = k;
            if(j==1)
            {
                SEG_FONT_PORT = Seg7TableN]&0b01111111;         
            }
            else
            {
                SEG_FONT_PORT = Seg7TableN];

            }
            delayms(5);
            k = k <<1;//把1向左移1为显示
      }
    }
}
void delayms (int ms)
{
    int i=0,j =0;
    for(i=0;i < ms;i++)
      for(j =0; j < DLY_MS;j++)
      {;}
}
//帮忙看下是什么原因,4位数码管电压显示均为0,麻烦知道的发烧友指点呀,

一叶倾城wwq 发表于 2021-11-30 10:30

扫描频率不对吧,太快或太慢,建议先一位一位点亮再说,一步一步调。

416112364 发表于 2021-11-30 10:45

一叶倾城wwq 发表于 2021-11-30 10:30
扫描频率不对吧,太快或太慢,建议先一位一位点亮再说,一步一步调。

我尝试了,结果还是不可以,不知道问题具体出在哪里

ningling_21 发表于 2021-11-30 11:24

AD转换部分有没问题,是不是转换结果就是0

416112364 发表于 2021-11-30 13:50

ningling_21 发表于 2021-11-30 11:24
AD转换部分有没问题,是不是转换结果就是0

你是说这个吗?
if(j==1)
            {
                SEG_FONT_PORT = Seg7TableN]&0b01111111;         
            }
//将这个修改成
if(j==1)
            {
                SEG_FONT_PORT = Seg7TableN]&0b01111111;         
            }
//结果还是一样,没有解决任何问题

xinyue_z 发表于 2021-11-30 14:47

这个问题需要分为两部分:一是数码管驱动问题,而是AD采集和转换问题。写个for循环,把显示值从0000-》1111-》2222.。。。-》9999都显示对了,确认驱动没有问题,然后再看AD采样是否正确,AD采样输入给一个固定电压,在转换完成以后打断点看转换的数值是否是预期的,如果AD转换没有问题那就去找AD值转换到显示的问题,这个应该很容易就能找到问题

xch 发表于 2021-11-30 18:40

void DisplayData (unsigned int iData )
{
    char i=0,j=0;//
    char k = 0,NumStr[ 5 ]={0,0,0,0,0};
    NumStr=iData / 1000;//取整
    NumStr=iData % 1000/100;
    NumStr=iData % 100/10;
    NumStr=iData % 10;
    for(i=0;i<10;i++)
    {
      SEG_BITSEL_PORT = k =0X01;
      for(j=0;j<=4;j++)
      {
            SEG_BITSEL_PORT = k;
            if(j==1)
            {
                SEG_FONT_PORT = Seg7TableN]&0b01111111;         
            }
            else
            {
                SEG_FONT_PORT = Seg7TableN];

            }
            delayms(5);
            k = k <<1;//把1向左移1为显示
      }
    }
}

这个函数有问题。
显示数字进行切换时。应当关闭当前显示。比如SEG_BITSEL_PORT=0 或者 SEG_FONT_PORT=0xff;
比如先关闭SEG_BITSEL_PORT 驱动,然后 设置下一个字符 SEG_FONT_PORT,然后打开显示,驱动 SEG_BITSEL_PORT 。

xch 发表于 2021-11-30 20:53

细看问题不少。这个程序显示函数应当在中断中执行。要不然每次显示都停留在最后一个字上。还有看样子只有4位数显示,可是却定义了5位数的数组,显示指针也错乱了。

得推导重写。先写出一个定时中断函数。然后添加应用

songchenping 发表于 2021-12-1 08:31

直接放代码估计没几个人看,先表述问题,然后描述处理过程,有问题的话自己都表述不下去了。
页: [1]
查看完整版本: AD数码管显示异常