/* This is a program to control AD9102 arbitrary waveform oscillator */
/*** Libraries ***/
#define VtoD1 6.75
#define VtoD2 6.65
#define VtoD3 6.75
#define VtoD4 6.7
#include "ch1.h"
#include "ch2.h"
#include "ch3.h"
#include "ch4.h"
#include "control.h"
#include <SPI.h>
//Set pins for the output
int Pin_en_cvddx = 2; //Oscillator out control @ #2
int Pin_shdn_n_lt3472 = 4; //LT3472 enable pin @ #4
int PinTrigger = 6; //AD9102 trigger pin @ #6 originally 7
int PinDutReset = 8; //AD9102 Reset pin @ #8
int PinSpiCS0 = 46; //AD9102 SPI CS0 @Group 1 pin @ #46
int PinSpiCS1 = 32; //AD9102 SPI CS0 @Group 3 pin @ #32
int PinSpiCS2 = 40; //AD9102 SPI CS0 @Group 4 pin @ #40
int PinSpiCS3 = 25; //AD9102 SPI CS0 @Group 5 pin @ #25
char ext_clk = 'y';
char amp_out = 'n';
char Stop = 'n';
char Exit = 'n';
char wave;
char dummy;
int pulse_num;
int multi;
char Connected = 1;
/*** Function Declarations ***/
void AD9102_reg_reset( void );
void AD9102_update_regs1( unsigned int Data[] );
void AD9102_update_regs2( unsigned int Data[] );
void AD9102_update_regs3( unsigned int Data[] );
void AD9102_update_regs4( unsigned int Data[] );
void AD9102_update_sram1( int Data[] );
void AD9102_update_sram2( int Data[] );
void AD9102_update_sram3( int Data[] );
void AD9102_update_sram4( int Data[] );
void spi_write1( unsigned int addr, int Data );
void spi_write2( unsigned int addr, int Data );
void spi_write3( unsigned int addr, int Data );
void spi_write4( unsigned int addr, int Data );
int spi_read1( unsigned int addr );
int numeric_read( void );
void printf_menu( void );
void generate_wave1( void );
void generate_wave2( void );
void generate_wave3( void );
void generate_wave4( void );
void printf_prompt3( void );
void stop_wave( void );
void printf_prompt4( void );
/*** Main Function ***/
void setup()
{
pinMode(Pin_en_cvddx, OUTPUT); //DigitalOut instance for enable pin of on-board oscillator supply
pinMode(Pin_shdn_n_lt3472, OUTPUT); //DigitalOut instance for shutdown/enable pin of on-board amplifier supply
pinMode(PinSpiCS0, OUTPUT); //AD9102 SPI CS0 @ Group 1 pin46
pinMode(PinSpiCS1, OUTPUT); //AD9102 SPI CS0 @ Group 3 pin32
pinMode(PinSpiCS2, OUTPUT); //AD9102 SPI CS0 @ Group 4 pin40
pinMode(PinSpiCS3, OUTPUT); //AD9102 SPI CS0 @ Group 5 pin25
pinMode(PinTrigger, OUTPUT); //AD9102 trigger pin
pinMode(PinDutReset, OUTPUT); //AD9102 Reset pin
digitalWrite(PinDutReset, HIGH);
digitalWrite(PinTrigger, HIGH);
digitalWrite(Pin_en_cvddx, HIGH);
digitalWrite(Pin_shdn_n_lt3472, HIGH);
digitalWrite(PinSpiCS0, HIGH);
digitalWrite(PinSpiCS1, HIGH);
digitalWrite(PinSpiCS2, HIGH);
digitalWrite(PinSpiCS3, HIGH);
Serial.begin(38400);
SPI.begin();
SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0));
AD9102_reg_reset();
}
void loop()
{
printf_menu();
while( Serial.available() == 0 );
wave = Serial.read();
delay(20);
if(wave=='9')
{
printf("\r\n Press 'R' and CR to regenerate waves. \r\n" );
while( Serial.available() == 0 ){}
dummy = numeric_read();
digitalWrite(PinTrigger, LOW);
}else{
//printf("wave= %c \r\n", wave);
printf("\r\n Input repeat number: \r\n");
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
while( Serial.available() == 0 ){}
pulse_num = numeric_read();
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
printf("Repeat number = %d \r\n", pulse_num);
inp_multi:
printf("\r\n Input multiple of time base 1 to 16, basic time base = 6.4ns: \r\n");
printf(" Input 4 for 4 x 6.4ns, for example \r\n");
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
while( Serial.available() == 0 ){}
multi = numeric_read();
while(Serial.available() > 0)
{
dummy = Serial.read();
delay(10);
}
if(multi<1 | multi>16)
{
printf(" Input number is out of range, input again. \r\n");
goto inp_multi;
}
printf("Multiple of time base = %d \r\n", multi);
printf("\r\n Wait for data transfer completion. \r\n");
if(pulse_num==0)
{
wave1_regval[15] = 0x0000;
wave2_regval[15] = 0x0000;
wave3_regval[15] = 0x0000;
wave4_regval[15] = 0x0000;
}else{
wave1_regval[15] = 0x0001;
wave2_regval[15] = 0x0001;
wave3_regval[15] = 0x0001;
wave4_regval[15] = 0x0001;
wave1_regval[26] = 0x0100 + pulse_num;
wave2_regval[26] = 0x0100 + pulse_num;
wave3_regval[26] = 0x0100 + pulse_num;
wave4_regval[26] = 0x0100 + pulse_num;
}
//set time base
wave1_regval[23] = 0x0001 + (multi * 0x0100);
wave2_regval[23] = 0x0001 + (multi * 0x0100);
wave3_regval[23] = 0x0001 + (multi * 0x0100);
wave4_regval[23] = 0x0001 + (multi * 0x0100);
switch (wave) {
case '4':
generate_wave1();
generate_wave2();
generate_wave3();
generate_wave4();
printf("\r\n All data have been transfered. Input 'S' and CR to generate waves. \r\n" );
while( Serial.available() == 0 ){}
dummy = numeric_read();
digitalWrite(PinTrigger, LOW);
break;
case '9':
break;
default:
printf("***Invalid Entry**** \r\n");
break;
}
}
printf_prompt3();
while( Serial.available() == 0 );
while ( !(Stop == 'y') ){
Stop = Serial.read();
}
stop_wave();
printf_prompt4();
while( Serial.available() == 0 );
Exit = Serial.read();
if ( Exit == 'y' ){
Connected = 0;
printf("\r\n Exiting program...\r\n");
}else{
Stop = 'n';
}
}
void printf_menu()
{
printf("\r\r\n***** Wave Option *****\r\r\n");
printf(" 4 - 4 Waves\r\n");
printf(" 9 - Restart after soft reset only\r\n");
printf("Select option: 4 or 9 \r\n");
}
/*Function to play shape 1*/
void generate_wave1()
{
printf("\r\n Start Wave1 data transfer.\r\n");
delay(500);
AD9102_update_sram1( wave1 );
AD9102_update_regs1( wave1_regval );
printf("Wave1 data transfer completed.\r\n");
}
/*Function to play shape 7*/
void generate_wave2()
{
printf("\r\n Start Wave2 data transfer.\r\n");
delay(500);
AD9102_update_sram2( wave2 );
AD9102_update_regs2( wave2_regval );
printf("Wave2 data transfer completed.\r\n");
}
void generate_wave3()
{
printf("\r\n Start Wave3 data transfer.\r\n");
delay(500);
AD9102_update_sram3( wave3 );
AD9102_update_regs3( wave3_regval );
printf("Wave3 data transfer completed.\r\n");
}
void generate_wave4()
{
printf("\r\n Start Wave4 data transfer.\r\n");
delay(500);
AD9102_update_sram4( wave4 );
AD9102_update_regs4( wave4_regval );
printf("Wave4 data transfer completed.\r\n");
}
/*Function to reset AD9102 reg reset*/
void AD9102_reg_reset()
{
digitalWrite(PinDutReset, LOW);
delay( 10 );
digitalWrite(PinDutReset, HIGH);
}
/*
* @brief Write data to SRAM
* @param data[] - array of data to be written to SRAM
* @return none
*/
void AD9102_update_sram1( int Data[] )
{
spi_write1( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD1 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write1( sram_add+i, data_shifted );
//if(i<100) printf("data= %d data_shifted= %d \r\n", Data[i], data_shifted);
}
spi_write1( 0x001E, 0x0010 );
}
void AD9102_update_sram2( int Data[] )
{
spi_write2( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD2 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write2( sram_add+i, data_shifted );
}
spi_write2( 0x001E, 0x0010 );
}
void AD9102_update_sram3( int Data[] )
{
spi_write3( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD3 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write3( sram_add+i, data_shifted );
}
spi_write3( 0x001E, 0x0010 );
}
void AD9102_update_sram4( int Data[] )
{
spi_write4( 0x001E, 0x0004 );
float fData;
int16_t DACdata;
int data_shifted = 0;
unsigned int sram_add = 0x6000;
for ( int i=0; i<4096; i++ )
{
if(Data[i]>1200||Data[i]<-1200) printf("\r\n data is too large or too small \r\n");
if(Data[i]>1200||Data[i]<-1200) exit(0);
fData = VtoD4 * (float)Data[i];
DACdata = (int16_t)fData;
if(DACdata<0) DACdata=16384 + DACdata;
data_shifted = (int16_t)DACdata << 2;
spi_write4( sram_add+i, data_shifted );
}
spi_write4( 0x001E, 0x0010 );
}
/*
* @brief Write to SPI registers, and read and printf new register values
* @param data[] - array of data to written to SPI registers
* @return none
*/
void AD9102_update_regs1( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write1( reg_add[i], Data[i] );
}
}
void AD9102_update_regs2( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write2( reg_add[i], Data[i] );
}
}
void AD9102_update_regs3( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write3( reg_add[i], Data[i] );
}
}
void AD9102_update_regs4( uint16_t Data[] )
{
unsigned int data_display = 0;
for ( int i=0; i<66; i++ ){
spi_write4( reg_add[i], Data[i] );
}
}
/*
* @brief Write 16-bit data to AD910x SPI/SRAM register
* @param addr - SPI/SRAM address
* @param data - data to be written to register address
* @return none
*/
void spi_write1( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS0, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS0, HIGH);
delay( 10 );
}
void spi_write2( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS1, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS1, HIGH);
delay( 10 );
}
void spi_write3( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS2, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS2, HIGH);
delay( 10 );
}
void spi_write4( unsigned int addr, int Data )
{
digitalWrite(PinSpiCS3, LOW);
SPI.transfer16( addr );
SPI.transfer16( Data );
digitalWrite(PinSpiCS3, HIGH);
delay( 10 );
}
int spi_read1( unsigned int addr )
{
digitalWrite(PinSpiCS0, LOW);
unsigned int read_addr;
int reg_data;
read_addr = 0x8000 + addr;
reg_data = SPI.transfer16( read_addr );
digitalWrite(PinSpiCS0, HIGH);
delay( 10 );
return( reg_data );
}
int numeric_read()
{
char inBytes[10];
int vals[6];
Serial.readBytesUntil('\r\n', inBytes, sizeof(inBytes)/sizeof(char));
vals[0] = atoi(inBytes);
//printf("vals[0] = %d \r\n",vals[0]);
return(vals[0]);
}
/*Function to printf prompt/question to user to stop pattern*/
void printf_prompt3()
{
printf( "\r\n Stop pattern?\r\n" );
printf( "If yes, input 'y' and CR.\r\n" );
}
/*Function to stop pattern generation*/
void stop_wave()
{
digitalWrite(PinTrigger, HIGH);
printf( "\r\n Waves stopped.\r\n" );
}
/*Function to printf prompt/question to user to exit program*/
void printf_prompt4()
{
printf( "\r\n Restart program?\r\n" );
printf( "If yes, input 'y' and CR or press reset button.\r\n" );
}
现在有4个频道输出,数据放在ch1.h,ch2.h文件里,将代码改为由用户选择有几个频道输出,更多的文件处理,比如100个波形的数据
为了实现用户选择有几个频道输出,我们需要先了解一些基本的编程概念和技巧。下面是一个可能的实现方式:
定义一个变量num_channels,用于记录用户选择的频道数。
根据用户选择的频道数,决定需要包含哪些数据文件。比如,如果用户选择输出2个频道,就只需要包含ch1.h和ch2.h文件。如果用户选择输出4个频道,就需要再包含ch3.h和ch4.h文件。
定义一个函数output_data(),用于输出数据。函数的参数包括数据文件的名称和需要输出的频道数。函数内部可以使用文件操作函数读取数据,并根据需要输出指定的频道数据。
在主函数中,通过用户输入来设置num_channels的值,并调用output_data()函数输出数据。
下面是一个示例代码,可以输出1至4个频道的数据:
c
Copy
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void output_data(string filename, int num_channels) {
ifstream infile(filename);
if (!infile) {
cout << "Error: cannot open file " <<filename << endl;
return;
}
int num_samples;
infile >> num_samples;
if (num_channels > 4 || num_channels < 1) {
cout << "Error: invalid number of channels" << endl;
return;
}
for (int i = 0; i < num_samples; i++) {
double ch1, ch2, ch3, ch4;
infile >> ch1 >> ch2 >> ch3 >> ch4;
switch (num_channels) {
case 1:
cout << ch1 << endl;
break;
case 2:
cout << ch1 << " " << ch2 << endl;
break;
case 3:
cout << ch1 << " " << ch2 << " " << ch3 << endl;
break;
case 4:
cout << ch1 << " " << ch2 << " " << ch3 << " " << ch4 << endl;
break;
}
}
infile.close();
}
int main() {
int num_channels;
cout << "Enter the number of channels to output (1-4): ";
cin >> num_channels;
string filename;
for (int i = 1; i <= num_channels; i++) {
cout << "Enter the filename for channel " << i << ": ";
cin >> filename;
output_data(filename, num_channels);
}
return 0;
}
```c
如果需要处理更多的数据文件,比如100个波形的数据,可以将数据文件名存储在一个列表或数组中,并使用循环遍历列表或数组,依次处理每个文件。例如:
```c
string filenames[] = {"data1.h", "data2.h", "data3.h", ..., "data100.h"};
for (int i = 0; i < 100; i++) {
output_data(filenames[i], num_channels);
}
这样就可以方便地处理大量的数据文件。
而且为了方便描述小车进行何种运动,所以事先用几个宏定义来描述
#include<Servo.h>
#define STOP 0
#define GO 1
#define RIGHT 2
#define LIFT 3
#define BACK 4
将前进,后退,左转,右转,停止宏定义
可以借鉴下
文件motorIR.h
#ifndef motorIR_h
#define motorIR_h
#include "Arduino.h"
#include "NECIRrcv.h"
#define STANDBY 999
#define inputIR 2
#define PWM_1 3
#define MI_1 4
#define MD_1 5
#define PWM_2 6
#define MI_2 7
#define MD_2 8
#define FORWARD
#define BACKWARD
class motorIR
{
public: // Funciones públicas
motorIR(int pPWM_1, int pMI_1, int pMD_1, int pPWM_2, int pMI_2, int pMD_2);
void setMotor(int PWM, int MI, int MD);
void begin();
void control();
void translate();
void serialPrint();
private: // Variables privadas
int _PWM= STANDBY;
int _MI;
int _MD;
unsigned long _IRcode;
// static NECIRrcv & getSensor() // <--- getSensor() added
// {
// static NECIRrcv sensor(4);
// return sensor;
// }
// static NECIRrcv & getSensor()
// {
// static NECIRrcv sensor(4);
// static bool firstRun(true);
// if ( firstRun )
// {
// sensor.begin();
// firstRun = false;
// }
// return sensor;
// }
};
#endif
文件motorIR.cpp
#include "Arduino.h"
#include "motorIR.h"
#include <string.h>
motorIR::motorIR(int PWM, int MI, int MD) // Constructor
{
_MI= MI +A0;
_PWM= PWM +A0;
_MD= MD +A0;
}
void motorIR::beginner()
{
Serial.begin(9600);
Serial.print("Begin");
}
void motorIR::control(int i)
{
NECIRrcv sensor(4) ; // I doesn't work as expected if placed here
sensor.begin();
Serial.println("Checkpoint");
while (sensor.available())
{
Serial.print("Detection");
IRcode= sensor.read();
Serial.print(IRcode, DEC);
Serial.print(IRcode, HEX);
Serial.print(IRcode, BIN);
}
}
文件NECIRrcv.h(给定)
#ifndef NECIRrcv_h
#define NECIRrcv_h
#include <Arduino.h>
#include "motorIR.h"
#define USECPERTICK 50 // microseconds per clock interrupt tick
#define CLKFUDGE 5 // fudge factor for clock interrupt overhead
#define CLKMAX 256 // max value for clock (timer 2)
#define PRESCALE 8 // timer2 clock prescale
#define SYSCLOCK 16000000 // main Arduino clock
#define CLKSPERUSEC (SYSCLOCK/PRESCALE/1000000) // timer clocks per microsecond
#define MAXBUF 8 // IR command code buffer length (circular buffer)
// IR detector output is active low
#define MARK 0
#define SPACE 1
#define NBITS 32 // bits in IR code
#define BLINKLED 13
// defines for setting and clearing register bits
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
// clock timer reset value
#define INIT_TIMER_COUNT2 (CLKMAX - USECPERTICK*CLKSPERUSEC + CLKFUDGE)
#define RESET_TIMER2 TCNT2 = INIT_TIMER_COUNT2
// pulse parameters -- nominal usec
#define STARTNOM 9000
#define SPACENOM 4500
#define BITMARKNOM 620
#define ONESPACENOM 1600
#define ZEROSPACENOM 480
#define RPTSPACENOM 2180
#define TOLERANCE 20 // percent
#define LTOL (1.0 - TOLERANCE/100.)
#define UTOL (1.0 + TOLERANCE/100.)
// pulse parameters (tick counts)
#define STARTMIN (int)((STARTNOM/USECPERTICK)*LTOL) // start MARK
#define STARTMAX (int)((STARTNOM/USECPERTICK)*UTOL)
#define SPACEMIN (int)((SPACENOM/USECPERTICK)*LTOL)
#define SPACEMAX (int)((SPACENOM/USECPERTICK)*UTOL)
#define BITMARKMIN (int)((BITMARKNOM/USECPERTICK)*LTOL-2) // extra tolerance for low counts
#define BITMARKMAX (int)((BITMARKNOM/USECPERTICK)*UTOL+2)
#define ONESPACEMIN (int)((ONESPACENOM/USECPERTICK)*LTOL)
#define ONESPACEMAX (int)((ONESPACENOM/USECPERTICK)*UTOL)
#define ZEROSPACEMIN (int)((ZEROSPACENOM/USECPERTICK)*LTOL-2)
#define ZEROSPACEMAX (int)((ZEROSPACENOM/USECPERTICK)*UTOL+2)
#define RPTSPACEMIN (int)((RPTSPACENOM/USECPERTICK)*LTOL)
#define RPTSPACEMAX (int)((RPTSPACENOM/USECPERTICK)*UTOL)
// receiver states
#define IDLE 1
#define STARTH 2
#define STARTL 3
#define BIT 4
#define ONE 5
#define ZERO 6
#define STOP 7
#define BITMARK 8
#define RPTMARK 9
// macros
#define GETIR(X) ((byte)digitalRead(X)) // used to read IR pin
#define nextstate(X) (irparams.rcvstate = X)
// state machine variables irparams
static volatile struct {
byte rcvstate ; // IR receiver state
byte bitcounter ; // bit counter
byte irdata ; // MARK or SPACE read from IR input pin
byte fptr ; // irbuf front pointer
byte rptr ; // irbuf rear pointer
byte irpin ; // pin for IR data from detector
byte blinkflag ; // TRUE to enable blinking of pin 13 on IR processing
unsigned int timer ; // state timer
unsigned long irmask ; // one-bit mask for constructing IR code
unsigned long ircode ; // IR code
unsigned long irbuf[MAXBUF] ; // circular buffer for IR codes
} irparams ;
// main class
class NECIRrcv
{
public:
NECIRrcv(int irpin);
unsigned long read();
void begin();
int available() ;
void flush() ;
void blink13(int blinkflag) ;
private:
} ;
卫星吗
以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:
在Arduino中,可以将代码分散在多个.ino文件中,然后在主文件中#include这些文件来使用。这有几个好处:
示例:
有两个ino文件:
File1.ino:
c
int func1() {
// ...
}
File2.ino:
c
int func2() {
// ...
}
在主文件Main.ino中:
c
#include "File1.ino"
#include "File2.ino"
void setup() {
// ...
int a = func1();
int b = func2();
}
void loop() {
// ...
}
这会将File1.ino和File2.ino中的内容合并到Main.ino中,你就可以在Main.ino中直接调用func1()和func2()了。
需要注意的是: