MP3模块和TM1637驱动

MP3模块应用

最近用51做了一边播放音乐一边拍打亮灯的按键的游戏机,涉及到MP3模块播放音乐和数码管的驱动,这里记录一下。

先放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();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值