最近在使用STM32F407ZGT6主芯片驱动CMX649语音编解码芯片,但是没找到相应的驱动程序,只能自己编写源程序。可是本人刚开始接触单片机,所以根据CMX649的datasheet编写驱动程序感到很吃力。我现在在编写CMX649的接口函数,但是调试了很久不知道问题出在哪里希望各位大神看后能帮我分析一下。
以下是CMX649的接口时序图,该芯片使用的是C-BUS接口,其时序图如下:
由于STM32主芯片没有C-BUS总线,因此只能利用STM32的GPIO通过软件来模拟C-BUS接口,下面是我编写的接口函数:
(注:CMX649的寄存器要么是只读,要么是只写,另外有些寄存器是16位的,有些是8位的,所以在写寄存器和读寄存器时分开来写,
分别是写一个字节/两个字节和读一个字节/两个字节。)
#include "delay.h"
#include "CBUS.h"
/***************************************************************
本程序只供学习使用,未经作者许可,不得用于其它任何用途
平台:ALIENTEK STM32F407开发板
功能:CBUS 软件模拟代码
作者:Qing yy
日期: 2016/4/14
版本:V1.0
***************************************************************/
//定义IO操作函数
#define CMX_SCLK_H GPIO_SetBits(GPIOC, GPIO_Pin_5)
#define CMX_SCLK_L GPIO_ResetBits(GPIOC, GPIO_Pin_5)
#define CMX_CMD_H GPIO_SetBits(GPIOC, GPIO_Pin_0)
#define CMX_CMD_L GPIO_ResetBits(GPIOC, GPIO_Pin_0)
#define CMX_CSN_H GPIO_SetBits(GPIOC, GPIO_Pin_4)
#define CMX_CSN_L GPIO_ResetBits(GPIOC, GPIO_Pin_4)
#define CMX_RPLY GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_7)
//初始化CBUS
void CBUS_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOB, ENABLE);//使能GPIOC/GPIOB时钟
//GPIOC0,C4,C5初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_5 | GPIO_Pin_4;//PC0,PC4,PC5
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC
//GPIOB7初始化设置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //PB7
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB
GPIO_SetBits(GPIOC,GPIO_Pin_0 | GPIO_Pin_5 | GPIO_Pin_4);//开始时将PC0,PC4,PC5置高
GPIO_ResetBits(GPIOB,GPIO_Pin_7);//开始时将PB7置低
}
//定义一个软件延时函数
static void delay(u16 value)
{
u32 j, i= 1;
for(j=1;j<value;j++)
i++;
}
//定义与C -BUS相干的几个函数,采用伪代码描述
//CMX649的片选信号控制
static void CS_cmx649(u32 value)
{
if(value)
CMX_CSN_H; //片选信号为1
else
CMX_CSN_L; //片选信号为0
}
//CMX649的时钟信号控制
static void set_cmx649clk(u32 value)
{
if(value)
CMX_SCLK_H; //时钟I/O口置1
else
CMX_SCLK_L; //时钟I/O口置0
}
//CMX649的数据出信号的控制
static void set_cmx649bit(u32 value)
{
if(value)
CMX_CMD_H; //数据出端口置1
else
CMX_CMD_L; //数据出端口置0
}
/****************************************
函数: cmx_put_char
说明:通过C -BUS写一字节数据,为内部函数
参数:abyte需要写入的字节数据
返回:无
****************************************/
void cmx_put_char(unsigned char abyte)
{
unsigned char i= 8;
unsigned char bit;
//Uchar data= abyte;
set_cmx649clk(0);
for(i=0; i<8; i++)
{
delay(0xff);
bit=((abyte&0x80)? 1:0);
set_cmx649bit(bit);
delay(0xff);
set_cmx649clk(1);
abyte<<=1;
delay(0xff);
set_cmx649clk(0);
}
}
/***************************************
函数: cmx_get_char
说明:通过C -BUS读一字节数据,为内部函数
参数:无
返回:读出的字节数据
*****************************************/
unsigned char cmx_get_char(void)
{
unsigned char i=8;
u32 data,value=0;
set_cmx649clk(0);
for(i=0;i<8;i++)
{
set_cmx649clk(1);
delay(0xff);
data=CMX_RPLY;
data=data&0x1000;
value=value<<1;
if(data)
value|=0x1;
set_cmx649clk(0);
}
return(value);
}
/**************************************************
函数: cmx_write_command
说明:向CMX649寄存器写,为内部函数
参数:addr需要写入的CMX寄存器地址.为无符号字符型
返回:无
**************************************************/
void cmx_write_command(unsigned char addr)
{
set_cmx649clk(0);
CS_cmx649(0);
cmx_put_char(addr);
CS_cmx649(1);
set_cmx649clk(0);
}
/**************************************************
函数: cmx_write_byte
说明:向CMX649寄存器写入一字节数据,为内部函数
参数:addr需要写入的CMX寄存器地址,为无符号字符型
abyte需要写入的字节数据,为无符号字符型
返回:无
***************************************************/
void cmx_write_byte(unsigned char addr,unsigned char abyte)
{
set_cmx649clk(0);
CS_cmx649(0);
cmx_put_char(addr);
delay(0xff);
cmx_put_char(abyte);
CS_cmx649(1);
set_cmx649clk(0);
}
/**********************************************
功能: cmx_write_word
说明:向CMX649寄存器写入16位字数据,为内部函数
参数:addr需要写入的CMX寄存器地址,为无符号字符型
aword需要写入的字数据,为无符号整型
返回:无
**********************************************/
void cmx_write_word(unsigned char addr,unsigned int aword)
{
CS_cmx649(0);
set_cmx649clk(0);
cmx_put_char(addr);
cmx_put_char(aword/0x100); //* char_temp
cmx_put_char(aword%0x100); //* char_temp
CS_cmx649(1);
set_cmx649clk(0);
}
/**********************************************
函数: cmx_read_byte
说明:自CMX649寄存器读出8位字节数据,为内部函数
参数:addr需要读出的CMX寄存器地址,为无符号字符型
返回:读出的字节数据,为无符号字符型
***********************************************/
unsigned char cmx_read_byte(unsigned char addr)
{
unsigned char byte_temp;
CS_cmx649(0);
set_cmx649clk(0);
cmx_put_char(addr);
byte_temp=cmx_get_char();
CS_cmx649(1);
set_cmx649clk(0);
return(byte_temp);
}
/********************************************
函数: cmx_read_word
说明:自CMX649寄存器读出16位字数据,为内部函数
参数:addr需要读出的寄存器地址,为无符号字符型
返回:读出的字数据,为无符号整型
*********************************************/
unsigned int cmx_read_word(unsigned char addr)
{
unsigned int a_int_temp=0x0000;
CS_cmx649(0);
set_cmx649clk(0);
cmx_put_char(addr);
delay(0xff);
a_int_temp=cmx_get_char()*0x100;
a_int_temp+=cmx_get_char();
CS_cmx649(1);
set_cmx649clk(0);
return(a_int_temp);
}
我在测试的时候调用这些接口函数去配置相应的寄存器,以及读出相应寄存器的值,编译时没有问题的,可无奈没成功,现在我主要就是不能确定这些接口函数是否正确,可是我自己又没老师指导,只能在这里求助各位,希望你们能分出你们宝贵的时间看看,谢了。
一周热门 更多>