一個用51單片機成無線鍵盤程序。ID藍牙鍵盤模塊配對后,pin2-Rxd輸入下面的格式即可,電平3.3V。
0.png (11.68 KB, 下載次數: 55)
下載附件
2017-11-20 22:55 上傳
UART2HID程序
單片機源程序如下:
- //-----------------------------------------------------------------------------
- // Includes
- //-----------------------------------------------------------------------------
- #include <c8051f330.h> // SFR declarations
- #include <stdio.h>
- #include "mytype.h"
- #include "config.h"
- static uint16 idle_timeout_time=300;//無按鍵按下超時,5min
- static uint16 idle_timeout=0;//無按鍵按下超時
- static uint8 reconn_flag=0;//重新連接標志
- static uint8 poweroff_flag=0;//關機標志
- static uint8 bat_val=0;//電池電壓
- static uint8 adc_flag=0;//電池電壓測試標志,10min
- static uint16 adc_timeout=0;//電壓測試時間
- uint8 code batt[16]= {0x27,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x05,0x04,0x17,0x10,0x0C,0x11}; //0~9,bat,min
- #define vcc_on 1
- #define vcc_off 0
- #define bl_on 0
- #define bl_off 1
- //-----------------------------------------------------------------------------
- // Global CONSTANTS
- //-----------------------------------------------------------------------------
- #define SYSTEMCLOCK 6125000 // SYSCLK frequency in Hz
- #define BAUDRATE 57600 // Baud rate of UART in bps
- #define TIMER_PRESCALER 48 // Based on Timer CKCON settings
- // There are SYSTEMCLOCK/TIMER_PRESCALER timer ticks per second, so
- // SYSCLK/TIMER_PRESCALER/1000 timer ticks per millisecond.
- #define TIMER_TICKS_PER_MS SYSTEMCLOCK/TIMER_PRESCALER/1000
- // Note: TIMER_TICKS_PER_MS should not exceed 255 (0xFF) for the 8-bit timer
- #define AUX1 TIMER_TICKS_PER_MS
- #define AUX2 -AUX1
- #define TIMER0_RELOAD_HIGH AUX2 // Reload value for Timer0 high byte
- //-----------------------------------------------------------------------------
- // Function PROTOTYPES
- //-----------------------------------------------------------------------------
- void ADC0_Init(void);
- void SYSCLK_Init (void);
- void UART0_Init (void);
- void PORT_Init (void);
- void Timer0_Init (void);
- void KEY_VAL(uint8 tmp);
- void delay_ms(uint16 ms);
- //-----------------------------------------------------------------------------
- // Global Variables
- //-----------------------------------------------------------------------------
- static uint8 tx_buf[12]= {0x0C,0x00,0xA1,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; //HID發送緩沖區
- static uint8 tx_count;//發送字節數,實際發送12個字節
- uint8 fn_flag;//Fn鍵按下狀態
- #define FnDown 0x00
- #define FnUp 0x01
- //key
- #define LCtrl 0x14
- #define LShift 0x12
- #define LAlt 0x10
- #define LGui 0x07
- //#define RCtrl 0x??
- #define RShift 0x59
- #define RAlt 0x13
- //#define RGui 0x??
- #define Fn 0x02
- //fn_key,用于測試。實際使用時查表
- #define Home 0x5E
- #define End 0x2F
- #define PgUp 0x28
- #define PgDown 0x60
- #define Esc 0x0E
- #define F1 0x16
- #define F3 0x26
- //uart緩沖區使用變量
- #define UART_BUFFERSIZE 32
- uint8 UART_Buffer[UART_BUFFERSIZE];
- uint8 UART_Buffer_Size = 0;
- uint8 UART_Input_First = 0;
- uint8 UART_Output_First = 0;
- uint8 TX_Ready =1;
- static uint8 Byte;
- //KEY
- uint8 code key_code[128]=
- {
- 0x00,0x00,0x65,0x00,0x00,0x00,0x00,0xE3,0x29,0x00,0x00,0x00,0x00,0x2B,0x35,0x00,
- 0xE2,0x00,0xE1,0xE6,0xE0,0x14,0x1E,0x00,0x00,0x00,0x1D,0x16,0x04,0x1A,0x1F,0x00,
- 0x00,0x06,0x1B,0x07,0x08,0x21,0x20,0x00,0x52,0x00,0x19,0x09,0x17,0x15,0x22,0x4F,
- 0x00,0x11,0x05,0x0B,0x0A,0x1C,0x23,0x00,0x00,0x00,0x10,0x0D,0x18,0x24,0x25,0x00,
- 0x00,0x36,0x0E,0x0C,0x12,0x27,0x26,0x00,0x00,0x37,0x38,0x0F,0x33,0x13,0x2D,0x00,
- 0x00,0x00,0x34,0x00,0x2F,0x2E,0x00,0x00,0x39,0xE5,0x28,0x30,0x2C,0x31,0x50,0x00,
- 0x51,0x00,0x00,0x00,0x00,0x00,0x4C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x2A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- //Fn_KEY
- uint8 code fn_key_code[128]=
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x3A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3B,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x3D,0x3C,0x00,0x4B,0x00,0x00,0x00,0x00,0x00,0x3E,0x4D,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x41,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x43,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4A,0x00,
- 0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- //-----------------------------------------------------------------------------
- // MAIN Routine
- //-----------------------------------------------------------------------------
- void main (void)
- {
- uint8 i,tmp;
- PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
- // enable)
- PORT_Init(); // Initialize Port I/O
- SYSCLK_Init (); // Initialize Oscillator
- UART0_Init();
- Timer0_Init (); //1ms定時器
- vcc_ctrl = vcc_on;//打開系統總電源,1開0關
- bl_conn_ctrl= 0;//根據外部按鈕的狀態控制藍牙模塊
- zb_led2 = 0;//1為亮,0為滅,LED2未連接
- //bl_state 為藍牙模塊狀態輸入
- //key_int0 按鍵中斷及開機
- //zb_adc0 電池電壓判斷
- idle_timeout=0;
- reconn_flag=0;//重新連接標志
- poweroff_flag=0;
- adc_flag=0;
- //'0c 00 a1 01 00 00 27 00 00 00 00 00
- tx_buf[0]=0x0C;//固定開頭
- tx_buf[1]=0x00;
- tx_buf[2]=0xA1;
- tx_buf[3]=0x01;
- tx_buf[4]=0x00;//功能鍵shift、alt、ctrl、win
- tx_buf[5]=0x00;//固定00
- tx_buf[6]=0x00;//后面6個字節為按鍵碼
- tx_buf[7]=0x00;
- tx_buf[8]=0x00;
- tx_buf[9]=0x00;
- tx_buf[10]=0x00;
- tx_buf[11]=0x00;
- fn_flag=FnUp;
- ADC0_Init();
- bl_vcc_ctrl = bl_on;//1為關閉藍牙電源,0為開啟
- EA = 1;
- while(1)
- {
- delay_ms(10);
- if(TX_Ready == 1 && UART_Buffer_Size != 0)
- {
- TX_Ready = 0; // Set the flag to zero
- // If a new word is being output
- if ( UART_Buffer_Size == UART_Input_First )
- {
- UART_Output_First = 0;
- }
- tmp = UART_Buffer[UART_Output_First];
- KEY_VAL(tmp);
- UART_Output_First++; // Update counter
- UART_Buffer_Size--; // Decrease array size
- TI0 = 1; // Set transmit flag to 1
- }
- else
- {
- UART_Buffer_Size = 0; // Set the array size to 0
- TX_Ready = 1; // Indicate transmission complete
- }
- if(reconn_flag)
- {
- idle_timeout=0;//重新連接按下則空閑等待置0,從新計數
- reconn_flag=0;
- bl_conn_ctrl=1;//藍牙清楚記憶,重新連接
- delay_ms(2000);
- bl_conn_ctrl=0;
- }
- if(poweroff_flag)
- {
- poweroff_flag=0;
- vcc_ctrl=vcc_off;//總電源關閉
- }
- if(adc_flag)
- {
- adc_flag=0;
- ADC0_Init();
- }
- }
- }
- //-----------------------------------------------------------------------------
- // Initialization Subroutines
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // PORT_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // Configure the Crossbar and GPIO ports.
- //
- // P0.4 digital push-pull UART TX
- // P0.5 digital open-drain UART RX
- //
- //-----------------------------------------------------------------------------
- void PORT_Init (void)
- {
- P1MDIN = 0x7F;
- P0MDOUT = 0x14;
- P1MDOUT = 0x48;
- XBR0 = 0x01; // Enable UART on P0.4(TX) and P0.5(RX)
- XBR1 = 0x40; // Enable crossbar and weak pull-ups
- }
- //ADC Init P1.7-GND
- void ADC0_Init()
- {
- uint8 k;
- uint16 adc_val;
- EA=0;
- delay_ms(50);
- AMX0P = 0x0F;//P1.7
- AMX0N = 0x11;//GND
- ADC0CF |= 0x04;//LEFT ADJUST
- AD0EN = 1;
- adc_val = 0;
- for(k=0; k<10; k++)
- {
- AD0INT=0;
- AD0BUSY=1;//轉換ADC
- while(!AD0INT);//等待轉換完成
- if(k>4)adc_val += ADC0H;
- }
- AD0EN = 0;
- k=(uint8)(adc_val / 5)+3;//補償3-36mv,4-48mv
- if(k>115)bat_val=100;//2776
- else if(k>110)bat_val=75;//2655
- else if(k>105)bat_val=50;//2535
- else if(k>100)bat_val=40;//2414
- else if(k>95)bat_val=30;//2293
- else if(k>90)bat_val=20;//2173
- else if(k>85)bat_val=10;//2052
- else if(k>80)bat_val=5;//1931
- else //if(k>75)//1811
- {
- bat_val=0;
- poweroff_flag=1;
- }
- EA=1;
- }
- //-----------------------------------------------------------------------------
- // SYSCLK_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // This routine initializes the system clock to use the internal oscillator
- // at its maximum frequency.
- // Also enables the Missing Clock Detector.
- //-----------------------------------------------------------------------------
- void SYSCLK_Init (void)
- {
- OSCICN = 0x81; //6.125MHz
- RSTSRC = 0x04; // Enable missing clock detector
- }
- //1ms定時器
- void Timer0_Init (void)
- {
- TH0 =TIMER0_RELOAD_HIGH;
- CKCON |= 0x02;//48分頻
- TL0 = TH0; // init Timer1
- TMOD &= ~0x0F; // TMOD: timer 1 in 8-bit autoreload
- TMOD |= 0x02;
- TR0 = 1;
- ET0=1;
- }
- //-----------------------------------------------------------------------------
- // UART0_Init
- //-----------------------------------------------------------------------------
- //
- // Return Value : None
- // Parameters : None
- //
- // Configure the UART0 using Timer1, for <BAUDRATE> and 8-N-1.
- //-----------------------------------------------------------------------------
- void UART0_Init (void)
- {
- SCON0 = 0x10; // SCON0: 8-bit variable bit rate
- // level of STOP bit is ignored
- // RX enabled
- // ninth bits are zeros
- // clear RI0 and TI0 bits
- if (SYSTEMCLOCK/BAUDRATE/2/256 < 1)
- {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2);
- CKCON &= ~0x0B; // T1M = 1; SCA1:0 = xx
- CKCON |= 0x08;
- }
- else if (SYSTEMCLOCK/BAUDRATE/2/256 < 4)
- {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/4);
- CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 01
- CKCON |= 0x01;
- }
- else if (SYSTEMCLOCK/BAUDRATE/2/256 < 12)
- {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/12);
- CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 00
- }
- else
- {
- TH1 = -(SYSTEMCLOCK/BAUDRATE/2/48);
- CKCON &= ~0x0B; // T1M = 0; SCA1:0 = 10
- CKCON |= 0x02;
- }
- TL1 = TH1; // init Timer1
- TMOD &= ~0xf0; // TMOD: timer 1 in 8-bit autoreload
- TMOD |= 0x20;
- TR1 = 1; // START Timer1
- TX_Ready = 1; // Flag showing that UART can transmit
- IP |= 0x10; // Make UART high priority
- ES0 = 1; // Enable UART0 interrupts
- }
- //-----------------------------------------------------------------------------
- // Interrupt Service Routines
- //-----------------------------------------------------------------------------
- //-----------------------------------------------------------------------------
- // Timer0_ISR
- //-----------------------------------------------------------------------------
- void Timer0_ISR (void) interrupt 1
- {
- static int counter = 0;
- if((counter++) >= 1000)
- {
- counter = 0;
- idle_timeout++;
- adc_timeout++;
- if(idle_timeout>=idle_timeout_time)//5min
- {
- idle_timeout=0;
- poweroff_flag=1;
- }
- if(adc_timeout>=600)//10min
- {
- adc_timeout=0;
- adc_flag=1;
- }
- }
- }
- //-----------------------------------------------------------------------------
- // UART0_Interrupt
- //-----------------------------------------------------------------------------
- //
- // This routine is invoked whenever a character is entered or displayed on the
- // Hyperterminal.
- //
- //-----------------------------------------------------------------------------
- void UART0_Interrupt (void) interrupt 4
- {
- idle_timeout=0;//有按鍵接收則,空閑等待時間置0,從新計數
- if (RI0 == 1)
- {
- if( UART_Buffer_Size == 0) // If new word is entered
- {
- UART_Input_First = 0;
- }
- RI0 = 0; // Clear interrupt flag
- Byte = SBUF0; // Read a character from UART
- if (UART_Buffer_Size < UART_BUFFERSIZE)
- {
- UART_Buffer[UART_Input_First] = Byte; // Store in array
- UART_Buffer_Size++; // Update array's size
- UART_Input_First++; // Update counter
- }
- }
- if (TI0 == 1) // Check if transmit flag is set
- {
- TI0 = 0; // Clear interrupt flag
- if (tx_count <12) // 總共發送12個字節
- {
- // Store a character in the variable byte
- SBUF0= tx_buf[tx_count++];
- }
- else
- {
- tx_count = 0; // Set the array size to 0
- TX_Ready = 1; // Indicate transmission complete
- }
- }
- }
- //鍵值處理
- void KEY_VAL(uint8 tmp)
- {
- switch (tmp)
- {
- case LCtrl:
- {
- tx_buf[4]|=0x01;
- break;
- }
- case LShift:
- {
- tx_buf[4]|=0x02;
- break;
- }
- case LAlt:
- {
- tx_buf[4]|=0x04;
- break;
- }
- case LGui:
- {
- tx_buf[4]|=0x08;
- break;
- }
- case RShift:
- {
- tx_buf[4]|=0x20;
- break;
- }
- case RAlt:
- {
- tx_buf[4]|=0x40;
- break;
- }
- case LCtrl+0x80:
- {
- tx_buf[4]&=~0x01;
- break;
- }
- case LShift+0x80:
- {
- tx_buf[4]&=~0x02;
- break;
- }
- case LAlt+0x80:
- {
- tx_buf[4]&=~0x04;
- break;
- }
- case LGui+0x80:
- {
- tx_buf[4]&=~0x08;
- break;
- }
- case RShift+0x80:
- {
- tx_buf[4]&=~0x20;
- break;
- }
- case RAlt+0x80:
- {
- tx_buf[4]&=~0x40;
- break;
- }
- case Fn:
- {
- fn_flag=FnDown;
- tx_buf[6]=0x00;
- break;
- }
- case Fn+0x80:
- {
- fn_flag=FnUp;
- tx_buf[6]=0x00;
- tx_buf[7]=0x00;
- tx_buf[8]=0x00;
- tx_buf[9]=0x00;
- tx_buf[10]=0x00;
- tx_buf[11]=0x00;
- break;
- }
- default :
- {
- if(tmp & 0x80)
- {
- tx_buf[6]=0x00;
- tx_buf[7]=0x00;
- tx_buf[8]=0x00;
- tx_buf[9]=0x00;
- tx_buf[10]=0x00;
- tx_buf[11]=0x00;
- }
- else
- {
- if(fn_flag==FnUp)
- {
- tx_buf[6]=key_code[tmp];
- }
- if(fn_flag==FnDown) //Fn鍵按下
- {
- if(tmp==0x2B)//Fn+F//重新連接
- {
- tx_buf[6]=0x00;
- reconn_flag=1;//重新連接標志置1
- }
- if(tmp==0x5D)//Fn+A=1c///0x5D(ok)//關機標志
- {
- tx_buf[6]=0x00;
- poweroff_flag=1;//關機標志置1
- }
- if(tmp==0x64)//Fn+S=1b///0x4A/67(BAT)//電池電量
- {
- ADC0_Init();
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
UART2HID程序.zip
(548.7 KB, 下載次數: 28)
2017-11-20 19:01 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|