⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fftavr.c

📁 AVR单片机MEGA128驱动ks0108控制的LCD
💻 C
字号:

#include <avr/io.h>
#include <avr/twi.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>

#include "fftAvr.h"

#ifdef	FFT_USE_INTERRUPT

	uint8_t* fftAvrRecvBuffer;
	volatile fftAvrResultCallback fftAvrTC = fftAvrTransmissionComplete;
	volatile uint8_t fftAvrRecvCount;
	volatile uint8_t fftAvrRecvIdx;
	volatile uint8_t fftAvrTransComp;

	// Default transmission complete callback function.
	void fftAvrTransmissionComplete(uint8_t* buffer) {
		fftAvrTransComp = 1;
	}
	
	// TWI interrupt service routine
	SIGNAL(SIG_2WIRE_SERIAL) {
		uint8_t status = TW_STATUS, data = TWDR;
		
		if(status == TW_MR_DATA_ACK) {
			*(fftAvrRecvBuffer + fftAvrRecvIdx++) = data;
			if(fftAvrRecvIdx == fftAvrRecvCount-1) {
				TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN);
			} else {
				TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
			}
		} else if(status == TW_MR_DATA_NACK) {
			*(fftAvrRecvBuffer + fftAvrRecvIdx++) = data;
			TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
			fftAvrTC(fftAvrRecvBuffer);
		}
	}
	
#endif

uint8_t twiReceive(uint8_t ack) {
	uint8_t twcr = (1<<TWINT) | (1<<TWEN);
	if(ack) twcr |= (1<<TWEA);
	// clear interrupt to start transmission
	TWCR = twcr;
	// wait for transmission
	while ((TWCR & (1<<TWINT)) == 0);
	// return data
	return TWDR;
}

uint8_t fftAvrTwiStart(void) {
	// send start condition
	TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
	// wait for transmission
	while ((TWCR & (1<<TWINT)) == 0);
	// return status code
	return TW_STATUS;
}

uint8_t fftAvrTwiTransmit(uint8_t data) {
	// transmit data
	TWDR = data;
	// clear interrupt to start transmission
	TWCR = (1<<TWINT) | (1<<TWEN);
	// wait for transmission
	while ((TWCR & (1<<TWINT)) == 0);
	// return status code
	return TW_STATUS;
}

uint8_t fftAvrInit(uint16_t fftAddr) {
	uint8_t status;
	
	// Start condition
	status = fftAvrTwiStart();
	if(status != TW_REP_START && status != TW_START) return 0;
	
	// send SLA+W
	status = fftAvrTwiTransmit(FFT_AVR_TWI_ADDR | TW_WRITE);
	if(status != TW_MT_SLA_ACK) return 0;
	
	// send FFT address
	// high byte
	status = fftAvrTwiTransmit(fftAddr >> 8);
	if(status != TW_MT_DATA_ACK) return 0;
	// low byte
	fftAvrTwiTransmit(fftAddr & 0x00FF);
	
	// Start condition
	status = fftAvrTwiStart();
	if(status != TW_REP_START && status != TW_START) return 0;
	
	// send SLA+R
	status = fftAvrTwiTransmit(FFT_AVR_TWI_ADDR | TW_READ);
	if(status != TW_MR_SLA_ACK) return 0;
	
	// FFT AVR initialization successful
	
	return 1;
}

void fftAvrReadSpectrum(uint8_t fftMode, uint8_t* buffer) {
	uint8_t ok=0, len=0;
	
	switch(fftMode) {
		case FFT_HI_RES:
			ok = fftAvrInit(FFT_HI_RES_ADDR);
			len = FFT_HI_RES_LEN;
			break;
		case FFT_HI_RES_PEAK:
			ok = fftAvrInit(FFT_HI_RES_PEAK_ADDR);
			len = FFT_HI_RES_LEN;
			break;
		case FFT_LO_RES:
			ok = fftAvrInit(FFT_LO_RES_ADDR);
			len = FFT_LO_RES_LEN;
			break;
		case FFT_LO_RES_PEAK:
			ok = fftAvrInit(FFT_LO_RES_PEAK_ADDR);
			len = FFT_LO_RES_LEN;
			break;
		case FFT_MIXED:
			ok = fftAvrInit(FFT_MIXED_ADDR);
			len = FFT_MIXED_LEN;
			break;
		case FFT_MIXED_PEAK:
			ok = fftAvrInit(FFT_MIXED_PEAK_ADDR);
			len = FFT_MIXED_LEN;
			break;
	}
	
	if(!ok) return;

	#ifndef FFT_USE_INTERRUPT
		// receive data
		for(uint8_t i=0; i<len; i++) {
			if(i<len-1) *buffer++ = twiReceive(1);
			else *buffer++ = twiReceive(0);
		}
		// send start condition
		TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN);
	#else
		fftAvrRecvBuffer = buffer;
		fftAvrRecvCount = len;
		fftAvrRecvIdx = 0;
		fftAvrTransComp = 0;
		// enable interrupts
		sei();
		// start transmission
		TWCR = (1<<TWIE) | (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
	#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -