- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
目的是将最新的 10 个 ADC 读数存储在一个数组中,然后计算它们的平均值以供其他地方使用。每次更新时删除最旧的。
关于 LED 时序,如果 ADC 读数在下面写的边界内,它必须将时序从 1s 切换到 0.25s,如何正确实现?我知道我的方法有效,但可以做得更好。至于 LED,如果按下开关,它们必须改变模式,如您所见,它们确实如此,但我再次确信它可以通过另一种更简单的方式完成!
以下是我的代码,我也确信有很多错误和足够的优化空间,我很乐意接受它!
#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned int timecount0;
unsigned int adc_reading;
volatile uint32_t timing = 1;
volatile uint32_t accumulator = 0;
volatile uint16_t average = 0;
volatile uint16_t samples = 0;
#define LED_RED PORTB = ((PORTB & ~0b00001110)|(0b00000010 & 0b00001110))
#define LED_GREEN PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110))
#define LED_BLUE PORTB = ((PORTB & ~0b00001110)|(0b00000100 & 0b00001110))
#define LED_RGB PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110))
#define DELAY_COUNT 6
volatile uint8_t portdhistory = 0xFF;
void Timer0_init(void)
{
timecount0 = 0; // Initialize the overflow count. Note its scope
TCCR0B = (5<<CS00); // Set T0 Source = Clock (16MHz)/1024 and put Timer in Normal mode
TCCR0A = 0; // Not strictly necessary as these are the reset states but it's good
// practice to show what you're doing
TCNT0 = 61; // Recall: 256-61 = 195 & 195*64us = 12.48ms, approx 12.5ms
TIMSK0 = (1<<TOIE0); // Enable Timer 0 interrupt
PCICR |= (1<<PCIE0);
PCMSK0 |= (1<<PCINT0);
sei(); // Global interrupt enable (I=1)
}
void ADC_init(void)
{
ADMUX = ((1<<REFS0) | (0<<ADLAR) | (0<<MUX0)); /* AVCC selected for VREF,ADLAR set to 0, ADC0 as ADC input (A0) */
ADCSRA = ((1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(7<<ADPS0));
/* Enable ADC, Start Conversion, Auto Trigger enabled,
Interrupt enabled, Prescale = 32 */
ADCSRB = (0<<ADTS0); /* Select AutoTrigger Source to Free Running Mode
Strictly speaking - this is already 0, so we could omit the write to
ADCSRB, but included here so the intent is clear */
sei(); //global interrupt enable
}
int main(void)
{
ADC_init();
Timer0_init();
DDRD = 0b00100000; /* set PORTD bit 5 to output */
DDRB = 0b00111110; /* set PORTB bit 1,2,3,4,5 to output */
sei(); // Global interrupt enable (I=1)
while(1)
{
if(!(PIND & (1<<PIND2)))
{
PORTD = PORTD |= (1<<PORTD5);
PORTB = PORTB |= (1<<PORTB4);
if(average>512)
{
PORTB = PORTB |= (1<<PORTB5);
}
}
else
{
PORTD = PORTD &= ~(1<<PORTD5);
PORTB = PORTB &= ~(1<<PORTB4);
}
}
}
ISR(TIMER0_OVF_vect)
{
TCNT0 = 61; //TCNT0 needs to be set to the start point each time
++timecount0; // count the number of times the interrupt has been reached
if(!(PIND & (1<<PIND3)))
{
if (timecount0 >= 0) // 40 * 12.5ms = 500ms
{
PORTB = ((PORTB & ~0b00001110)|(0b00000000 & 0b00001110));
}
if (timecount0 >= 8*timing)
{
LED_RED;
}
if (timecount0 >= 16*timing)
{
LED_GREEN;
}
if (timecount0 >= 24*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00000110 & 0b00001110));
}
if (timecount0 >= 32*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001000 & 0b00001110));
}
if (timecount0 >= 40*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001010 & 0b00001110));
}
if (timecount0 >= 48*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001100 & 0b00001110));
}
if (timecount0 >= 56*timing)
{
PORTB = ((PORTB & ~0b00001110)|(0b00001110 & 0b00001110));
}
if (timecount0 >= 64*timing)
{
timecount0 = 0;
}
}
else
{
if (timecount0 >= 0)
{
PORTB = ((PORTB & ~0b00001110)|(0b00000000 & 0b00001110)); //ALL OFF
}
if (timecount0 >= 8*timing)
{
LED_RED;
//PORTB = ((PORTB & ~0b00001110)|(0b00000010 & 0b00001110)); //RED
}
if (timecount0 >= 16*timing)
{
LED_GREEN;
}
if (timecount0 >= 24*timing)
{
LED_BLUE;
}
if (timecount0 >= 32*timing)
{
timecount0 = 0;
}
}
}
ISR (ADC_vect) //handles ADC interrupts
{
adc_reading = ADC; //ADC is in Free Running Mode
accumulator+= adc_reading;
if ((adc_reading > 768) & (adc_reading <= 1024))
{
timing = 10;
}
if ((adc_reading >= 0) & (adc_reading<= 768) )
{
timing = 2.5;
}
samples++;
if(samples == 10)
{
average = accumulator/10;
accumulator = 0;
samples = 0;
}
}
最佳答案
根据您的处理器,您可以保持 ISR()
的速度并避免昂贵的 /,%
。
LED 的东西,我会在定时器中断中处理。
#define N 10
volatile unsigned sample[N];
volatile unsigned count = 0;
volatile unsigned index = 0;
volatile unsigned sum = 0;
ISR (ADC_vect) {
if (count >= N) {
sum -= sample[index];
} else {
count++;
}
sample[index] = ADC;
sum += sample[index];
index++;
if (index >= N) {
index = 0;
}
}
unsigned ADC_GetAvg(void) {
block_interrupts();
unsigned s = sum;
unsigned n = count;
restore_interrupts();
if (n == 0) {
return 0; //ADC ISR never called
}
return (s + n/2)/n; // return rounded average
}
我推荐 low pass filter 的整数版本。比上一个 N
的平均值。
关于c - 如何计算 ADC 读数的平均值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60878795/
我将 ADC 与 DMA(STM32F4,ide STM32CubeIDE)一起使用,我认为我了解它是如何工作的,但仍然有一个难题。根据我的理解,MCU 仅在 DMA 传输完成时调用,基本上 MCU
我正在开展一个项目,其中涉及 STM32H743 核板和 16 个 ADC 输入的使用。 显然,这些模拟输入一次使用一次;通过轮询机制读取值并配置下一个输入...配置 ADC channel ,启动
1 指令语法 adc <Xd>, <Xn>, <Xm> 2 指令语义 adc就是带「进位」加法,指令中的c就是英文carry。 整个指令等价于: (Xd
ATtiny88初体验(五):ADC ADC模块介绍 ATtiny88单片机包含一个10bit分辨率的ADC模块,拥有8个通道,最大采样率15kSPS,转换时间14us。ATtiny88的
我正在尝试在 STM32L476 Nucleo 板上调出一个 ADC。我想我已经配置好了,但我一定是漏掉了一步。我知道这可以使用 HAL API 和 CubeMX 来完成,但我更喜欢在启动新板时进行寄
mov eax, ptr_to_num1 ; little endian mov ebx, ptr_to_num2 ; little endian xor ecx, ecx xor edx, edx
.MODEL SMALL .STACK 1000 .DATA MSGA DB 13,10,"Input first number: ","$" MSGB DB 13,10,"Input second
我目前正在对 PIC 微 Controller 进行编程。 当按照我的方式创建结构时,每次我尝试访问该结构的变量的地址是否都会更改? 还是像静态变量一样,意味着地址在编译时确定,并且在整个程序中不会更
大家好,我正在开发一个项目,我必须计算 ADC 读数的移动平均值。从 ADC 输出的数据代表正弦波。 这是我用来获取给定信号的移动平均值的代码。 longNew = (8 bit data from
我希望在每次转换结束后调用 ADC 中断服务程序。但是它没有被调用。 这是我的代码: #define RCC_APB2ENR (*((volatile unsigned long*) 0x4002
有人可以看看我的代码吗?当我旋转电位器时,我试图让 8 个 LED 旋转,但四个 LED 一直保持亮着,根本不旋转。 #include /******************************
目的是将最新的 10 个 ADC 读数存储在一个数组中,然后计算它们的平均值以供其他地方使用。每次更新时删除最旧的。 关于 LED 时序,如果 ADC 读数在下面写的边界内,它必须将时序从 1s 切换
我正在尝试将音频ADC(wm8782 / pcm1803a)与Beagle Black连接。我已经对文件 davinci-evm , wm8782.c 和BB-BONE-AUDI-01设备树覆盖文件进
我正在尝试在简单的连续转换模式下通过 STM32F411RE 配置 ADC。我使用 CubeMX 生成基于 HAL 驱动程序的代码,这是生成的代码中初始化 ADC 的部分内容: /* ADC1 ini
我只是对我用 C 编写的反汇编 32 位程序进行一些分析。以下是反汇编程序输出的一部分: 41153c 02 00 add al, [eax] 41153e 00 00 add [eax]
我一直在运行Blarggs CPU tests通过我的 Gameboy 模拟器,op r,r 测试表明我的 ADC 指令工作不正常,但 ADD 是。我的理解是两者之间的唯一区别是在添加之前将现有的进位
我正在使用Renesas RX62N ;我的屏幕使用 ADC 单元 1,我的代码使用单元 0。 难道两个ADC单元不能一起工作吗?当我分别运行“ADC”和“显示代码”时,它工作正常,但一旦我尝试将它们
描述很长,抱歉。我用粗体突出显示了问题。 我目前正在尝试建立一个 driverlib 机制来执行以下操作: 大约每 20 个 RTC 预分频器 1 事件,检查是否应进行 ADC 测量。 如果需要,请设
我正在努力让 ADC 与我的设备配合使用。我正在使用 dsPIC33FJ128GP802,并尝试通过手动采样和转换缓慢启动。 我的代码发布在下面,我已经设置了 ADC 的每个寄存器,然后尝试仅采样一次
我的板上有一个 adc 模块。我在信号发生器上创建了一个正弦波。我将这个发生器的输出提供给一个 adc 引脚。最后我定期读取这个引脚的值。我尝试在我的软件上创建一个正弦波。 x = t, y = As
我是一名优秀的程序员,十分优秀!