📄 keydrvavr(16m).c
字号:
#include "iom16v.h"
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#define Meboard 0x02 //板号
#define P33 3 //PD3 O
#define P35 5 //PD5 O
#define P36 6 //PD6 I
#define P37 7 //PD7 O
#define TXDLED 1 //PD1 O
uchar Sequence_No=0x00; //音乐标准数据帧序列号,00,01,02
uchar Mididata[3]; //标准音乐数据帧
uchar Midi_data_flow[250]; //音乐数据流
uchar data_in=0; //收到的音乐数据流序列号,从UART得到的是本板的有效号,
uchar data_out=0; //从Midi_data_flow 读出判断数据号, data_out
uchar Mididata1[3]; //标准音乐数据帧
uchar Sequence1_No=0x00;
uchar data_temp,data_temp1, data_temp2,led_temp=0x12;
uchar Key_status[12]; //键状态 0x00 表示该键目前关闭 0x11 表示正在动作 0x22 表示保持
uchar Key_lidu_high[12]; //力度高电平的次数, 以8us为单次
uchar Key_lidu_low[12]; //力度低电平次数
uchar Key_lidu_reg[12]; //力度过程值缓冲,参与递减运算
uchar Key_hit_time[12]; //执行键动作需要的周期 次数
uchar Key_hit_status[12]; //力度周期目前电平状态, 00 表示 目前处于高电平, 01 表示目前处于低电平。
uchar count_temp=1;
uchar timer_status_reg=0x00 ;
uchar init_status=0x00; //程序初始化标志 0x01 表示已经初始化完毕
uchar Meboard_key_num; // =(data_temp1-0x1a)%12 本板的键序号
const uchar lidu1[128]={ //对应力度的脉冲次数的倍数,脉冲高电平越长,力度越大,高电平和低电平之和
0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14, //为255,(定频调宽),当该数减为0后才有脉冲翻转, 目前设定其始0x14
0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
0x14,0x14,0x14,0x14,0x14,0x14,0x14,0x14,
0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
0x34,0x34,0x34,0x34,0x34,0x34,0x34,0x34,
0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
0x64,0x64,0x64,0x64,0x64,0x64,0x64,0x64,
0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,0xb4,
0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,0xc4,
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,
0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0
};
const uchar lidu2[128]={ //对应力度的时间长度,当减为0后,为键保持
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,
};
/* UART初始化 */
void uart_init(void)
{
UCSRB = 0x90; // 0x接收和中断
UBRRL = 31 ; //31250
UBRRH = 0x00 ; //
UCSRC = 0x86 ; //
}
void delay_us(unsigned int time) //us delay
{
do
{
time--;
}
while (time>1);
}
void delay_ms(unsigned int time) //ms delay
{
while(time!=0)
{
delay_us(500);
time--;
}
}
/***********************************************************************************/
#pragma interrupt_handler timer2_ovf_isr:iv_TIMER2_OVF
void timer2_ovf_isr(void) //uS定时中断
{
TCNT2 = 0x80; //
if(init_status==01) //已过初始化
{
Key_lidu_reg[0]--;
Key_lidu_reg[1]--;
Key_lidu_reg[2]--;
Key_lidu_reg[3]--;
Key_lidu_reg[4]--;
Key_lidu_reg[5]--;
Key_lidu_reg[6]--;
Key_lidu_reg[7]--;
Key_lidu_reg[8]--;
Key_lidu_reg[9]--;
Key_lidu_reg[10]--;
Key_lidu_reg[11]--;
}
else
{
timer_status_reg = 0x01; //status
}
}
#pragma interrupt_handler UART_RX_interrupt:iv_USART_RX // 12
void UART_RX_interrupt(void)
{
data_temp = UDR;
switch(Sequence_No) //分析音乐数据流
{
case 0: if((data_temp==0x90)||(data_temp==0xb0)||(data_temp==0x80))
{
Mididata[Sequence_No] = data_temp; //读入缓冲
Sequence_No++;
}
break;
case 1: if(data_temp<128) //有效值范围
{
Mididata[Sequence_No] = data_temp;
data_temp1=data_temp;
//(键号-0x1a)/12+1=板号;(键号-0x1a)%12=板上序号
if (((data_temp1-0x1a)/12+1)==Meboard) //是本板的键
{
Sequence_No++;
}
else //非本板的键
{
Sequence_No=0;
}
}
else //无效值范围
{
Sequence_No=0;
}
break;
case 2: if(data_temp<128)
{
Mididata[Sequence_No] = data_temp; //
Midi_data_flow[data_in]=Mididata[0];
data_in++;
if(data_in>249)
{
data_in=0;
}
Midi_data_flow[data_in]=Mididata[1];
data_in++;
if(data_in>249)
{
data_in=0;
}
Midi_data_flow[data_in]=Mididata[2];
data_in++;
if(data_in>249)
{
data_in=0;
}
Midi_data_flow[data_in]=0;
Sequence_No=0;
}
else
{
Sequence_No=0;
}
break;
}
}
/************************************************************************************
* function: main()
* use:
* input parameter: None
* output parameter: None
************************************************************************************/
void main(void)
{
uchar i, j, k;
PORTB = 0x00; //先关闭键驱动
PORTA = 0x00; //关闭保持脉冲序列
PORTC = 0x00; //
//I/O方向定义 1输出 0输入
DDRA = 0xff;
DDRB = 0xff;
DDRC = 0xff;
DDRD = 0xBf;
PORTB = 0x00; //先关闭键驱动
PORTA = 0x00; //关闭保持脉冲序列
PORTC = 0x00; //
//
//
for(i=0;i<12;i++)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -