gpt4 book ai didi

c - 使用 PIC 微处理器上的 C 语言进行二进制输出以实现 MIDI 输出

转载 作者:行者123 更新时间:2023-11-30 19:43:19 31 4
gpt4 key购买 nike

所以我正在创建一个需要二进制输出才能运行的项目。我有一系列 IF 语句来确定输出是什么,这里一切都很好。问题是我使用的是 PIC 微 Controller 16F877 并用 C 语言编程。我使用 RS232 将信息直接发送到 MIDI Controller ,其中包含大约 8 个音符值和 8 个音量值(8x8 组选项)。

我也使用proteus和CCS来编程。

我的问题是:如何以二进制形式创建 MIDI 输出?我知道所有二进制值,但我不确定如何创建“midi 友好”输出。

编辑:根据请求添加示例代码:

#include <16F877.h>
TRISB=1; //sets all tris in portB to 1, to allow as inputs

TRISD=1; //sets all tris in portD to 1, to allow as inputs

TRISC.RC6=0; //sets trisC port 6 to 0, to allow as an output

#use rs232(baud=9600,parity=N,xmit=STDOUT,rcv=None,bits=8,stream=PORT1,float_high)
// initialises RS232 and configures for transmision
#use delay(crystal=4MHz)
// crystal at 4MHz is used (XT MODE)

#define X1 PIN_B0 //names pin B0 as X1
#define X2 PIN_B1 //names pin B1 as X2
#define X3 PIN_B2 //names pin B2 as X3
#define X4 PIN_B3 //names pin B3 as X4
#define X5 PIN_B4 //names pin B4 as X5
#define X6 PIN_B5 //names pin B5 as X6
#define X7 PIN_B6 //names pin B6 as X7
#define X8 PIN_B7 //names pin B7 as X8

#define STDOUT PIN_C6 // Names pin C6 as STDOUT

#define Y1 PIN_D0 //names pin D0 as Y1
#define Y2 PIN_D1 //names pin D1 as Y2
#define Y3 PIN_D2 //names pin D2 as Y3
#define Y4 PIN_D3 //names pin D3 as Y4
#define Y5 PIN_D4 //names pin D4 as Y5
#define Y6 PIN_D5 //names pin D5 as Y6
#define Y7 PIN_D6 //names pin D6 as Y7
#define Y8 PIN_D7 //names pin D7 as Y8

char xout;
char yout;

int main (void)
{
if(B0==1) //if B0 is 1, sets xout to "A"
{
xout='A';
}
if(B1==1) //if B1 is 1, sets xout to "B"
{
xout='B';
}
if(B2==1) //if B2 is 1, sets xout to "C"
{
xout='C';
}
if(B3==1) //if B3 is 1, sets xout to "D"
{
xout="D";
}
if(B4==1) //if B4 is 1, sets xout to "E"
{
xout='E';
}
if(B5==1) //if B5 is 1, sets xout to "F"
{
xout='F';
}
if(B6==1) //if B6 is 1, sets xout to "G"
{
xout='G';
}
if(B7==1) //if B7 is 1, sets xout to "H"
{
xout='H';
}
if(D0==1) //if D0 is 1, sets yout to "A"
{
yout='A';
}
if(D1==1) //if D1 is 1, sets yout to "B"
{
yout='B';
}
if(D2==1) //if D2 is 1, sets yout to "C"
{
yout='C';
}
if(D3=1) //if D3 is 1, sets yout to "D"
{
yout='D';
}
if(D4==1) //if D4 is 1, sets yout to "E"
{
yout='E';
}
if(D5==1) //if D5 is 1, sets yout to "F"
{
yout='F';
}
if(D6==1) //if D6 is 1, sets yout to "G"
{
yout='G';
}
if(D7==1) //if D7 is 1, sets yout to "H"
{
yout='H';
}


printf("%c,%c", xout yout); //outputs xout and yout for display on a screen

用二进制代码代替字母(它们只是为了演示实际输出,以便我可以进入 midi),printf 将输出 IF 语句中确定的 midi 值

编辑 2:进一步了解

我基本上将使用一个 8x8 的“开关”网格(使用可见光作为接口(interface)方式),x 轴控制音符,Y 轴控制音量。我只需要一个输出,该输出将通过 5 针 DIN 直接连接到 MIDI Controller

最佳答案

我可能会只使用 2 个命令(NoteOn、NoteOff)开始,然后根据需要继续。

下面是一个示例“架构”,我可能会用它来入门。由于您需要跟踪“note on”和“note off”操作,因此我添加了全局“state”数组。第一索引以交替方式在当前状态和旧状态之间变化。对于初学者来说,这可能就足够了。

8 个插槽可容纳 8 个 key 。如果按下该键,该值可能是“音量”代码。如果没有按下该音调的键,则为 KEY_OFF。

#define KEY_OFF 0x80  // command parameters only use lower 7 bits...
static uint8_t state[2][8];

static void Configure()
{ // Do what you need to do in terms of initializing pins, serial port, etc...

}

static void UpdateState(uint8_t index)
{
// read pins into the global state variable at first index "index"
// Not pressed "tones" get value "OFF".
// TIP: later, you could consider to use PIC
// "interrupt on change" features
// to save power.
// Tip: Depending on the types of your keys and your circuitry,
// you might run into "bouncing keys" problems.
// But the fact, that you send your serial messages synchronously
// gives your keys some time to "settle", which might be enough.
}

// ROM based lookup table
// TODO: fill in correct values for your note-key to note-to-play mapping.
static const uint8_t notes[8] =
{ 0x01
, 0x01
, 0x01
, 0x01
, 0x01
, 0x01
, 0x01
, 0x01
};

static const uint8_t velocities[8] =
{
// TODO: 8 entries mapping your "volume key" code to a MIDI "velocity" code.
};

#define DEFAULT_CHANNEL 0x00 // 16 channels available in midi... 0x00..0x0F

static void SerialSend(uint8_t count, const uint8_t * message)
{ // TODO: Implement sending the message on Rs232...
// TIP: Use the flag "tx buffer EMPTY" before you write next byte.
for( uint8_t i = 0; i < count; ++i )
{
while( !TXEMPTY ); // TODO: look up correct name ...
TX = message[i]; // TODO: look up correct name...
}
}

// Assuming to use only channel 0 here...
static void SendNoteOff(uint8_t note)
{
// TODO: find out if NoteOff needs a "real" velocity value...
uint8_t midiCmd[3] = { 0x80|DEFAULT_CHANNEL, notes[note], 0x00 };
SerialSend(3, midiCmd);
}

static void SendNoteOn(uint8_t note, uint8_t velocity)
{
uint8_t midiCmd[3] = { 0x90 | DEFAULT_CHANNEL, notes[note], velocities[velocity] };
SerialSend(3, midiCmd);
}

// Named it emain() as it is in some random file of mine which already has a main ;)
void emain()
{
Configure();
uint8_t current = 0;
uint8_t old = 1;
while (1)
{
UpdateState(current);
for (uint8_t i = 0; i < 8; ++i)
{
uint8_t os = state[old][i];
uint8_t cs = state[current][i];
if (os != cs )
{
if (0x00 != (cs & KEY_OFF))
{
SendNoteOff(i);
}
else
{
SendNoteOn(i, cs);
}
}
}
old = current;
current = (current + 1) % 2;
}
}

关于c - 使用 PIC 微处理器上的 C 语言进行二进制输出以实现 MIDI 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29760886/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com