搜索
bottom↓
回复: 4

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

[复制链接]

出0入0汤圆

发表于 2010-8-23 09:23:28 | 显示全部楼层 |阅读模式
这是在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>

#define  Data_IO     PORTA
#define  Data_DDR    DDRA
#define  D_LE0       PORTD&=~(1<<PD4)
#define  D_LE1       PORTD|=(1<<PD4)
#define  W_LE0       PORTD&=~(1<<PD5)
#define  W_LE1       PORTD|=(1<<PD5)
#define  uchar       unsigned char
#define  uint        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[A1];
  D_LE0;
  delay_nms(1);
  D_LE1;
  W_LE1;
  Data_IO=~j;
  W_LE0;
  j=(j<<1);
  Data_IO=table[A2];
  D_LE0;
  delay_nms(1);
  D_LE1;
  W_LE1;
  Data_IO=~j;
  W_LE0;
  j=(j<<1);
  Data_IO=table[A3];
  D_LE0;
  delay_nms(1);
  D_LE1;
  W_LE1;
  Data_IO=~j;
  W_LE0;
  j=(j<<1);
  Data_IO=table[A4];
  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();
  }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

 楼主| 发表于 2010-8-23 16:25:53 | 显示全部楼层
自己顶!

出0入0汤圆

发表于 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[adc_data0]-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++;
        }
       
}

出0入0汤圆

发表于 2013-2-22 12:56:55 | 显示全部楼层
m                                         

出0入0汤圆

发表于 2013-2-23 21:26:55 来自手机 | 显示全部楼层
路过,学习一下....
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 05:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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