小玩了一下Atmega88V的AD,没想到,几个简单寄存器还挺复杂,坎坷了一下……终于,世上无难事,因为有高人啊!终于,O了!
采用内部1.1v基准电压作参考电压,PORTC为输入通道,根据ATMEG的数据手册,仔细研读,配置寄存器,把数据完美的显示在了LCD上!(LCD网上买的,至于用法,若有兴趣,可先参考,哈哈!)
还是老话,上程序!
*****************************************************/
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h> //中断函数头文件
#include <string.h>
#define sce1 (PORTD |= (1<<PD0))
#define sce0 (PORTD &= ~(1<<PD0))
#define res1 (PORTD |= (1<<PD1))
#define res0 (PORTD &= ~(1<<PD1))
#define dc1 (PORTD |= (1<<PD2))
#define dc0 (PORTD &= ~(1<<PD2))
#define sdin1 (PORTD |= (1<<PD3))
#define sdin0 (PORTD &= ~(1<<PD3))
#define sclk1 (PORTD |= (1<<PD4))
#define sclk0 (PORTD &= ~(1<<PD4))
//6*16字符
const prog_char data222[]={
0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x2f, 0x00, 0x00, // !
0x00, 0x07, 0x00, 0x07, 0x00, // "
0x14, 0x7f, 0x14, 0x7f, 0x14, // #
0x24, 0x2a, 0x7f, 0x2a, 0x12, // $
0x62, 0x64, 0x08, 0x13, 0x23, // %
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x05, 0x03, 0x00, 0x00, // ’
0x00, 0x1c, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1c, 0x00, // )
0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x00, 0xA0, 0x60, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x60, 0x60, 0x00, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x42, 0x7F, 0x40, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x21, 0x41, 0x45, 0x4B, 0x31, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
0x01, 0x71, 0x09, 0x05, 0x03, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x06, 0x49, 0x49, 0x29, 0x1E, // 9
0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x08, 0x14, 0x22, 0x41, 0x00, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x41, 0x22, 0x14, 0x08, // >
0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x32, 0x49, 0x59, 0x51, 0x3E, // @
0x7C, 0x12, 0x11, 0x12, 0x7C, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x22, 0x1C, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x3E, 0x41, 0x49, 0x49, 0x7A, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x20, 0x40, 0x41, 0x3F, 0x01, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x7F, 0x04, 0x08, 0x10, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
0x7F, 0x09, 0x19, 0x29, 0x46, // R
0x46, 0x49, 0x49, 0x49, 0x31, // S
0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x3F, 0x40, 0x38, 0x40, 0x3F, // W
0x63, 0x14, 0x08, 0x14, 0x63, // X
0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x7F, 0x41, 0x41, 0x00, // [
0x55, 0x2A, 0x55, 0x2A, 0x55, // 55
0x00, 0x41, 0x41, 0x7F, 0x00, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x01, 0x02, 0x04, 0x00, // ’
0x20, 0x54, 0x54, 0x54, 0x78, // a
0x7F, 0x48, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x20, // c
0x38, 0x44, 0x44, 0x48, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x08, 0x7E, 0x09, 0x01, 0x02, // f
0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x40, 0x80, 0x84, 0x7D, 0x00, // j
0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x18, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0xFC, 0x24, 0x24, 0x24, 0x18, // p
0x18, 0x24, 0x24, 0x18, 0xFC, // q
0x7C, 0x08, 0x04, 0x04, 0x08, // r
0x48, 0x54, 0x54, 0x54, 0x20, // s
0x04, 0x3F, 0x44, 0x40, 0x20, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x00, 0x08, 0x36, 0x41, 0x00, // {
0x00, 0x00, 0x7F, 0x00, 0x00, // |
0x00, 0x41, 0x36, 0x08, 0x00, // }
0x08, 0x10, 0x08, 0x04, 0x08 // ~
};
void delayms(unsigned int ii)// ms延时函数
{
_delay_ms(ii);
}
/*--------------------------------------------
LCD_write_byte: 使用SPI接口写数据到LCD
输入参数:dt:写入的数据;
command :写数据/命令选择;
编写日期:20080918
----------------------------------------------*/
void LCD_write_byte(unsigned char dt, unsigned char command)
{
unsigned char i;
sce0;
//dc=command;
if(command)
dc1;
else
dc0;
for(i=0;i<8;i++)
{
if(dt&0x80)
sdin1;
else
sdin0;
dt=dt<<1;
sclk0;
sclk1;
}
dc1;
sce1;
sdin1;
}
/*---------------------------------------
LCD_init: 3310LCD初始化
编写日期:20080918
----------------------------------------- */
void LCD_init(void)
{
PORTD = 0X00;
DDRD = 0XFF;
res0;
delayms(1);
res1;
LCD_write_byte(0x21,0);//初始化Lcd,功能设定使用扩充指令
LCD_write_byte(0xD0,0);//设定液晶偏置电压
LCD_write_byte(0x20,0);//使用基本指令
LCD_write_byte(0x0C,0);//设定显示模式,正常显示
}
/*-------------------------------------------
LCD_set_XY: 设置LCD坐标函数
输入参数:X:0-83 Y:0-5
编写日期:20080918
---------------------------------------------*/
void LCD_set_XY(unsigned char X, unsigned char Y)
{
LCD_write_byte(0x40 | Y, 0);// column
LCD_write_byte(0x80 | X, 0);// row
}
/*------------------------------------------
LCD_clear: LCD清屏函数
编写日期:20080918
--------------------------------------------*/
void LCD_clear(void)
{
unsigned char t;
unsigned char k;
LCD_set_XY(0,0);
for(t=0;t<6;t++)
{
for(k=0;k<84;k++)
{
LCD_write_byte(0x00,1);
}
}
}
void LCD_write_zifu(unsigned int x, unsigned int y,unsigned char dd) //x:x坐标 y:y坐标 dd:字符
{
unsigned char i=0;
unsigned int No;
No=dd-32; //字模数据是由空格开始,空格字符的ASCII的值就是32
No*=5;
LCD_set_XY(x,y);
dc1;
while(i<5) //一个字符的字模是5个字节,就是5*8点阵
{
LCD_write_byte(pgm_read_byte(&data222[No]),1);
i++;
No++;
}
}
/*---------------------------------------------
LCD_write_shu: 显示8(宽)*16(高)点阵列数字字母符号等半角类
输入参数:c:显示的字符;
编写日期:20080918
-----------------------------------------------*/
void LCD_write_zifustr(unsigned int x, unsigned int y,unsigned char *string) //x:x坐标 y:y坐标 dd:字符
{
unsigned char i=0;
while(i<strlen(string))
{
LCD_write_zifu(x,y,string[i]); //顺序显示字符
i++;
x=x+7;
}
}
/*************ADC*******************/
#define ADC_VREF_TYPE 0xC0// 参考电压使用内部1.1v时请悬空VREF
unsigned int ADData; //AD转换获得的数据
unsigned int data;
unsigned char data1,data2;
void adc_init()
{
PORTC=0x00;//初始用到的输入通道
DDRC=0x00;
ADMUX=ADC_VREF_TYPE;//配置ADC的参考电压
ADCSRA=0x85; //10000101,使能ACD,分频比为64
}
unsigned int read_adc(unsigned char adc_input)//adc_input,第几通道
{
ADMUX=adc_input|ADC_VREF_TYPE;//配置通道,同时不改变原来的设置
ADCSRA|=0x40; //01000000,启动转换
while ((ADCSRA & 0x10)==0); //00010000,等待转换结束
ADCSRA|=0x10; //清楚中断标志位,应注意,不管ADIE置位与否,转换结束,ADIF都置位
return ADCW; //返回转换数据,有效
}
/***************************************/
void main(void)
{
char v_tmp[32]="\0";
unsigned long i=0,val = 1100;// val 参考电压mV 使用的内部的1.1基准
LCD_init();
LCD_clear();
adc_init();
while (1)
{
data = read_adc(0);// 读取0通道
data1= (unsigned char) data;// L位
data = data >>8;
data2= (unsigned char) data;// H位
data = data2<<8 | data1;//获取有效的10位数据
LCD_write_zifustr(0,1,"ADC TEST");
i = (val*data)/0x3ff;
sprintf(v_tmp,"%04dmV",i);//转换数据显示,加上了mV字样
LCD_write_zifustr(0,3,v_tmp);//LCD显示数据
};
}