
typedef unsigned int WORD
#include "reg51.h"
#include "intrins.h"
/*Declare SFR associated with the ADC */
sfr ADC_CONTR = 0xBC
sfr ADC_RES = 0xBD
sfr ADC_LOW2= 0xBE
sfr P1ASF = 0x9D
sfr P2M0 = 0x96
sfr P2M1 = 0x95
/*Define ADC operation const for ADC_CONTR*/
#define ADC_POWER 0x80
#define ADC_FLAG0x10
#define ADC_START 0x08
#define ADC_SPEEDLL 0x00
#define ADC_SPEEDL 0x20
#define ADC_SPEEDH 0x40
#define ADC_SPEEDHH 0x60
//延时
void Delay(WORD n)
{
WORD x
while (n--)
{
x = 5000
while (x--)
}
}
//初始AD寄存器
void InitADC()
{
P1ASF = 0xff
ADC_RES = 0
ADC_CONTR = ADC_POWER | ADC_SPEEDLL
Delay(2)
}
//AD转换
BYTE GetADCResult(BYTE ch)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL | ch | ADC_START
_nop_()
_nop_()
_nop_()
_nop_()
while (!(ADC_CONTR &ADC_FLAG))
ADC_CONTR &= ~ADC_FLAG
return ADC_RES
}
void main()
{ BYTE temp
P2M1=0 P2M0=0x03 //P2.0和P2.1强推挽
InitADC()
while (1)
{
temp=GetADCResult(0)//转换P1.0
if(temp>1)
P2|=0x03//P1.0有电压 P2.0和P2.1输出高
else
P2&=0xFC//P1.0无电压 P2.0和P2.1输出低
}
}
给你写一个吧,反正很简单一个程序,用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=0voltage=voltage2/8voltage2=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()
}
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)