好友帅峰的技术文章,帅峰电子科技淘宝店
//定时器初值计算,定时1ms,1024分频为例,(255 – 130)*(T_CPU*64)=0.001s
//主机液晶显示调试 11.7.24
#include <mega16.h>
#include <delay.h>
#define uchar unsigned char
#define uint unsigned
uint ADC_data,ADC_real_data;
uint time,t;
uchar SET_ADC,num;
bit ADC_flag,time_ok;
#define LED PORTB.7
#define LCD PORTD //1602_LCD_8位并行数据
#define RS PORTB.0
#define RW PORTB.1
#define E PORTB.2
uint ADC_data_store[3]; //AD数据缓存
uchar lcd_1602_table[]= ” <MEGA 16> ADC “;
uchar lcd_1602_table1[]= ” DC= 0000 mV “;
void write_1602_com(uchar com) // 写指令到1602LCD
{
RS=0;
RW=0;
E=0;
LCD=com;
delay_ms(1);
E=1;
delay_ms(1);
E=0;
}
void write_1602_data(uint date) // 写数据到1602LCD
{
RS=1;
RW=0;
E=0;
LCD=date;
delay_ms(1);
E=1;
delay_ms(1);
E=0;
}
void lcd_1602_init()
{
E=0;
write_1602_com(0x38); //设置1602显示,5*7点阵,8位数据接口
write_1602_com(0x0C); //
write_1602_com(0x06); //指令码设置
write_1602_com(0x01); //数据指针清零,所有显示清零
write_1602_com(0x80); //数据地址指针位.下一行的话 就是0x80+0x40+第几个,上一行就是0x80+第几个
}
void write_lcd_data(uchar x,uchar y,uint date) //数字提取数据子函数
{
uchar shi,ge,bai,qian,x_;
qian=date/1000;
bai=date%1000/100;
shi=date%100/10;
ge=date%10;
if(x==0) x_=0;
if(x==1) x_=0x40;
write_1602_com(0x80+x_+y);
write_1602_data(0x30+qian);
write_1602_data(0x30+bai);
write_1602_data(0x30+shi);
write_1602_data(0x30+ge);
}
uint ADC_conv(uint i) //这里我们要将实际值放大1000倍计算,目的是不让单片机进行复杂的浮点数运算
{
long x;
uint y;
x=(4910*(long)i)/1023; //输入电压值/1023*adc
y=(uint)x; //将无符号长整型变量X转化为无符号整型变量Y
return y; //取Y数据转换返回值
}
interrupt [ADC_INT] void adc_isr(void)
{
ADC_data=ADCL;
ADC_data|=(int)ADCH<<8; //将ADCH右对齐的低两位左移到高位,并和ADCL相加。
SET_ADC++; //完成一次转换自加1
if(SET_ADC==1) ADMUX= 0x40; //选择通道0
if(SET_ADC==3) ADMUX= 0x41; //选择通道1 //如果要通道3加一句就行,记住数据缓冲区也改大一些
if(SET_ADC==4) SET_ADC=0;
ADC_flag=1; //转换完成标志位
}
void AD_init( )
{
ADMUX |= (0<<REFS1)|(0<<REFS0)|(0<<ADLAR)|(0<<MUX4)|(0<<MUX3)|(0<<MUX2)|(0<<MUX1)|(0<<MUX0);//初始化通道0
ACSR =0X80; //关模拟比较器
ADCSRA |= (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(0<<ADIF)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
}
void TC0_init()
{
TCCR0=0X00; //先停止定时器0,无时钟源所以停止
TCNT0=130; //设定初值
TCCR0=0X03; //预置分频为64,低2位设置为11 /启动定时器0
TIMSK=0X01; //打开定时器0中断
SREG|=0X80; //打开总中断
}
void main(void)
{
PORTA=0X00; //高阻态
DDRA=0X00; //设定为输入使能
PORTB= 0XFF;//给端口写数据
DDRB=0xFF; //设定为输出使能
PORTC=0XFF; //给端口写数据
DDRC=0XFF; //设定为输出使能
PORTD= 0XFF;//给端口写数据
DDRD=0xFF; //设定为输出使能
SET_ADC=0;
TC0_init();
AD_init();
lcd_1602_init();
for(num=0;num<16;num++)
{
write_1602_data( lcd_1602_table[num]);
delay_ms(1);
}
write_1602_com(0x80+40); //第二行
for(num=0;num<16;num++)
{
write_1602_data( lcd_1602_table1[num]);
delay_ms(1);
}
t=0;
while(1)
{
if(ADC_flag==1)
{
ADC_flag=0;
ADC_real_data= ADC_conv(ADC_data);//数据转换
ADC_data_store[SET_ADC]=ADC_real_data;//存放到数组里
}
// if(ADC_data_store[1] >2000) LED=0;
if(time_ok) //500Ms刷新一次显示
{
write_lcd_data(1,6,ADC_data_store[3]);
time_ok=0;
}