Ryo Od
/
Nucleo_MCP4922_DCA_Test
MCP4922にADSR波形を出力。
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "rtos.h" 00003 #include "AverageAnalogIn.h" 00004 00005 #define SPIM_TIMER_PERIOD (5) // 5ms 00006 #define SPIM_RATE (8000000) // 8MHz 00007 #define SPIM_WAIT /*(wait_us(1))*/ 00008 00009 // ピン・アサイン 00010 #define PIN_CHECK PA_10 00011 #define PIN_DAC_CS PA_9 00012 #define PIN_DAC_LDAC PA_8 00013 00014 SPI SpiM(SPI_MOSI, SPI_MISO, SPI_SCK); 00015 DigitalOut DacCs(PIN_DAC_CS); 00016 DigitalOut DacLdac(PIN_DAC_LDAC); 00017 00018 DigitalOut CheckPin(PIN_CHECK); 00019 00020 AverageAnalogIn DurationIn(A0); 00021 AverageAnalogIn DecayIn(A1); 00022 AverageAnalogIn SustainIn(A2); 00023 00024 int16_t beatLen = 25; 00025 00026 int16_t level = 4095; 00027 int16_t duration = 400; 00028 int16_t decay = 100; 00029 int16_t sustain = 2000; 00030 00031 int16_t decay_delta; 00032 int16_t release_delta = 1000; 00033 int16_t mod_value; 00034 00035 int16_t tick; 00036 00037 // DAC A Channelに出力 00038 // parameter: v: 出力値(0 .. 4095) 00039 void writeToDacA(int16_t v) 00040 { 00041 // Channel A 00042 DacLdac = 1; 00043 DacCs = 0; 00044 SpiM.write((v >> 8) | 0x30); // 0x30: DAC_A(0) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1) 00045 SpiM.write(v & 0xff); 00046 SPIM_WAIT; 00047 DacCs = 1; 00048 DacLdac = 0; 00049 } 00050 00051 // DAC B ChannelにA ChannelのVrefを出力 00052 void outVref() 00053 { 00054 // Channel B 00055 DacLdac = 1; 00056 DacCs = 0; 00057 SpiM.write(0x08 | 0xB0); // 0xB0: DAC_B(1) | Vref Unbuffered(0) | Vout 1x(1) | !SHDN(1) 00058 SpiM.write(0x00); 00059 SPIM_WAIT; 00060 DacCs = 1; 00061 DacLdac = 0; 00062 } 00063 00064 // ADSR波形を出力 00065 void outADSR(void const* arg) 00066 { 00067 tick++; 00068 00069 if (tick > beatLen) { 00070 tick = 0; 00071 // モジュレーション波形を初期化する 00072 mod_value = level; 00073 decay_delta = (level - sustain) / decay; 00074 } 00075 00076 // 出力値補正 00077 if (mod_value < 0) { 00078 mod_value = 0; 00079 } 00080 writeToDacA(mod_value); 00081 00082 if (tick < decay) { 00083 mod_value -= decay_delta; 00084 } 00085 /* 00086 if (tick >= duration) { 00087 mod_value -= release_delta; 00088 } 00089 */ 00090 if (tick == duration) { 00091 mod_value = 0; 00092 } 00093 } 00094 00095 int main() 00096 { 00097 RtosTimer SpiM_timer(outADSR, osTimerPeriodic); 00098 00099 SpiM.format(8, 0); 00100 SpiM.frequency(SPIM_RATE); 00101 00102 outVref(); 00103 00104 SpiM_timer.start(SPIM_TIMER_PERIOD); 00105 00106 while(true) { 00107 duration = DurationIn.read() * beatLen; 00108 decay = DecayIn.read() * beatLen; 00109 sustain = SustainIn.read() * 4095; 00110 00111 printf("%d\t%d\t%d\r\n", duration, decay, sustain); 00112 00113 Thread::wait(10); 00114 } 00115 }
Generated on Mon Jul 18 2022 05:10:10 by 1.7.2