AVR单片机ADC控制LED程序(C语言)
2个回答
展开全部
给你写一个吧,反正很简单一个程序,用mega8实现,单片机型号你可以改,只要改掉中断向量号就行:
#include <iom8v.h>
#include <macros.h>
#define LED1_ON PORTB|= BIT(1)
#define LED1_OFF PORTB&=~BIT(1)
//一下你可以再写七个灯或者更多
#define uchar unsigned char
#define uint unsigned int
uint adc_count = 0 ; //控制AD转换速度计数
uint a_time = 0 ; //用于AD数字滤波计数
uchar mode = 0 ; //用于AD处理结果赋值
void port_init(void)
{
DDRB = 0xff;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xff;
DDRD = 0xf0;
PORTD = 0x00;
}
// 定时器分频: 64
// 设定定时值: 1ms
// 真实定时值: 1ms (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
TIMSK |= 0x01;
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x83; //reload counter value
adc_count++;
if(adc_count==50) //用于控制AD转换速度
{
adc_count=0;
ADCSRA = 0xCF;
}
else
{
ADCSRA = 0x00;
}
}
void adc_init(void)
{
ADCSRA = 0x00; //禁止AD转换
ADMUX = 0x07;
SFIOR |= 0x00;
ACSR = 0x80; //禁止模拟比较器
ADCSRA = 0xCF;
//ADCSRA = 0xED;
}
unsigned int adc_calc(void)
{
//计算实际电压
unsigned long value=0;
unsigned int voltage=0; //电压单位为(mV)
value=ADCL; //首先读低位
value|=(int)ADCH << 8; //然后读高位
voltage=(value*5000)/1023;
ad_flag=1;
return voltage;
}
//采用AD取平均值的方式
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
//转换完成后中断处理
unsigned int voltage1;
a_time++;
if(a_time<8)
{voltage1=adc_calc();voltage2=voltage2+voltage1;}//数字滤波
while(a_time==8)
{
a_time=0;voltage=voltage2/8;voltage2=0;
if((voltage)<1130){dianliang=0;}
if((voltage>=1130)&&(voltage<1300)){mode=1;}
if((voltage>=1300)&&(voltage<1560)){mode=2;}
if((voltage>=1560)&&(voltage<1750)){mode=3;}
if((voltage>=1750)&&(voltage<1950)){mode=4;}
if((voltage>=1950)&&(voltage<2150)){mode=5;}
if((voltage>=2150)&&(voltage<2341)){mode=6;}
if((voltage>=2341)&&(voltage<2560)){mode=7;}
if((voltage>=2560)&&(voltage<2710)){mode=8;}
if((voltage>=2710)&&(voltage<2870)){mode=9;}
}
else{mode=0;}
}
void LED_DISP(void) //用于控制LED显示
{
switch(mode)
{
case 0: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 1: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 2: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 3: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 4: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 5: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 6: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 7: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 8: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 9: /*此处写上你要控制的灯的亮或灭*/ ;break;
default: break;
}
}void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
timer0_init();
port_init();
adc_init();
//SEI();//开全局中断
}
void main(void)
{
init_devices();
while(1)
{
LED_DISP();
}
}
#include <iom8v.h>
#include <macros.h>
#define LED1_ON PORTB|= BIT(1)
#define LED1_OFF PORTB&=~BIT(1)
//一下你可以再写七个灯或者更多
#define uchar unsigned char
#define uint unsigned int
uint adc_count = 0 ; //控制AD转换速度计数
uint a_time = 0 ; //用于AD数字滤波计数
uchar mode = 0 ; //用于AD处理结果赋值
void port_init(void)
{
DDRB = 0xff;
PORTB = 0x00;
DDRC = 0x00;
PORTC = 0xff;
DDRD = 0xf0;
PORTD = 0x00;
}
// 定时器分频: 64
// 设定定时值: 1ms
// 真实定时值: 1ms (0.0%)
void timer0_init(void)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
TIMSK |= 0x01;
TCCR0 = 0x03; //start timer
}
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x83; //reload counter value
adc_count++;
if(adc_count==50) //用于控制AD转换速度
{
adc_count=0;
ADCSRA = 0xCF;
}
else
{
ADCSRA = 0x00;
}
}
void adc_init(void)
{
ADCSRA = 0x00; //禁止AD转换
ADMUX = 0x07;
SFIOR |= 0x00;
ACSR = 0x80; //禁止模拟比较器
ADCSRA = 0xCF;
//ADCSRA = 0xED;
}
unsigned int adc_calc(void)
{
//计算实际电压
unsigned long value=0;
unsigned int voltage=0; //电压单位为(mV)
value=ADCL; //首先读低位
value|=(int)ADCH << 8; //然后读高位
voltage=(value*5000)/1023;
ad_flag=1;
return voltage;
}
//采用AD取平均值的方式
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
//转换完成后中断处理
unsigned int voltage1;
a_time++;
if(a_time<8)
{voltage1=adc_calc();voltage2=voltage2+voltage1;}//数字滤波
while(a_time==8)
{
a_time=0;voltage=voltage2/8;voltage2=0;
if((voltage)<1130){dianliang=0;}
if((voltage>=1130)&&(voltage<1300)){mode=1;}
if((voltage>=1300)&&(voltage<1560)){mode=2;}
if((voltage>=1560)&&(voltage<1750)){mode=3;}
if((voltage>=1750)&&(voltage<1950)){mode=4;}
if((voltage>=1950)&&(voltage<2150)){mode=5;}
if((voltage>=2150)&&(voltage<2341)){mode=6;}
if((voltage>=2341)&&(voltage<2560)){mode=7;}
if((voltage>=2560)&&(voltage<2710)){mode=8;}
if((voltage>=2710)&&(voltage<2870)){mode=9;}
}
else{mode=0;}
}
void LED_DISP(void) //用于控制LED显示
{
switch(mode)
{
case 0: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 1: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 2: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 3: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 4: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 5: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 6: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 7: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 8: /*此处写上你要控制的灯的亮或灭*/ ;break;
case 9: /*此处写上你要控制的灯的亮或灭*/ ;break;
default: break;
}
}void init_devices(void)
{
CLI(); //禁止所有中断
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
timer0_init();
port_init();
adc_init();
//SEI();//开全局中断
}
void main(void)
{
init_devices();
while(1)
{
LED_DISP();
}
}
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
说得太简单了,有具体点的要求不?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询