
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输出低
}
}
/*程序效果:数码管显示AD转换到的一字节数据,以十进制显示
调节相应的电位器,显示数据作相应的变化
程序开发:http://www.51hei.com
原理:0831是串行AD芯片,调节点位器就是调节了输入0831的模拟电压的大小,然后通过数码管显示
运行环境:51hei单片机学习板
*/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,//数码管显示的数值
0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}
sbit scl1=P1^3//芯片的通信脉冲引脚
sbit sda1=P1^4 //数据传输引脚
sbit px1=P1^5 //片选引脚,即选择ADC0831和DS1302
sbit cs1=P1^6//片选引脚
uchar tmpdata[]={0,0,0}
uchar readad0831()//定义该函数为读取ADC0831的数据
void display(uchar *lp,uchar lc)//显示子函数
void delay() //延时子函数
void main()// 主函数
{
uchar i=0,tmp
px1=0 //选择ADC0831该芯片
while(1)
{
i++
if(i==255) //这里为循环255个周期读取一次0831,
{ //因为CPU得运行速度很快,所以没有必要每一次
tmp=readad0831()//读取数据,这样可以充分利用CPU的资源
i=0
tmpdata[0]=tmp/100//分离百位
tmp=tmp%100
tmpdata[1]=tmp/10//分离十位
tmpdata[2]=tmp%10//分离个位
}
display(tmpdata,3)//输出显示
}
}
void display(uchar *lp,uchar lc) //显示子函数
{
uchar i //定义局部变量
P2=0 //端口P2为输出口
P1=P1&0xf8 //P1口的前三位用则衫于控制那个数码管亮,
//如果改为P1=0xf8,可能会出现数码管
//不停的显示,难以分清显示的数值
for(i=0i<lci++)
{
P2=table[lp[i]]//循环显示
delay() //延时五个孙漏腔空指令
if(i==7) //检测是否显示完8位,完成则直接退出
//不让P1口再加一,否则会影响P1^4口
break
P2=0 //清零端口,准备显示下一位
P1++//点亮下一个数码管
}
}
void delay() //延时子函数
{
_nop_()_nop_()_nop_()_nop_()_nop_()
}
uchar readad0831() //本函数是按照ADC0831的协议编写的
{
uchar i=0,tmp=0
sda1=1
cs1=0
_nop_()
_nop_()
scl1=0
_nop_()
搜液 _nop_()
scl1=1
_nop_()
_nop_()
scl1=0
_nop_()
_nop_()
scl1=1
_nop_()
_nop_()
scl1=0
_nop_()
_nop_()
for(i=0i<8i++)
{
tmp<<=1
if(sda1)
tmp++
scl1=1
_nop_()
_nop_()
scl1=0
_nop_()
_nop_()
}
cs1=1
return tmp
}
如程序无法编译,请去掉所有前导空白。
给你写一个吧,反正很简单一个程序,用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条)