I2S的函数分析

来源:互联网 发布:js换行符分隔字符串 编辑:程序博客网 时间:2024/06/05 16:19

1、相关寄存器

(1)IIS控制寄存器


(2)IIS模式寄存器


(3)IIS分频寄存器


(4)IIS FIFO接口寄存器


(5)IIS FIFO寄存器


2、程序分析

#include <s3c24xx.h>

1:volatile

  当计算机需要一个数值的时候,会先把内存中的值读取到寄存器,然后下次在使用该值的时候就直接读取寄存器中的值了。加上volatile之后,程序就会在每次需要该值的时候都读取一次内存。这是为了防止某些原因硬件会改变其值。

2:

  (volatile unsigned long *)即为强制类型转换;(volatile unsigned long *)0x55000000 的意思就是把0x55000000强制转换为unsigned long类型的指针。这时(volatile unsigned long *)0x55000000就可以看做是一个指针p了。*(volatile unsigned long*)0x56000010等价于*p,也就是取指针p的地址(取0x56000010的地址)的值。

#define IISCON              (*(volatile unsigned long *)0x55000000)
#define IISMOD              (*(volatile unsigned long *)0x55000004)
#define IISPSR              (*(volatile unsigned long *)0x55000008)
#define IISFCON             (*(volatile unsigned long *)0x5500000C)
#define IISFIFO             (*(volatile unsigned long *)0x55000010)

//前面“s3c2440时钟系统分析”中IIS的时钟是PCLK,50000000是50M的意思,是在u-boot中已经设置好的。

#define PCLK 50000000

#define ABS(a, b) ((a>b)?(a-b):(b-a))

//IIS初始化函数,其中传入的两个参数是每个取样样本的位数和采样率
void iis_init(int bits_per_sample, int fs)
{
    int tmp_fs;
    int i;
    int min = 0xffff;
    int pre = 0;


    /* 配置GPIO用于IIS */
    GPECON &= ~((3<<0) | (3<<2) | (3<<4) | (3<<6) | (3<<8));
    GPECON |= ((2<<0) | (2<<2) | (2<<4) | (2<<6) | (2<<8));
    
    
    /* bit[9] : Master clock select, 0-PCLK  (时钟源是PCLK)
     * bit[8] : 0 = Master mode  (主动发出时钟信号)
     * bit[7:6] : 10 = Transmit mode   (发送模式)
     * bit[4] : 0-IIS compatible format   (格式与外接芯片吻合)
     * bit[2] : 384fs, 确定了MASTER CLOCK之后, fs = MASTER CLOCK/384

     * bit[1:0] : Serial bit clock frequency select, 32fs


     */
   //  bits_per_sample来源于所要读取的文件,如wav文件
    if (bits_per_sample == 16)
        IISMOD = (2<<6) | (0<<4) | (1<<3) | (1<<2) | (1);
    else
        IISMOD = (2<<6) | (0<<4) | (0<<3) | (1<<2) | (1);


    /* Master clock = PCLK/(n+1)//因为要用到分频
     * fs = Master clock / 384
     * fs = PCLK / (n+1) / 384

     */

采样率fs应跟wav文件的采样率相同或相近,因为查IIS分频寄存器可知,值为0~31.看看哪一个误差最小

    for (i = 0; i <= 31; i++)
    {

        tmp_fs = PCLK/384/(i+1);

求出误差最小的分频值

        if (ABS(tmp_fs, fs) < min)
        {

            min = ABS(tmp_fs, fs);

/记录分频系数

            pre = i;
        }

    }

IIS分频寄存器,设置分频参数

    IISPSR = (pre << 5) | (pre);


    /*
     * bit15 : Transmit FIFO access mode select, 1-DMA  (DMA访问模式)
     * bit13 : Transmit FIFO, 1-enable (发送FIFO 使能),把数据写到FIFO寄存器,就可以自动地从IIS接口发给编码芯片(如WM8976)
     */

    IISFCON = (1<<15) | (1<<13);
    
    /*
     * bit[5] : Transmit DMA service request, 1-enable  (发送DMA请求服务使能)
     * bit[1] : IIS prescaler, 1-enable  (IIS时钟分频使能)
     */

    IISCON = (1<<5) | (1<<1) ;
}

//启动IIS功能
void iis_start(void)
{
    IISCON |= (1);
}

//关闭IIS功能
void iis_stop(void)
{
    IISCON &= ~(1);
}


0 0
原创粉丝点击