AVR 328pb ADC基本介绍和使用

AVR 328pb ADC基本介绍和使用


  • 📍结合参考同架构lgt8f328p中文文档:http://www.prodesign.com.cn/wp-content/uploads/2023/03/LGT8FX8P_databook_v1.0.4.pdf

📘328pb ADC特性

• 10-bit Resolution 10位分辨率
• 0.5 LSB Integral Non-linearity 0.5 LSB积分非线性
• ± 2 LSB Absolute Accuracy ±2 LSB绝对精度
• 13 - 260 μs Conversion Time 13-260μs转换时间
• Up to 76.9 kSPS (Up to 15 kSPS at Maximum Resolution) 高达76.9 kSPS(最大分辨率高达15 kSPS)
• 6 Multiplexed Single Ended Input Channels 6个多路复用单端输入通道
• 2 Additional Multiplexed Single Ended Input Channels (TQFP and QFN/MLF Package only) 2个额外的多路复用单端输入通道(仅限TQFP和QFN/MLF封装)
• Temperature Sensor Input Channel 温度传感器输入通道
• Optional Left Adjustment for ADC Result Readout ADC结果读数的可选左调整
• 0 - VCC ADC Input Voltage Range ADC结果读出的可选左调整0 - VCC
• Selectable 1.1V ADC Reference Voltage 可选1.1V ADC参考电压
• Free Running or Single Conversion Mode 自由运行或单次转换模式
• Interrupt on ADC Conversion Complete ADC转换完成时中断
• Sleep Mode Noise Canceler 睡眠模式降噪器

  • 🍁中断向量表:
    在这里插入图片描述

  • ADC模数转换器块原理图
    在这里插入图片描述

  • ADC自动触发逻辑
    在这里插入图片描述

  • ADC转换和分频
    在这里插入图片描述
    默认情况下,逐次近似电路需要一个输入频率在50 kHz和200 kHz之间的时钟频率,以获得最大分辨率。如果需要低于10位的分辨率,则对ADC的输入时钟频率可以高于200 kHz,以获得更高的采样率。

  • ADC时序图,第一次转换(单次转换模式)
    在这里插入图片描述

  • ADC定时图,自动触发转换

在这里插入图片描述

  • ⌛ADC转换时间
    在这里插入图片描述

📓ADC 参考电压

ADC的参考电压(VREF)表示ADC的转换范围。超过VREF的单端通道将导致代码接近0x3FF。VREF可以选择为AVCC、内部1.1V参考或外部AREF引脚。

📘ADC 相关寄存器

  • 🌿ADC多路复用器选择寄存器:ADMUX
    在这里插入图片描述
  • 🔖6-7位决定ADC参考电压选择。

位5-ADLAR: ADC左调整结果ADLAR位影响ADC转换结果在ADC数据寄存器中的呈现。向左写入一个ADLAR调整结果。否则,结果右调整。更改ADLAR位将立即影响ADC数据寄存器,而不管任何正在进行的转换。有关该位的完整描述,请参阅ADCL和ADCH。
位3:0-MUX[3:0]:模拟通道选择这些位的值选择哪些模拟输入连接到ADC。如果在转换期间更改了这些位,则在此转换完成之前更改不会生效。
在这里插入图片描述
在这里插入图片描述

  • ADC控制和状态寄存器A:ADCSRA
    在这里插入图片描述
    在这里插入图片描述

  • ADC控制和状态寄存器B:ADCSRB
    在这里插入图片描述

  • ADC数据寄存器低字节和高字节(ADLAR=0):ADCL and ADCH
    ADCL和ADCH寄存器对代表16位值,ADC数据寄存器。低字节[7:0](后缀L)可在原始偏移量处访问。高字节[15:8](后缀H)可在偏移量+0x01处访问。有关读取和写入16位寄存器的更多详细信息,请参阅访问16位定时器/计数器寄存器。当ADC转换完成时,结果在这两个寄存器中找到。当读取ADCL时,ADC数据寄存器不会更新,直到读取ADCH。因此,如果结果保持调整,并且不需要超过8位精度,则读取ADCH就足够了。否则,必须先读取ADCL,然后再读取ADCH。ADLAR位和ADMUX中的MUXn位会影响从寄存器读取结果的方式。如果设置了ADLAR(ADLAR=1),则结果向左调整。如果ADLAR被清除(ADLAR=0,这是默认值),则结果向右调整。
    在这里插入图片描述

  • ADC数据寄存器低字节和高字节(ADLAR=1):(ADCL and ADCH)
    ADCL和ADCH寄存器对代表16位值,ADC数据寄存器。低字节[7:0](后缀L)可在原始偏移量处访问。高字节[15:8](后缀H)可在偏移量+0x01处访问。有关读取和写入16位寄存器的更多详细信息,请参阅访问16位定时器/计数器寄存器。当ADC转换完成时,结果在这两个寄存器中找到。当读取ADCL时,ADC数据寄存器不会更新,直到读取ADCH。因此,如果结果保持调整,并且不需要超过8位精度,则读取ADCH就足够了。否则,必须先读取ADCL,然后再读取ADCH。ADLAR位和ADMUX中的MUXn位会影响从寄存器读取结果的方式。如果设置了ADLAR(ADLAR=1),则结果向左调整。如果ADLAR被清除(ADLAR=0,这是默认值),则结果向右调整。
    在这里插入图片描述

📗测试例程

  • 📝例程采用AREF引脚的使用5V供电电压作为参考。采集通道0(PC0引脚)输入电压值。
//官方ADC例程编号:AN17644 Getting STARTED with AVR
#include "atmel_start.h"#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include "stdio.h"uint16_t adc_res = 0;/**************************************************************
PIN change interrupt ISR
LED toggle code is commented as LED dimming code has been added in main
****************************************************************/ISR(PCINT0_vect)
{// 	if (!(PINB & (1<<PINB7))) // if PINB7 is low (Switch pressed)// 	{// 		PORTB |= (1<<PORTB5); // Turn ON LED// 	}// 	else// 	{// 		PORTB &= ~(1<<PORTB5); // Turn OFF LED// 	}
}uint16_t ReadADC(uint8_t ADCchannel)
{// select ADC channel with safety maskADMUX = (ADMUX & 0xF0) | (ADCchannel & 0x0F);//// single conversion modeADCSRA |= (1 << ADSC);// wait until ADC conversion is completewhile (ADCSRA & (1 << ADSC));return ADC;
}
void optimize_power_consumption()
{DIDR0 |= 0xC0; /*ADC7D and ADC6D are undefined in header file so set bits this way*//* Disable digital input buffer on Analog comparator pins */DIDR1 |= (1 << AIN1D) | (1 << AIN0D);/* Disable Analog Comparator */ACSR |= (1 << ACD);/*Watchdog Timer OFF*//* Disable interrupts */cli();/* Reset watchdog timer */wdt_reset();/* Clear WDRF in MCUSR */MCUSR &= ~(1 << WDRF);/* Turn off WDT */WDTCSR = 0x00;/* Set sleep mode */set_sleep_mode(SLEEP_MODE_PWR_DOWN);
}int main(void)
{system_init();optimize_power_consumption();TIMSK1 |= (1 << OCIE1A); // Enable output compare match A interruptPCMSK0 |= (1 << PCINT7); // Enable Pin Change Interrupt 7PCICR |= (1 << PCIE0);   // Enable the interrupt enable bit for PCINTsei();while (1){ADCSRA &= ~(1 << ADEN);//禁用ADCpower_adc_disable();sleep_mode();power_adc_enable();//AVCC AREF使用5V供电电压作为参考ADCSRA |= (1 << ADEN);//使能ADCadc_res = ReadADC(0);//通道0:PC0printf("adc_value:%d",adc_res);_delay_ms(1000);LED_toggle_level();}return 0;
}
  • 裸机ADC0测试代码
/** USART_PRINTF.c** Created: 2024/2/8 19:50:27* Author : Administrator*/#include <avr/io.h>
#include "util/delay.h"
//#include "util/setbaud.h"
#include "avr/sfr_defs.h"//包含loop_until_bit_is_set函数
#include "avr/interrupt.h"
// Standard Input/Output functions
#include <stdio.h>// Voltage Reference: AVCC pin
#define ADC_VREF_TYPE ((0<<REFS1) | (1<<REFS0) | (0<<ADLAR))// Read the AD conversion result
unsigned int ReadADC(unsigned char adc_input)
{ADMUX=adc_input | ADC_VREF_TYPE;// Delay needed for the stabilization of the ADC input voltage_delay_us(10);// Start the AD conversionADCSRA|=(1<<ADSC);// Wait for the AD conversion to completewhile ((ADCSRA & (1<<ADIF))==0);ADCSRA|=(1<<ADIF);return ADCW;
}// ADC initialization
void ADC_Init(void)
{// ADC Clock frequency: 125.000 kHz// ADC Voltage Reference: AVCC pin// ADC Auto Trigger Source: Free Running// Digital input buffers on ADC0: Off, ADC1: On, ADC2: On, ADC3: On// ADC4: On, ADC5: On, ADC6: On, ADC7: OnDIDR0=(0<<ADC7D) | (0<<ADC6D) | (0<<ADC5D) | (0<<ADC4D) | (0<<ADC3D) | (0<<ADC2D) | (0<<ADC1D) | (1<<ADC0D);ADMUX=ADC_VREF_TYPE;ADCSRA=(1<<ADEN) | (0<<ADSC) | (1<<ADATE) | (0<<ADIF) | (0<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);// Ensure that the ADC is enabledPRR0&= ~(1<<PRADC);
}static int	uart_putchar(char c, FILE *stream)
{//   if (c == '\n')//       uart_putchar('\r', stream);//   loop_until_bit_is_set(UCSR0A, UDRE0);//需包含:avr/sfr_defs.h// /* Wait for empty transmit buffer */while ( !( UCSR0A & (1<<UDRE0)) );UDR0 = c;return 0;
}// 配置输出流
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,_FDEV_SETUP_WRITE);
//static FILE USART0_stream = FDEV_SETUP_STREAM(NULL, uart_getchar, _FDEV_SETUP_RW);//#define BAUD 9600
#define F_CPU 16000000UL
#define MYUBRR (F_CPU/16/BAUD-1)// 串口初始化
void USART0_Init(void)
{UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0) | (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);/*Enable receiver and transmitter */UCSR0B=(1<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (1<<RXEN0) | (1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);/* Set frame format: 8data, 1stop bit */UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) | (0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);/*Set baud rate */UBRR0H = (unsigned char)(MYUBRR>>8);UBRR0L = (unsigned char)MYUBRR;stdout = &mystdout;//输出流配置// Ensure that the USART0 is enabledPRR0&= ~(1<<PRUSART0);// Globally enable interruptssei();}
void USART_Transmit( unsigned char data )
{/* Wait for empty transmit buffer */while ( !( UCSR0A & (1<<UDRE0)) );/* Put data into buffer, sends the data */UDR0 = data;
}unsigned char USART_Receive( void )
{/* Wait for data to be received */while ( !(UCSR0A & (1<<RXC0)) );/* Get and return received data from buffer */return UDR0;
}void SYS_Clock_Init()
{CLKPR=(1<<CLKPCE);CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
}int main(void)
{/* Replace with your application code */unsigned int adc_res;SYS_Clock_Init();USART0_Init();DDRB = PINB5;//配置PB5为输出模式ADC_Init();//ADC initializationwhile (1){PORTB ^= (1 << PINB5);//PB5状态翻转_delay_ms(1000); // 使用util/delay.h中的宏函数来实现1毫秒的延时adc_res = ReadADC(0);//通道0:PC0printf("adc_value:%d",adc_res);}
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2775686.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Java stream 流的基本使用

Java stream 的基本使用 package com.zhong.streamdemo.usestreamdemo;import jdk.jfr.DataAmount; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.util.ArrayList; import java.util.Comparator; import java.util.Li…

LabVIEW网络测控系统

LabVIEW网络测控系统 介绍了基于LabVIEW的网络测控系统的开发与应用&#xff0c;通过网络技术实现了远程的数据采集、监控和控制。系统采用LabVIEW软件与网络通信技术相结合&#xff0c;提高了系统的灵活性和扩展性&#xff0c;适用于各种工业和科研领域的远程测控需求。 随着…

基于微信小程序的新生报到系统的研究与实现,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

【Linux】Shell编程

Shell编程 目录 Shell编程1.shell基础1.输入重定向 & 输出重定向2.管道3.特殊字符(3.1)通配符(3.2)引号(3.3)注释符(#) 4.别名5.命令历史history 2.Shell脚本Shell脚本的执行方式(1)为脚本文件加上可执行权限,然后在命令行直接输入shell脚本文件名执行。(2)sh shell脚本名(…

基于Robei EDA--实现串口通信

一、串口简介 串口作为常用的三大低速总线&#xff08;UART、SPI、IIC&#xff09;之一&#xff0c;在设计众多通信接口和调试时占有重要地位。但UART和SPI、IIC不同的是&#xff0c;它是异步通信接口&#xff0c;异步通信中的接收方并不知道数据什么时候会到达&#xff0c;所…

深度优先搜索(DFS)与广度优先搜索(BFS):探索图与树的算法

一、引言 在图论和树形结构中&#xff0c;搜索算法是寻找从起点到终点的路径的关键。其中&#xff0c;深度优先搜索&#xff08;DFS&#xff09;和广度优先搜索&#xff08;BFS&#xff09;是最常用且最基础的两种搜索算法。本文将详细介绍广度优先搜索&#xff08;BFS&#xf…

C#上位机与三菱PLC的通信03--MC协议之A-1E报文解析

1、MC协议帧 MC协议可以在串口通信&#xff0c;也可以在以太网通信&#xff0c;有A-1E和Qna-3E两种模式&#xff0c;这两种都是三菱PLC通信协议中比较常用的两种&#xff0c;一般我们使用比较多的是以太网通信&#xff0c;对于FX5U系列/Q系列/Qna系列/L系列的PLC&#xff0c;…

目标检测 | 卷积神经网络(CNN)详细介绍及其原理详解

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;是一种深度学习模型&#xff0c;主要用于图像识别和计算机视觉任务。它的设计灵感来自于生物学中视觉皮层的工作原理。CNN的核心思想是通…

Stable Diffusion教程——使用TensorRT GPU加速提升Stable Diffusion出图速度

概述 Diffusion 模型在生成图像时最大的瓶颈是速度过慢的问题。为了解决这个问题&#xff0c;Stable Diffusion 采用了多种方式来加速图像生成&#xff0c;使得实时图像生成成为可能。最核心的加速是Stable Diffusion 使用了编码器将图像从原始的 3512512 大小转换为更小的 46…

Leetcode刷题笔记题解(C++):面试题 08.07. 无重复字符串的排列组合

思路&#xff1a;因为字符之间互不相同&#xff0c;故使用全排列的方式去解题&#xff1b; 字符串长度为n&#xff0c;将第一个字母分别与后面每一个字母进行交换&#xff0c;生成n种不同的全排列&#xff1b;再用第二个元素与后面每一个元素进行交换&#xff0c;生成n - 1种不…

Transformer的PyTorch实现之若干问题探讨(一)

《Transformer的PyTorch实现》这篇博文以一个机器翻译任务非常优雅简介的阐述了Transformer结构。在阅读时存在一些小困惑&#xff0c;此处权当一个记录。 1.自定义数据中enc_input、dec_input及dec_output的区别 博文中给出了两对德语翻译成英语的例子&#xff1a; # S: de…

《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述(10)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第II篇 第4章 PCIe总线概述&#xff08;9&#xff09; 4.2 PCIe体系结构的组成部件 PCIe总线作为处理器系统的局部总线&#xff0c;其作用与PCI总线类似&#xff0c;主要目的是为了连接处理器系统中的外部设备&…

Vue源码系列讲解——虚拟DOM篇【二】(Vue中的DOM-Diff)

目录 1. 前言 2. patch 3. 创建节点 4. 删除节点 5. 更新节点 6. 总结 1. 前言 在上一篇文章介绍VNode的时候我们说了&#xff0c;VNode最大的用途就是在数据变化前后生成真实DOM对应的虚拟DOM节点&#xff0c;然后就可以对比新旧两份VNode&#xff0c;找出差异所在&…

MATLAB知识点:使用逻辑值修改或删除矩阵元素

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第3章 3.4.4 逻辑运算 3.4.4.3 使用逻辑值修改或删…

Elasticsearch(四)

是这样的前面的几篇笔记&#xff0c;感觉对我没有形成知识体系&#xff0c;感觉乱糟糟的&#xff0c;只是大概的了解了一些基础知识&#xff0c;仅此而已&#xff0c;而且对于这技术栈的学习也是为了在后面的java开发使用&#xff0c;但是这里的API学的感觉有点乱&#xff01;然…

熔断机制解析:如何用Hystrix保障微服务的稳定性

微服务与系统的弹性设计 大家好,我是小黑,在讲Hystrix之前,咱们得先聊聊微服务架构。想象一下,你把一个大型应用拆成一堆小应用,每个都负责一部分功能,这就是微服务。这样做的好处是显而易见的,更新快,容错性强,每个服务可以独立部署,挺美的对吧?但是,问题也随之而…

PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证

文章目录 Openssl操系统默认的CA证书的公钥位置Nginx Https 自签证书Nginx Https 使用CA签发证书客户端使用自签证书供服务端验证客户端使用 根证书 签发客户端证书 供服务端验证 Openssl https://www.openssl.net.cn/ openssl是一个功能丰富且自包含的开源安全工具箱。 它提…

放假--寒假自学版 day1(补2.5)

fread 函数&#xff1a; 今日练习 C语言面试题5道~ 1. static 有什么用途&#xff1f;&#xff08;请至少说明两种&#xff09; 1) 限制变量的作用域 2) 设置变量的存储域 2. 引用与指针有什么区别&#xff1f; 1) 引用必须被初始化&#xff0c;指针不必。 2) 引用初始…

无心剑七绝《龙年大吉》

七绝龙年大吉 龙腾五岳九州圆 年吼佳音万里传 大漠苍鹰华夏梦 吉人天相铸奇缘 2024年2月8日 平水韵一先平韵 这首藏头七绝《龙年大吉》是无心剑为2024年春节所创作的诗作。2024年是农历的甲辰年&#xff0c;即龙年。在中国传统文化中&#xff0c;龙是吉祥的象征&#xff0c;代表…

PSM-Net根据Stereo图像生成depth图像

一、新建文件夹 在KITTI数据集下新建depth_0目录 二、激活anaconda环境 conda activate pt14py37三、修改submission.py文件 3.1 KITTI数据集路径 parser.add_argument(--datapath, default/home/njust/KITTI_DataSet/00/, helpselect model)3.2 深度图像输出路径 save…