zhegongda 发表于 2010-8-23 09:23:28

Atmega128的ADC转换实现不了,请帮个忙,看看有什么问题

这是在Atmega128上,用ICCAVR做ADC转换的程序。发现ADC不转换,数码管上显示的永远是0514,不知道哪里出错了,望各位帮忙看看错在哪里,其他地方应该没有错,估计就在ADC初始化adc_init()、ADC转换adc_zhuanhuan()两个程序里面错,或者在main()函数出错,显示的程序display_adc()肯定没错的,因为在其他地方用过的

//A、D口都是用来数码管显示的
#include<iom128v.h>
#include<macros.h>
#include<stdio.h>
#include<delay.h>

#defineData_IO   PORTA
#defineData_DDR    DDRA
#defineD_LE0       PORTD&=~(1<<PD4)
#defineD_LE1       PORTD|=(1<<PD4)
#defineW_LE0       PORTD&=~(1<<PD5)
#defineW_LE1       PORTD|=(1<<PD5)
#defineuchar       unsigned char
#defineuint      unsigned int

uchar table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar A1,A2,A3,A4;

void system_init()            //系统初始化
{
DDRA=0xff;
PORTA=0xff;
DDRB=0xff;
PORTB=0xff;                //关闭LED灯
DDRD=0xff;
PORTD=0xff;
}

void adc_init()               //ADC初始化
{
ADCSRA=0x00;                //关ADC
ADMUX=0xc0;               //2.56V基准电压,右对齐
ACSR=0x80;
ADCSRA=0x86;                //转换使能,64分频,单次转换
}

uint adc_zhuanhuan()         //ADC转换开始
{
uint adc_value;
ADMUX=0xc0;
ADCSRA|=(1<<ADSC);         //启动转换
delay_nms(3);
while(!(ADCSRA&(1<<ADIF)));
ADCSRA|=(1<<ADIF);
adc_value=ADCL;
adc_value+=ADCH*256;
return adc_value;
}

void data_do(uint adc_value)
{
A1=adc_value/1000;
A2=adc_value%1000/100;
A3=adc_value%1000%100/10;
A4=adc_value%1000%100%10;
}

void display_adc()
{
uchar i,j;
system_init();
j=0x01;
for(i=0;i<4;i++)
{
    D_LE1;
        W_LE1;
        Data_IO=~j;
        W_LE0;
        j=(j<<1);
        Data_IO=0x00;
        D_LE0;
        delay_nms(1);
}
D_LE1;
W_LE1;
Data_IO=~j;
W_LE0;
j=(j<<1);
Data_IO=table;
D_LE0;
delay_nms(1);
D_LE1;
W_LE1;
Data_IO=~j;
W_LE0;
j=(j<<1);
Data_IO=table;
D_LE0;
delay_nms(1);
D_LE1;
W_LE1;
Data_IO=~j;
W_LE0;
j=(j<<1);
Data_IO=table;
D_LE0;
delay_nms(1);
D_LE1;
W_LE1;
Data_IO=~j;
W_LE0;
j=(j<<1);
Data_IO=table;
D_LE0;
delay_nms(1);
}

void main()
{
uint adc_value;
system_init();
adc_init();
SREG=0x80;
while(1)
{
    adc_zhuanhuan();
    data_do(adc_value);
    display_adc();
}
}

zhegongda 发表于 2010-8-23 16:25:53

自己顶!

xxsc118 发表于 2010-8-24 11:35:04

这是我自己编的,经过试验是好用的。功能为:温度表。你参考一下。
#include<iom128v.h>
#include"1602.h"
#define uchar unsigned char
#define uint unsigned int
uchar tem[]={"tempreture:"};
#pragma data:code
const uchar table_ad[]={
        /*0,1,2,3,4,5,6,7,8,9,10 ,11 ,12 ,13 ,14 ,15 ,16 ,17 ,18 ,19 */
      //0,0,0,
      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

      /*20 ,21 ,22 ,23 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,39 */
          0,0,0,0,0,0,0,0,1,2,4,6,7,8,9,10 ,12 ,14 ,15 ,16 ,

      /*40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 ,48 ,49 ,50 ,51 ,52 ,53 ,54 ,55 ,56 ,57 ,58 ,59 */
          17 ,18 ,20 ,21 ,22 ,24 ,25 ,26 ,27 ,28 ,29 ,30 ,31 ,32 ,33 ,34 ,35 ,36 ,37 ,38 ,

      /*60 ,61 ,62 ,63 ,64 ,65 ,66 ,67 ,68 ,69 ,70 ,71 ,72 ,73 ,74 ,75 ,76 ,77 ,78 ,79 */
          39 ,40 ,41 ,42 ,43 ,44 ,45 ,46 ,47 ,48 ,49 ,50 ,51 ,51 ,52 ,53 ,54 ,55 ,56 ,57 ,

      /*80 ,81 ,82 ,83 ,84 ,85 ,86 ,87 ,88 ,89 ,90 ,91 ,92 ,93 ,94 ,95 ,96 ,97 ,98 ,99 */
          58 ,59 ,59 ,60 ,61 ,62 ,63 ,63 ,64 ,65 ,66 ,67 ,68 ,69 ,69 ,70 ,71 ,72 ,73 ,73 ,

      /*100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119*/
          74 ,75 ,76 ,77 ,77 ,78 ,79 ,80 ,81 ,82 ,83 ,83 ,84 ,85 ,86 ,87 ,87 ,88 ,89 ,90 ,

      /*120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139*/
          91 ,91 ,92 ,93 ,94 ,95 ,95 ,96 ,97 ,98 ,99 ,100,101,101,102,103,104,105,106,107,

      /*140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159*/
          107,108,109,110,111,112,113,114,115,115,116,117,118,119,120,121,122,123,124,125,

      /*160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179*/
          126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,

      /*180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199*/
          146,148,149,150,151,153,154,155,157,158,159,160,161,163,164,165,167,168,170,171,

      /*200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219*/
          173,175,176,177,179,181,183,185,186,187,189,191,193,195,197,199,200,201,202,204

};



//ADC测试,使用1602显示ADC0和ADC1的值
//主函数
main()
{
uchar ten_1,ten_2,ten_3,ten_4,i,temp;
uint adc_data0,adc_l0,adc_h0,adc_data1,adc_l1,adc_h1;

//初始化端口
DDRA=0xff;
DDRC=0XFF;
PORTC=0XFF;
PORTA=0x00;
DDRB=0xff;
DDRD=0xff;
PORTD=0x00;
DDRF=0x00;
PORTF=0x00;
DDRG=0xff;
PORTG=0x00;

//1602初始化
LcdInit();   
WriteChar(1,2,11,tem);

PORTC|=(1<<6);
while(1)
   {
          //取ADC_0
      ADCSRA=0x00;
      ADMUX=0x40;
      ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADFR)|0x07;   //128分频,连续转换
      s_ms(500);                                 //延时很重要,给出转换的时间
      adc_l0=ADCL;
      adc_h0=ADCH;
      adc_data0=adc_h0<<8|adc_l0;                  
      adc_data0=adc_data0>>2;               //放弃2位精度                           
           //adc_data0=adc_h0;   
          temp=(table_ad-40)/2;//温度计算
          
          //显示ADC0
          ten_3=(temp)/100;
          ten_2=(temp-(ten_3*100))/10;
          ten_1=temp-(ten_3*100)-ten_2*10;
          ten_1+=0x30;//转换成ASCII
          ten_2+=0x30;;//转换成ASCII
          ten_3+=0x30;;//转换成ASCII
          WriteNum(1,13,(ten_3));
          WriteNum(1,14,(ten_2));
          WriteNum(1,15,(ten_1));
       
          
          for(i=0;i<18;i++)
             {
              s_ms(60000);
             }       
       }
}


#define uchar unsigned char
#define uint unsigned int

#define RS 0
#define RW 1
#define EN 2

void s_ms(uint ms)
{
        for(;ms>1;ms--);
}       

//查忙
void busy(void)
{
    uchar temp;
        s_ms(500);
        PORTC&=~(1<<RS);    //RS=0
        s_ms(500);
        PORTC|=(1<<RW);   //RW=1
        s_ms(500);
        while(temp)
        {
                PORTC|=(1<<EN); //EN=1
                s_ms(500);
                DDRA=0x00;      //A口变输入
                PORTA=0xff;   //上拉使能
                s_ms(500);
                temp = PINA&0x80;    //读取A口
                s_ms(500);      
                DDRA=0xff;      
                PORTA=0xff;      //A口变输出
                s_ms(500);
                PORTC&=~(1<<EN);   //EN=0
                s_ms(500);
        }
}

//写指令
void writecom(uchar        com)
{
        busy();
        s_ms(500);
        PORTC&=~(1<<RS);   //RS=0
        s_ms(500);
        PORTC&=~(1<<RW);   //RW=0
        s_ms(500);
        PORTC|=(1<<EN);    //EN=1
        s_ms(500);
        PORTA = com;       //输出指令
        s_ms(500);
        PORTC&=~(1<<EN);   //EN=0
        s_ms(500);
}

//1602初始化
void        LcdInit(void)
{
        writecom(0x38);
        s_ms(1000);
        writecom(0x01);
        s_ms(10000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        s_ms(1000);
        writecom(0x02);
        s_ms(1000);
        writecom(0x06);
        s_ms(1000);
        writecom(0x0c);
        s_ms(1000);
        writecom(0x38);       
        s_ms(1000);
}       

//写数据
void        writedata(uchar data)
{
        busy();
        s_ms(500);
        PORTC|=(1<<RS);   //RS=1
        s_ms(500);
        PORTC&=~(1<<RW);   //RW=0
        s_ms(500);
        PORTC|=(1<<EN);    //EN=1
        s_ms(500);
        PORTA = data;      //输出数据
        s_ms(500);
        PORTC&=~(1<<EN);   //EN=0
        s_ms(500);
}


//读数据
uchar        readdata(void)
{
        uchar temp;
        busy();
        s_ms(500);
        PORTC|=(1<<RS);//RS=1
        s_ms(500);
        PORTC|=(1<<RW);//RW=1
        s_ms(500);
        PORTC|=(1<<EN);//EN=1
        s_ms(500);
        DDRA=0x00;       //A端口变输入
        s_ms(500);
        temp = PINA;   //读A端口
        s_ms(500);
        DDRA=0xff;       //A端口变输出
        s_ms(500);
        PORTC&=~(1<<EN); //EN=0
        s_ms(500);
        return temp;       
}

//=================================================
// 描述: 写LCD内部CGRAM函数
// 入口: ‘num’要写的数据个数
//      ‘pbuffer’要写的数据的首地址
// 出口: 无
//================================================
void        WriteCGRAM(uint        num, const uint        *pBuffer)
{
        uint        i,t;
        writecom(0x40);
        PORTC|=(1<<RS);
        PORTC&=~(1<<RW);
        for(i=num;i!=0;i--)
        {
                t = *pBuffer;
                PORTC|=(1<<EN);
                PORTA = t;
                PORTC&=~(1<<EN);                               
                pBuffer++;
        }
       
}

//=================================================
//描述:写菜单函数,本程序使用的LCD规格为 16 * 2
//入口:菜单数组首地址
//出口:无
//=================================================
void        WriteMenu(const uchar *pBuffer)
{
        uchar        i,t;
        writecom(0x80);   //数据地址
       
        PORTC|=(1<<RS);
        PORTC&=~(1<<RW);
        s_ms(50);
        for(i=0;i<16;i++)
        {
                t = *pBuffer;
                PORTA = t;
                PORTC|=(1<<EN);
                s_ms(50);
                PORTC&=~(1<<EN);                               
                pBuffer++;
        }
        writecom(0xC0);

        PORTC|=(1<<RS);
        PORTC&=~(1<<RW);
        s_ms(50);       
        for(i=0;i<16;i++)
        {
                t = *pBuffer;
                PORTA = t;
                PORTC|=(1<<EN);
                s_ms(50);
                PORTC&=~(1<<EN);                               
                pBuffer++;
        }
}
//====================================================
// 描述:在任意位置写数字函数
// 入口:’row‘表示要写数字所在的行地址,只能为1或2
//       ’col‘表示要写数字所在的列地址,只能为0--15
//               ‘num’表示要写的数字,只能为0--9
// 出口:无
//===================================================
void WriteNum(uchar row,uchar col,uchar num)
{
        if (row == 1)        row = 0x80 + col;
        else        row = 0xC0 + col;
        writecom(row);

        PORTC|=(1<<RS);
        s_ms(500);
        PORTC&=~(1<<RW);
        s_ms(500);
        PORTA = num;
        s_ms(500);
        PORTC|=(1<<EN);
        s_ms(500);
        PORTC&=~(1<<EN);       
        s_ms(500);                       
}
//================================================================
// 描述:在任意位置写任意多个字符
// 入口:’row‘要写的字符所在的行,只能为1或2;
//       ‘col’要写的字符所在的列,只能为0---15
//       ‘num’要写字符的个数
//       ‘pbuffer’要写字符的首地址
//==================================================================
void        WriteChar(uchar row,uchar col,uint num,uchar *pBuffer)
{
        uchar i,t;
        if (row == 1)        row = 0x80 + col;
        else        row = 0xC0 + col;
        writecom(row);


        PORTC|=(1<<RS);
        s_ms(500);
        PORTC&=~(1<<RW);
        s_ms(500);
        for(i=num;i!=0;i--)
        {
                t = *pBuffer;
                s_ms(500);
                PORTA = t;
                s_ms(500);
                PORTC|=(1<<EN);
                s_ms(500);
                PORTC&=~(1<<EN);               
                s_ms(500);               
                pBuffer++;
        }
       
}

lkwslk1 发表于 2013-2-22 12:56:55

m                                       

jz701209李 发表于 2013-2-23 21:26:55

路过,学习一下....
页: [1]
查看完整版本: Atmega128的ADC转换实现不了,请帮个忙,看看有什么问题