关于tiny13 的ADC问题!
前几天从啊莫这里拿了几片tiny13 ,很长时间没用AVR熟悉起开还是蛮快搞了小弟一下午的是ADC转换结果怎么整都不是理想的结果.adcdata=~~~L;
adcdata+=~~~h*255;
if(dacdata>1024)
{portb|=(1<<pb2)}
if(dacdata<1024)
{portb|=(0<<pb2)}
这样的结果 PB2还输出高点平. 郁闷 ,
以前学习M8的时候可以用 屏幕来知道AD结果是多少,tiny13就没办法实现了( 没硬件防真)
所以问一下 大家有没有 tiny13的ADC 程序 C语言的 最好是GCC!!谢谢.
补充一点点MAKEFILE里没tiny13我是手动改的MCU 名字,其他的没改,不知道这样都ADC 有影响吗?> 哦忘记问一下她里面的1.1的VREF怎么样和M8的2.5V看怎么样!!
用过的朋友告诉一下谢谢 点击此处下载armok01166578.rar 不错啊 #include <avr/io.h>
#include <avr/delay.h>
#define uchar unsigned char
#define uint unsigned int
voidadcstar()
{
ADCSRA=0x00;
ADMUX=(1<<REFS0)|(1<<MUX1)|(0<<MUX0);
ACSR = (1 << ACD);
ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
_delay_ms(1);
ADCSRA|=(1<<ADSC);
ADC=0;
loop_until_bit_is_set(ADCSRA, ADIF);
ADCSRA |= (1 << ADIF);
}
int main(void)/////////////////主函数
{
DDRB=(0<<PB0)|(1<<PB1)|(0<<PB2)|(1<<PB3)|(0<<PB4);
PORTB=(1<<PB0)|(0<<PB1)|(0<<PB2)|(0<<PB3)|(0<<PB4);
uintadcdata;
while(1)
{
adcdata=0;
adcstar();
adcdata=ADC;
if(adcdata>500)
{
PORTB|=(1<<PB1);
}
if(adcdata<500)
{
PORTB|=(0<<PB1);
}
}
}
灯亮了就灭 不了?奇怪 好像和他们说的第一次启动正常,以后就全是0X3FF(ADC) 郁闷搞了2天 什么方法都试了,还是没办法解决!!!! m48 也是1.1V的。既然有M8的软件,用M48试试看 不知道内部AD精度能达到多少? 呵呵!高手总是不写注释的^_^ 楼主的ADC设置写的有些乱,IO口操作写的不正确。。。我改了一下,虽然还是很乱哈
#include <avr/io.h>
#define uchar unsigned char
#define uint unsigned int
voidadcstar()
{
DIDR0=0x10; // ADC2(PB4)禁用数字输入缓冲;
ADMUX=(1<<REFS0)|(0<<ADLAR)|(1<<MUX1)|(0<<MUX0);
/*
ADMUX (ADC Multiplexer Select Register) PDF86页
bit7Res 保留
bit6REFS0 0=VCC作为模拟参考电压;1=片内基准电压
bit5ADLAR 0=右对齐;1=左对齐(8bit只读ADCH即可)
bit4:2Res 保留
bit1:0MUX1,MUX0 通道选择,00=ADC0(PB5);01=ADC1(PB2);10=ADC2(PB4);11=ADC3 (PB3)
*/
ADCSRA=(1<<ADEN)|(1<<ADSC)|(0<<ADATE)|(0<<ADIF)|(0<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
/*
ADCSRA (ADC Control and Status Register A) PDF 87页
bit7 ADEN ADC使能=1
bit6 ADSC 启动ADC开始转换=1
bit5 ADATE 自触发使能
bit4 ADIF ADC中断标志
bit3 ADIE ADC中断使能
bit2:0 ADC 预分频选择位
*/
}
int main(void)/////////////////主函数
{
uint adcdata=0;
DDRB=(0<<PB0)|(1<<PB1)|(0<<PB2)|(1<<PB3)|(0<<PB4);
PORTB=(1<<PB0)|(0<<PB1)|(0<<PB2)|(0<<PB3)|(0<<PB4);
adcstar();
while(1)
{
if (ADCSRA&(1<<ADIF))
{
adcdata=ADC;
ADCSRA|=(1<<ADSC)|(1<<ADIF); // 再启动ADC 查询方式 ADIF为1时须用软件再写1来清0
}
if(adcdata>500)
{
PORTB|=(1<<PB1); // PB1 输出1
}
else
{
PORTB&=~(1<<PB1); // PB1 输出0
}
}
} tiny13的AD很复杂么?参考cvavr的代码向导啊,很简单的,8楼检测AD值的方法很好,我也在用呢,还可以用“龙”等等硬件仿真检测AD采样值。 谢谢楼上高手认可,cvavr是很好用,我也在用呢。但向导出来的代码要检查一下,我用tiny13就发现向导出来的DIDR0设置有误,如上面的ADC2(PB4)禁用数字输入缓冲(0x10),向导出来是0x04(ADC0)错误的 不知道你用的是哪个版本的cvavr,我用了1256没有问题,用了1257beta4没有问题,你的数字端口实际上可以不要管缓冲的问题,直接采集就可以了。 我碰到和10楼一样的问题,所以CVAVR生成的代码还是校验一下为好 【11楼】 JAMESKING 兄
我用的cvavr版本是1253,没你的新。数字端口能关掉我还是关了好,反正就改一句而已 cv1253对tiny13操作有些问题,详细请参考www.hpinfotech.ro上面的说明。 呵呵!下了个cv1257a Evaluation版,没发现错误了。谢谢楼上大哥! 嘎嘎小弟弟愚昧端口 操作错误!!现在好了1! 偶是菜鸟,这是我用TINNY13控制1W大功率LED手电的程序,AD检测电压,3.1V保护锂电,自动关灯,2个按键操作,亮度调节,暴闪.用了60%左右的FLASH空间,给楼主参考下,用05版的GCC编译的,makefile我就不发了.程序有点乱,需要花点时间看明白.
#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#define key1 PB1
#define key2 PB4
#define set_led_ddr DDRB|=_BV(PB0)
#define clr_led_ddr DDRB&=~_BV(PB0)
#define led_off PORTB&=~_BV(PB0)
#define led_on PORTB|=_BV(PB0)
#define uchar unsigned char
#define uint unsigned int
#define uint8 uint8_t
/*定义全局变量*/
uint8 light=185; //灯亮度
uint8 inter_count=0; //开灯计数值
uchar adc_val; //电池电压值,低于3.1V时自动关灯
uint8 power=0; //电源控制位,1为开灯,0为关灯
uint8 cpu_sta=0x30; //cpu状态控制,0x00为开灯状态,0x30为关灯状态
uint8 flash_sign=0; //闪灯控制,为1时灯闪,0是灯长亮
uint8 flash_count=0; //按下按键时间长度计数
uint8 key1_count=0;
//********** 按键检测**************
void key_check(void)
{
if(!(PINB&0X10)) power=0;
while(!(PINB&0X10));
}
//******* 电池电压检测 *************
void adc_check(void)
{
adc_val=ADCH;
if(adc_val<0x78) cpu_sta=0X30; //电池电压低于3.1V关灯,保护锂电
}
// ****** 灯状态扫描**************
void flash_check(void)
{
if(!(PINB&0X10)) //长按按键灯闪烁
{
flash_count++;
if(flash_count>70) flash_sign=1;
}
else flash_count=0; //放开按键灯亮
if(flash_sign==1) //灯闪烁
{
TCCR0B=0X04;
OCR0A=205;
}
else //灯长亮
{
TCCR0B=0X01;
OCR0A=light;
}
}
//**********开灯和关灯************
SIGNAL(SIG_INTERRUPT0)
{
inter_count++;
flash_sign=0;
if(inter_count==1) //开灯,配置寄存器
{
set_led_ddr;
PORTB=0X12; //配置端口
power=1; //电源标志,1为开灯,0为关灯
cpu_sta=0; //配置cpu
light=eeprom_read_byte(0);//读取亮度值
_delay_us(5);
OCR0A=light; //比较匹配值,灯亮度
TCNT0=0; //配置定时器
TCCR0A=0Xc3;
TCCR0B=0X01;
TIMSK0=0X02;
ADMUX=0X63; //配置AD
DIDR0=0X08;
ADCSRB=0X00;
ADCSRA=0Xe3;
while(!(PINB&0X02));
_delay_ms(2);
wdt_enable(WDTO_2S);//配置看门狗
}
if(inter_count>=2)
{
wdt_disable();
if(power==0) cpu_sta=0x30;//关灯
else
{
light+=30; //改变灯亮度
if(light>250) light=1; //灯由暗至亮,到最亮后循环变化
if(inter_count>250) inter_count=5;
}
while(!(PINB&0X02)); //按键不释放,在此停留
wdt_enable(WDTO_2S); //开看门狗
_delay_ms(1); //延时
}
}
//*********** 定时扫描,PWM ***********
SIGNAL(SIG_OVERFLOW0)
{
wdt_reset(); //喂狗
if(ADCSRA&0X10) adc_check();//电池电压检测
flash_check(); //灯状态扫描
}
//*******主程序 **************
int main(void)
{
GIMSK=0X40;
PORTB=0x02; //配置端口
CLKPR=0X80; //系统时钟分频
CLKPR=0X02; //分频系数为8,Fosc=128KHz/8=16KHz
eeprom_write_byte(0,light);//保存初始亮度
_delay_us(10);
sei(); //开中断
while(1)
{
MCUCR=cpu_sta; //配置cpu状态
if(cpu_sta==0x30)
{
eeprom_write_byte(0,light);//关灯前保存亮度值
wdt_reset();
wdt_disable(); //关闭看门狗
TCCR0B=0; //关闭定时器
ADCSRA=0x00; //关闭AD
ADMUX=0x03;
DDRB=0X00; //配置端口
PORTB=0X02;
flash_count=0; //计数器清零
inter_count=0;
_delay_us(10);
asm("sleep"); //掉电模式,最大地省电
}
key_check(); //按键检测
}
} littleboy可以交个朋友吗 我们做的是一个行业也 !! tiny adc 的adc采集好像部是很稳定,连续采集多次的结果部同,且使用内部参考电压时,adc采集值会随工作电压变化,但是mega48 的没有此问题 正在用到这部分功能,不知道端口要怎样设置 好东西来学习了 shinehjx 发表于 2007-8-17 08:27
呵呵!高手总是不写注释的^_^ 楼主的ADC设置写的有些乱,IO口操作写的不正确。。。我改了一下,虽然还是很 ...
请教一下 ADC的中断模式如何设置? 试了很多次,查询模式正常但是 中断模式无法正常使用。 路过路过了顺便看看
页:
[1]