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

📄 keydrvavr(16m).c

📁 AVR单片机应用开发指南及实例,包含许多实例,挺不错
💻 C
📖 第 1 页 / 共 3 页
字号:

#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 + -