》》点此进入 http://bbs.armavr.com/ ARM-AVR嵌入式开发论坛
ARM-AVR嵌入式开发论坛,专为AVR单片机初学者而建,以资源共享、经验交流为主旨,以共同进步和提高为目标。期待志同道合的朋友加入!
【相关实验】
【ATMEGA16L】实验一:流水灯实验(八种LED点亮模式)
【ATMEGA16L】实验三:按键扫描(用KEY选择对应LED点亮)
【ATMEGA16L】实验四:键盘扫描+8种LED亮灭模式控制
【ATMEGA16L】实验二四:四线制LCD1602B驱动实验
【ATMEGA16L】实验二五:八线制LCD1602B驱动实验
经过两天的突击,终于搞定了实验三三,现贴出与大家共享。
一、硬件电路
二、程序结构
三、程序代码
1、main.c
/*******************************************************************************
Platform: AVR mega16学习板(www.iccavr.com)
Project : 实验三三:ADC&LCD1602&DS1302&USART综合实验
Clock F : 3.6864MHz
Software: ICCAVR7.14C
Author : 林夕依然
Version : 09.04.03-09.04.04
Updata :
comments:
1、串口发送命令'1'开启一次ADC,并将结果通过串口发送到PC,同时在LCD1602上显示;
2、PC和LCD1602也同时显示每次更新ADC转换结果的时间;
3、USART使用中断方式接收数据,当接收到指定数据后,开启一次ADC转换;
4、当ADC转换完成后产生中断,并置位一个自定义的标志;
5、检测ADC转换完成后的中断标志,为1时则将ADC转换数据发送给PC,同时在LCD1602显示;
6、4种不同的配置方式;
7、参考:实验25,实验26,实验28,实验30
problem :
1、存放ADC转换结果的AdcData要定义为uint,当定义为uchar时,PC和LCD1602接收均错误
04-03晚出现了此问题,04-04才找到问题的原因。
*******************************************************************************/
#include <iom16v.h>
#include <macros.h>
#include "ds1302.h"
#include "LCD1602.h"
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
uint AdcData; //存放ADC转换的结果
uchar AdcConCom = 0; //ADC转换完成标志
/*-----------------------------------------------------------------
函数名称: void AdcInit(void)
函数功能: ADC初始化
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void AdcInit(void)
{
ADCSR = 0x00; //ADC关闭
ADMUX = 0x67; //1:外部参考源AVCC,左对齐,选择ADC7通道
//ADMUX = 0x46; //2:外部参考源AVCC,右对齐,选择ADC7通道
//ADMUX = 0xE0; //3:2.56V 的片内基准电压源,左对齐,选择ADC0通道
//ADMUX = 0xC1; //4:2.56V 的片内基准电压源,右对齐,选择ADC0通道
ACSR = 0x80; //模拟比较器控制和状态寄存器ACSR的ACD置1,使模拟比较器禁用
ADCSR = 0x8B; //开启ADC,8分频,ADC中断使能
}
/*-----------------------ADC转换中断程序--------------------------------------*/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{
AdcData=(uint)((ulong)ADCH * 4930 / 256); //1:将AD值转换为电压值(只读高8位)
//AdcData=(uint)((ulong)ADC * 4930 / 1024); //2:将AD值转换为电压值(读所有位)
//AdcData=(uint)((ulong)ADCH * 2635 / 256); //3:将AD值转换为电压值(只读高8位)
//AdcData=(uint)((ulong)ADC * 2635 / 1024); //4:将AD值转换为电压值(读所有位)
AdcConCom = 1; //置ADC转换完成标志
}
/*-----------------------------------------------------------------
函数名称: void InitDevices(void)
函数功能: 初始化各种信息
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void InitDevices(void)
{
CLI(); //关全部中断
Usart_init03(); //中断方式初始化
Port_init();
AdcInit();
ds1302_init(); //DS1302初始化
delay_ms(10);
ds1302_write_time(); //写入初始值
LCD_init(); //LCD初始化
LCD_clear();//清屏
LCD_write_str(0,0,"09-04-05 ACDtest");
LCD_write_str(0,1,"ADC is so easy!");
//delay_ms(2000);
MCUCR = 0x00;
SEI(); //开全中断
}
void main(void)
{
unsigned char temp;
InitDevices();
while(1)
{
if(AdcConCom)
{
AdcConCom = 0; //清ADC转换完成标志
//将电压值发送给PC
USART_Transmit(AdcData/1000 + 0x30); //得到电压值的千位并发送
USART_Transmit('.'); //发送小数点
USART_Transmit(AdcData%1000/100 + 0x30); //得到电压值的百位并发送
USART_Transmit(AdcData%100/10 + 0x30); //得到电压值的十位并发送
USART_Transmit(AdcData%10 + 0x30); //得到电压值的个位并发送
USART_Transmit('V'); //发送电压符号"V"
newline(); //换行
//读取时间并将其显示在LCD1602上
ds1302_read_time(); //读取时间
LCD_clear(); //清屏
temp = (time_buf[0] >> 4) + '0';
LCD_write_char(0, 1, temp);/*年*/
USART_Transmit(temp);
temp = (time_buf[0] & 0x0F) + '0';
LCD_write_char(1, 1, temp);
USART_Transmit(temp);
temp = (time_buf[1] >> 4) + '0';
LCD_write_char(2, 1, temp);
USART_Transmit(temp);
temp = (time_buf[1] & 0x0F) + '0';
LCD_write_char(3, 1, temp);
USART_Transmit(temp);
LCD_write_char(4, 1, '-');
USART_Transmit('-');
temp = (time_buf[2] >> 4) + '0';
LCD_write_char(5, 1, temp);/*月*/
USART_Transmit(temp);
temp = (time_buf[2] & 0x0F) + '0';
LCD_write_char(6, 1, temp);
USART_Transmit(temp);
LCD_write_char(7, 1, '-');
USART_Transmit('-');
temp = (time_buf[3] >> 4) + '0';
LCD_write_char(8, 1, temp);/*日*/
USART_Transmit(temp);
temp = (time_buf[3] & 0x0F) + '0';
LCD_write_char(9, 1, temp);
USART_Transmit(temp);
blank();
//temp = (time_buf[7]) + '0';
//LCD_write_char(1, 1, temp); //不显示周
temp = (time_buf[4] >> 4) + '0';
LCD_write_char(11, 1, temp); //时
USART_Transmit(temp);
temp = (time_buf[4] & 0x0F) + '0';
LCD_write_char(12, 1, temp);
USART_Transmit(temp);
LCD_write_char(13, 1, ':');
USART_Transmit(':');
temp = (time_buf[5] >> 4) + '0';
LCD_write_char(14, 1, temp);/*分*/
USART_Transmit(temp);
temp = (time_buf[5] & 0x0F) + '0';
LCD_write_char(15, 1, temp);
USART_Transmit(temp);
newline(); //换行
//LCD_write_char(13, 1, ':');
//temp = (time_buf[6] >> 4) + '0';
//LCD_write_char(14, 1, temp); //秒不显示
//temp = (time_buf[6] & 0x0F) + '0';
//LCD_write_char(15, 1, temp);
//将电压值显示在LCD1602上
LCD_write_char(0, 0, 'A');
LCD_write_char(1, 0, 'D');
LCD_write_char(2, 0, 'C');
LCD_write_char(3, 0, '=');
LCD_write_char(4, 0, AdcData/1000 + 0x30);
LCD_write_char(5, 0, '.');
LCD_write_char(6, 0, AdcData%1000/100 + 0x30);
LCD_write_char(7, 0, AdcData%100/10 + 0x30);
LCD_write_char(8, 0, AdcData%10 + 0x30);
LCD_write_char(9, 0, 'V');
}
}
}
/******************************4种不同配置测试*********************************
1、ADMUX = 0x67; //1:外部参考源AVCC,左对齐,选择ADC7通道
实测为1.824V,PC接收为1.810V,误差不足0.05V
2、ADMUX = 0x46; //2:外部参考源AVCC,右对齐,选择ADC7通道
实测为1.824V,PC接收为1.810V-1.829V,误差不足0.05V
3、ADMUX = 0xE0; //3:2.56V 的片内基准电压源,左对齐,选择ADC0通道
实测为1.824V,PC接收为1.811V-1.824V,误差不足0.05V
4、ADMUX = 0xC1; //4:2.56V 的片内基准电压源,右对齐,选择ADC0通道
实测为1.823V,PC接收为1.819V-1.827V,误差不足0.05V
*****************************************************************************/
2、function.c
#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define F_CPU 3686400
/*-----------------------------------------------------------------
函数名称: void Usart_init01(void)
函数功能: 串口初始化方式01(波特率设置用查表)
波特率 9600 0.2% ,8bit,异步,倍速,无奇偶校验,1个停止位
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init01(void) //初始化串口方式1
{
UCSRA="0X02"; //倍速选择
UCSRB=(1<<RXEN)|(1<<TXEN); //使能接收,发送
UCSRC=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);//8bit,异步,无奇偶校验,1个停止位
UBRR="47"; //9600波特率,见M16_cn中文P155:Table68-72通用振荡器频率下设置 UBRR
}
/*-----------------------------------------------------------------
函数名称: void Usart_init02(void)
函数功能: 串口初始化方式02(波特率设置用公式)
波特率 9600 0.2% 8bit,异步,常速,无奇偶校验,2个停止位
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init02( unsigned int baud )//初始化串口方式2,并设置波特率
{
unsigned int tmp;
tmp= F_CPU/baud/16-1; //设置波特率,见M16_cn中文P135:Table60波特率计算公式
UBRRH = (unsigned char)(tmp>>8);
UBRRL = (unsigned char)tmp;
UCSRB = (1<<RXEN)|(1<<TXEN); //接收器与发送器使能
UCSRC = (1<<URSEL)|(1<<USBS)|(1<<UCSZ0)|(1<<UCSZ1);//异步,8bit,2停止位,无奇偶校验
}
/*-----------------------------------------------------------------
函数名称: void Usart_init03(void)
函数功能: 串口初始化方式03(中断方式接收)
波特率 9600 0.2%,8bit,异步,倍速,无奇偶校验,1个停止位
参 数:
返 回 值: 无
-----------------------------------------------------------------*/
void Usart_init03(void)
{
UCSRB = 0x00; //关串口
UCSRA = 0x02; //倍速模式 M16中文P151
UCSRC = BIT(URSEL) | 0x06; //写UCSRC寄存器,设定8个bit,1停止位,异步
UBRR = 47; //设定串口波特率为9600
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);//使能接收结束中断,使能收发
}
#pragma interrupt_handler UartRecvData:12
void UartRecvData(void)
{
uchar temp;
temp = UDR;
if(temp=='1') //如果接到到1,则开启一次ADC转换
ADCSRA|= (1<<ADSC); //开启一次ADC转换
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmit( unsigned char data )
函数功能: 数据发送【发送5 到8 位数据位的帧】
参 数:
返 回 值: 无
说 明:直接从数据手册上拷贝过来的
-----------------------------------------------------------------*/
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) ) ; //等待发送缓冲器为空
UDR = data; // 将数据放入缓冲器,发送数据
}
/*-----------------------------------------------------------------
函数名称: unsigned char USART_Receive( void )
函数功能: 数据接收【以5 到8 个数据位的方式接收数 据帧】
参 数:
返 回 值: UDR
说 明:直接从数据手册上拷贝过来的
-----------------------------------------------------------------*/
unsigned char USART_Receive( void )
{
while ( !(UCSRA & (1<<RXC)) ); // 等待接收数据
return UDR; // 从缓冲器中获取并返回数据
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmits01( void )
函数功能: 连续发送字符"Hello"
参 数:
返 回 值:
-----------------------------------------------------------------*/
void USART_Transmits01( void )
{
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'H';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'e';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'l';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'l';
while ( !( UCSRA & (1<<UDRE)) );
UDR = 'o';
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmits02(unsigned char *str)
函数功能: 发送字符串(方法一)
参 数: str 发送字符串的首地址
返 回 值:
说 明:已通过验证,str必须定义为指针,调用时只需指针名即可
例 如:定义指针 uchar *buffer0="2009年03月26日23:40";
调用函数 USART_Transmits02(buffer0); 即可
-----------------------------------------------------------------*/
void USART_Transmits02(unsigned char *ptr)//字符串
{
while (*ptr)
{
USART_Transmit(*ptr);
*ptr++;
}
newline();
}
/*-----------------------------------------------------------------
函数名称: void USART_Transmits03(uchar *str, uint len)
函数功能: 发送字符串(方法二)
参 数: str 发送字符串的首地址
len 发送字符串的长度
返 回 值:
说 明:已通过验证,str必须定义为指针,调用时只需指针名即可
例 如:定义指针 uchar *buffer0="2009年03月26日23:40";
调用函数 USART_Transmits03(buffer0,19); 即可
-----------------------------------------------------------------*/
void USART_Transmits03(uchar *str,uint len)
{
uint i;
for( i = 0; i < len; i++)
{
while ( !( UCSRA & (1<<UDRE)) ); //等待发送缓冲器为空
UDR = str;
}
}
void newline() //换行
{
USART_Transmit(0x0d); //发送一个回车
USART_Transmit(0x0a); //发送一个换行
}
void blank() //空格
{
USART_Transmit(0x20);
}
/************************************************
UMSEL 模式选择
0 异步操作
1 同步操作
USBS 停止位位数
0 1
1 2
UCSZ2 UCSZ1 UCSZ0 字符长度
0 0 0 5 位
0 0 1 6 位
0 1 0 7 位
0 1 1 8 位
1 0 0 保留
1 0 1 保留
1 1 0 保留
1 1 1 9 位
*************************************************/
3、LCD1602.c
/*******************************
Platform : AVR mega16学习板(www.iccavr.com)
function :LCD1602八线制功能函数集
Clock F : 3.6864M
Software : ICCAVR7.14C
Author : 林夕依然
Version : 09.04.03
comments :
1、两种方式实现延时
********************************/
#include <iom16v.h>
#include <macros.h>
#include "LCD1602.h"
//us延时函数
void delay_us(uint n) //4*0.27=1.08us
{
int i,j;
for(j=0;j<4;j++)
{
for (i=0;i<n;i++)
NOP();
}
}
//ms延时函数
void delay_ms(uint i)
{
while(i--)
{
uint j;
for(j=1;j<=613;j++)
;
}
}
//端口初始化
void Port_init()
{
//PORTA=0XFF; //不对ADC通道进行设置
//DDRA =0X00;
PORTB="0XFF";
DDRB =0X00;
PORTC="0X7F";
DDRC =0X80;
PORTD="0XFF";
DDRD =0X00;
}
//显示屏初始化函数
void LCD_init(void)
{
DDRB = 0xFF; //I/O口方向设置
DDRD|=(1<<PD3)|(1<<PD4)|(1<<PD6);
delay_ms(15); //上电延时一段时间,使供电稳定
Write_Instruction(0x38); //8bit interface,2line,5*7dots
delay_ms(5);
Write_Instruction(0x38);
delay_ms(5);
Write_Instruction(0x38);
Write_Instruction(0x08); //关显示,不显光标,光标不闪烁
Write_Instruction(0x01); //清屏
delay_ms(5);
Write_Instruction(0x04); //写一字符,整屏显示不移动
//Write_Instruction(0x05); //写一字符,整屏右移
//Write_Instruction(0x06); //写一字符,整屏显示不移动
//Write_Instruction(0x07); //写一字符,整屏左移
delay_ms(5);
//Write_Instruction(0x0B); //关闭显示(不显示字符,只有背光亮)
Write_Instruction(0x0C); //开显示,光标、闪烁都关闭
//Write_Instruction(0x0D); //开显示,不显示光标,但光标闪烁
//Write_Instruction(0x0E); //开显示,显示光标,但光标不闪烁
//Write_Instruction(0x0F); //开显示,光标、闪烁均显示
}
//控制LCD写时序
void LCD_en_write(void) //EN端产生一个高电平脉冲,控制LCD写时序
{
EN_SET;
delay_us(3);
EN_CLR;
delay_us(3);
}
//清屏函数
void LCD_clear()
{
Write_Instruction(0x01);
delay_ms(5);
}
//写指令函数
void Write_Instruction(uchar command)
{
RS_CLR;
RW_CLR;
EN_SET;
PORTB="command";
LCD_en_write();//写入指令数据
}
//写数据函数
void Write_Data(uchar Wdata)
{
RS_SET;
RW_CLR;
EN_SET;
PORTB="Wdata";
LCD_en_write();//写入数据
}
//字符显示初始地址设置
void LCD_SET_XY(uchar X,uchar Y)
{
uchar address;
if(Y==0)
address="0x80"+X;//Y=0,表示在第一行显示,地址基数为0x80
else
address="0xc0"+X;//Y非0时,表时在第二行显示,地址基数为0XC0
Write_Instruction(address);//写指令,设置显示初始地址
}
//在第X行Y列开始显示,指针*S所指向的字符串
void LCD_write_str(uchar X,uchar Y,uchar *s)
{
LCD_SET_XY(X,Y);//设置初始字符显示地址
while(*s)//逐次写入显示字符,直到最后一个字符"/0"
{
Write_Data(*s);//写入当前字符并显示
s++;//地址指针加1,指向下一个待写字符
}
}
//在第X行Y列开始显示Wdata所对应的单个字符
void LCD_write_char(uchar X,uchar Y,uchar Wdata)
{
LCD_SET_XY(X,Y);//写地址
Write_Data(Wdata);//写入当前字符并显示
}
4、DS1302.C
#include <iom16v.h>
/******************复位脚*********************/
#define RST_CLR PORTC &= ~(1 << PC4) /*电平置低*/
#define RST_SET PORTC |= (1 << PC4) /*电平置高*/
#define RST_IN DDRC &= ~(1 << PC4) /*方向输入*/
#define RST_OUT DDRC |= (1 << PC4) /*方向输出*/
/*****************双向数据********************/
#define IO_CLR PORTC &= ~(1 << PC3) /*电平置低*/
#define IO_SET PORTC |= (1 << PC3) /*电平置高*/
#define IO_R PINC & (1 << PC3) /*电平读取*/
#define IO_IN DDRC &= ~(1 << PC3) /*方向输入*/
#define IO_OUT DDRC |= (1 << PC3) /*方向输出*/
/*****************时钟信号*******************/
#define SCK_CLR PORTC &= ~(1 << PC2) /*时钟信号*/
#define SCK_SET PORTC |= (1 << PC2) /*电平置高*/
#define SCK_IN DDRC &= ~(1 << PC2) /*方向输入*/
#define SCK_OUT DDRC |= (1 << PC2) /*方向输出*/
#define ds1302_sec_add 0x80 //秒数据地址
#define ds1302_min_add 0x82 //分数据地址
#define ds1302_hr_add 0x84 //时数据地址
#define ds1302_date_add 0x86 //日数据地址
#define ds1302_month_add 0x88 //月数据地址
#define ds1302_day_add 0x8a //星期数据地址
#define ds1302_year_add 0x8c //年数据地址
#define ds1302_control_add 0x8e //控制数据地址
#define ds1302_charger_add 0x90
#define ds1302_clkburst_add 0xbe
unsigned char time_buf[8] = {0x20,0x09,0x04,0x05,0x01,0x21,0x00,0x03};
//DS1302初始化函数
void ds1302_init(void)
{
RST_CLR; /*RST脚置低*/
SCK_CLR; /*SCK脚置低*/
RST_OUT; /*RST脚设置为输出*/
SCK_OUT; /*SCK脚设置为输出*/
}
//向DS1302写入一字节数据
void ds1302_write_byte(unsigned char addr, unsigned char d) {
unsigned char i;
RST_SET; /*启动DS1302总线*/
/*写入目标地址:addr*/
IO_OUT;
addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET; //产生时钟
SCK_CLR;
addr = addr >> 1;
}
/*写入数据:d*/
IO_OUT;
for (i = 0; i < 8; i ++) {
if (d & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET; //产生时钟
SCK_CLR;
d = d >> 1;
}
RST_CLR; //停止DS1302总线
}
//从DS1302读出一字节数据
unsigned char ds1302_read_byte(unsigned char addr) {
unsigned char i;
unsigned char temp;
RST_SET; /*启动DS1302总线*/
/*写入目标地址:addr*/
IO_OUT;
addr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET;
SCK_CLR;
addr = addr >> 1;
}
/*输出数据:temp*/
IO_IN;
for (i = 0; i < 8; i ++) {
temp = temp >> 1;
if (IO_R) {
temp |= 0x80;
}
else {
temp &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
RST_CLR; /*停止DS1302总线*/
return temp;
}
//向DS302写入时钟数据
void ds1302_write_time(void) {
ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
ds1302_write_byte(ds1302_sec_add,0x80); //暂停时钟
//ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电
ds1302_write_byte(ds1302_year_add,time_buf[1]); //年
ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
ds1302_write_byte(ds1302_date_add,time_buf[3]); //日
ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时
ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
}
//从DS302读出时钟数据
void ds1302_read_time(void) {
time_buf[1]=ds1302_read_byte(ds1302_year_add); //年
time_buf[2]=ds1302_read_byte(ds1302_month_add); //月
time_buf[3]=ds1302_read_byte(ds1302_date_add); //日
time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时
time_buf[5]=ds1302_read_byte(ds1302_min_add); //分
time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7F;//秒,屏蔽秒的第7位,避免超出59
time_buf[7]=ds1302_read_byte(ds1302_day_add); //周
}
5、LCD1602.h
#define uchar unsigned char
#define uint unsigned int
#define RS_CLR PORTD &= ~(1 << PD3)
#define RS_SET PORTD |= (1 << PD3)
#define RW_CLR PORTD &= ~(1 << PD4)
#define RW_SET PORTD |= (1 << PD4)
#define EN_CLR PORTD &= ~(1 << PD6)
#define EN_SET PORTD |= (1 << PD6)
6、ds1302.h
extern unsigned char time_buf[8];
void ds1302_read_time(void);
void ds1302_write_time(void);
void ds1302_init(void);
四、测试附图
1、ADMUX = 0x67; //1:外部参考源AVCC,左对齐,选择ADC7通道
实测为1.824V,PC接收为1.810V,误差不足0.05V
2、ADMUX = 0x46; //2:外部参考源AVCC,右对齐,选择ADC7通道
实测为1.824V,PC接收为1.810V-1.829V,误差不足0.05V
3、ADMUX = 0xE0; //3:2.56V 的片内基准电压源,左对齐,选择ADC0通道
实测为1.824V,PC接收为1.811V-1.824V,误差不足0.05V
4、ADMUX = 0xC1; //4:2.56V 的片内基准电压源,右对齐,选择ADC0通道
实测为1.823V,PC接收为1.819V-1.827V,误差不足0.05V
用户1326417 2009-4-15 11:47
tengjingshu_112148725 2009-4-10 21:50