赞
踩
最近用51做了一边播放音乐一边拍打亮灯的按键的游戏机,涉及到MP3模块播放音乐和数码管的驱动,这里记录一下。
#define MP3_BUFF_LEN 10 uint8_t MP3_CMD_BUFF[MP3_BUFF_LEN]; uint16_t MP3_CheckSum(uint8_t *mp3_cmd) { uint16_t sum = 0; uint8_t i; for (i = 1; i < 7; i++) { sum += mp3_cmd[i]; } return -sum; } void MP3_set_Cmd_buff(uint8_t *mp3_cmd, uint8_t cmd, uint8_t feedback, uint16_t dat) { uint16_t checksum; uint8_t i; mp3_cmd[0] = 0X7E; mp3_cmd[1] = 0XFF; mp3_cmd[2] = 0X06; mp3_cmd[3] = cmd; mp3_cmd[4] = feedback; mp3_cmd[5] = (uint8_t)(dat >> 8); mp3_cmd[6] = (uint8_t)dat; checksum = MP3_CheckSum(mp3_cmd); mp3_cmd[7] = (uint8_t)(checksum >> 8); mp3_cmd[8] = (uint8_t)checksum; mp3_cmd[9] = 0xEF; // for(i = 0;i<10;i++) // { // LOG("mp3_cmd[%d] = 0x%x\n",(uint16_t)i,(uint16_t)mp3_cmd[i]); // } } //具体的指令直接调用这个函数输入就可以了,通过串口4发送给MP3模块 void MP3_CMD_Uart_Send(uint8_t cmd, uint8_t feedback, uint16_t dat) { MP3_set_Cmd_buff(MP3_CMD_BUFF, cmd, feedback, dat); uart4_put(MP3_CMD_BUFF, MP3_BUFF_LEN); } //串口4的代码 bit busy4 = 0; void Uart4Isr() interrupt 18 { if (S4CON & 0x02) { S4CON &= ~0x02; busy4 = 0; } if (S4CON & 0x01) { S4CON &= ~0x01; } } void Uart4Init(void) // 9600bps@35.000MHz MP3模块要用9600比特率 { P5_IO_QB(2); P5_IO_QB(3); P_SW2 = 0x04; // RXD4_2/P5.2, TXD4_2/P5.3 S4CON = 0x10; S4CON &= 0xBF; AUXR |= 0x04; T2L = 0x8F; T2H = 0xFD; AUXR |= 0x10; } void uart4_puc(char dat) { while (busy4) ; busy4 = 1; S4BUF = dat; } void uart4_put(uint8_t *p, uint8_t len) { while (len--) { uart4_puc(*p++); } }
typedef enum { TM1637_A = 1 << 0, TM1637_B = 1 << 1, TM1637_C = 1 << 2, TM1637_D = 1 << 3, TM1637_E = 1 << 4, TM1637_F = 1 << 5, TM1637_G = 1 << 6, TM1637_H = 1 << 7, } TM1637_AG_E; uint8_t TM1637_Write_Cmd(uint8_t byte) { uint8_t status = 0; soft_i2c_Start(); soft_i2c_SendByte(byte); status |= soft_i2c_WaitAck(); soft_i2c_Stop(); return status; } uint8_t TM1637_WriteDisplayData(uint8_t addr, uint8_t Ddata) { uint8_t status = 0; soft_i2c_Start(); soft_i2c_SendByte(addr); status |= soft_i2c_WaitAck(); status <<= 1; soft_i2c_SendByte(Ddata); status |= soft_i2c_WaitAck(); status <<= 1; soft_i2c_Stop(); return status; } uint8_t TM1637_Key_Scan() { uint8_t status = 0; uint8_t rxbuf = 0; soft_i2c_Start(); soft_i2c_SendByte(TM1637_READ_KEY_DATA_CMD); status |= soft_i2c_WaitAck(); status <<= 1; rxbuf = soft_i2c_ReadByte(0); soft_i2c_Stop(); return rxbuf; } uint8_t Key_Press_Check() { uint8_t KeyStatus; KeyStatus = TM1637_Key_Scan(); if (KeyStatus != 0xff) { LOG("****KEY SCAN ERROR****"); return 0; } else { LOG("****KEY SCAN SUCCESS****"); return KeyStatus; } } /**位置0~5, 支持显示的符号数 0~9, ' ', '-', '.' */ void TM1637_DisplayNumber(uint8_t pos, uint8_t num) { if (pos > 5) pos = 5; if (num >= TM1637_CHARACTER_SUPPORT_COUNT) num = TM1637_CHARACTER_SUPPORT_COUNT - 1; switch (pos) { case 0: TM1637_WriteDisplayData(TM1637_SEG1_ADDR, TM1637_NUMBER[num]); break; case 1: TM1637_WriteDisplayData(TM1637_SEG2_ADDR, TM1637_NUMBER[num]); break; case 2: TM1637_WriteDisplayData(TM1637_SEG3_ADDR, TM1637_NUMBER[num]); break; case 3: TM1637_WriteDisplayData(TM1637_SEG4_ADDR, TM1637_NUMBER[num]); break; case 4: TM1637_WriteDisplayData(TM1637_SEG5_ADDR, TM1637_NUMBER[num]); break; case 5: TM1637_WriteDisplayData(TM1637_SEG6_ADDR, TM1637_NUMBER[num]); break; default: break; } } void TM1637_Display_time(uint16_t time) { uint8_t timeArray[3] = {10, 10, 10}; TM1637_Write_Cmd(TM1637_DISPLAY_CMD); TM1637_Write_Cmd(TM1637_DISPLAY_ON | TM1637_BRIGHTNESS_8); timeArray[2] = time % 10; timeArray[1] = time / 10 % 10; timeArray[0] = time / 100 % 10; TM1637_DisplayNumber(3, 0); TM1637_DisplayNumber(4, timeArray[1]); TM1637_DisplayNumber(5, timeArray[2]); } //模拟I2C的驱动 TM1637数据读取和写入都是从低位开始 要注意 void soft_i2c_Delay() { unsigned char i; i = softI2cDelayT; while (--i) ; } void soft_i2c_Start(void) { I2C_SDA_1(); I2C_SCL_1(); soft_i2c_Delay(); I2C_SDA_0(); soft_i2c_Delay(); I2C_SCL_0(); soft_i2c_Delay(); } void soft_i2c_SendByte(uint8_t _ucByte) { uint8_t i; /* 先发送字节的低位 */ for (i = 0; i < 8; i++) { if (_ucByte & 0x01) { I2C_SDA_1(); } else { I2C_SDA_0(); } soft_i2c_Delay(); I2C_SCL_1(); soft_i2c_Delay(); I2C_SCL_0(); // if (i == 7) // { // I2C_SDA_1(); // 释放总线 // } _ucByte >>= 1; /* 左移一个bit */ // soft_i2c_Delay(); } I2C_SDA_1(); // 释放总线 } uint8_t soft_i2c_ReadByte(u8 ack) { uint8_t i; uint8_t value; /* 读到第1个bit为数据的bit1 */ // I2C_SDA_INPUT(); // set data input soft_i2c_Delay(); value = 0; for (i = 0; i < 8; i++) { value >>= 1; I2C_SCL_1(); soft_i2c_Delay(); if (I2C_SDA_READ()) { value |=0x80; } else { value|=0x00; } //I2C_SCL_1(); //soft_i2c_Delay(); I2C_SCL_0(); soft_i2c_Delay(); } // I2C_SDA_OUTPUT(); // set data output soft_i2c_Delay(); if (ack == 0) soft_i2c_NAck(); else soft_i2c_Ack(); return value; } uint8_t soft_i2c_WaitAck(void) { uint8_t re; I2C_SDA_1(); /* CPU释放SDA总线 */ // I2C_SDA_INPUT(); //set data input soft_i2c_Delay(); soft_i2c_Delay(); I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */ soft_i2c_Delay(); soft_i2c_Delay(); if (I2C_SDA_READ()) /* CPU读取SDA口线状态 */ { re = 1; } else { re = 0; } I2C_SCL_0(); // I2C_SDA_OUTPUT(); //set data output soft_i2c_Delay(); return re; } void soft_i2c_Stop(void) { // I2C_SCL_OUTPUT(); // I2C_SDA_OUTPUT(); /* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */ I2C_SDA_0(); I2C_SCL_1(); soft_i2c_Delay(); I2C_SDA_1(); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。