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();
}
} 自己顶! 这是我自己编的,经过试验是好用的。功能为:温度表。你参考一下。
#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++;
}
} m 路过,学习一下....
页:
[1]