源码结构
设计框图
下面就Basic_io.h,Functions.h,Main.c,Functions.c作说明
basic_io.h
#ifndef __basic_io_H__
#define __basic_io_H__
#define BYTE unsigned char
#define UINT16 unsigned int
#define UINT32 unsigned long
#include <io.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include "system.h"
#include "sys/alt_irq.h"
// for GPIO
#define inport(base) IORD(base, 0)
#define outport(base, data) IOWR(base, 0, data)
#define get_pio_dir(base) IORD(base, 1)
#define set_pio_dir(base, data) IOWR(base, 1, data)
#define get_pio_irq_mask(base) IORD(base, 2)
#define set_pio_irq_mask(base, data) IOWR(base, 2, data)
#define get_pio_edge_cap(base) IORD(base, 3)
#define set_pio_edge_cap(base, data) IOWR(base, 3, data)
// for SEG7 Display
#define seg7_show(base,data) IOWR(base, 0, data)
// for Time Delay
#define msleep(msec) usleep(1000*msec);
#define Sleep(sec) msleep(1000*sec);
#endif
Fuctions.h
#ifndef _FUNCTIONS_H_
#define _FUNCTIONS_H_
#include "basic_io.h"
#include "LCD.h"
#include "Open_I2C.h"
#include "SD_Card.h"
#include <stdlib.h>
#include <string.h>
#define ITEM_NUM 3 //Audio项目总数
#define VOL_MAX 255 //Max Volume
#define MEM_NUM 3 //存储器个数
#define MEM_BASE_REC 0x00000010
#define MEM_BASE 0x00000000
#define SRAM_MAX 0x00040000 //512K 0x00040000 * 16 Bits=512K;
#define SDRAM_MAX 0x00400000 //8M 0x00400000 * 16 bits=8M
#define CFI_FLASH_MAX 0x00200000 //4M 0x00400000 * 8 bits=4M
/*定义七段数码管,LED默认值*/
#define SEG7_VALUE 0x88888888
#define LED_GREEN_VALUE 0x1FF
#define LED_RED_VALUE 0x3FFFF
/*定义Button的延时以及中断Mask*/
#define BUTTON_STOP_TIME 500000 // us
#define BUTTON_INT_MASK 0xF
/*设定I2C频率*/
#define I2C_FREQ 100000 // 100Khz
/*函数原型*/
void Init_All(void);
void LED_red(UINT32);
void LED_green(BYTE);
void Audio_test(void);
void Button_Irq_Init(void);
void Timer_Irq_Init(void);
int Button_Handle(void);
void Mode_Recover_Timer_Handle(void);
void Audio_Mode_Go(int);
void Vol_Go(int);
void Mem_Choose_Go(int);
UINT32 Get_Mem_Max(void);
char * Vol_Str(BYTE);
void test_sdram(void);
void test_cfi_flash(void);
#endif //_FUNCTIONS_H_
Main.C
#include "functions.h"
/*引进Functions.C文件中的全局变量*/
extern int AUDIO_MODE_INDEX;
extern int FUNC_MODE;
extern int INIT_FLAG;
extern int MEM_CHOOSE;
extern int CODEC_TYPE;
extern char STR_ITEM[ITEM_NUM][17];
extern char STR_DOING[ITEM_NUM][17];
extern char STR_STOPED[ITEM_NUM][17];
extern char STR_TITLE[17];
/*主函数中的变量*/
UINT32 AUDIO_RD_ADD=MEM_BASE_REC; //读地址
UINT32 AUDIO_WR_ADD=MEM_BASE_REC; //写地址
UINT16 WR_DATA=0x0000; //读数据
UINT16 RD_DATA=0x0000; //写数据
int RecValid=0,RecLastValid=0; //读有效变量,读上次有效变量(状态变化时改写)
int SpeValid=0,SpeLastValid=0; //写有效变量,写上次有效变量(状态变化时改写)
/*本文件中函数原型声明*/
void Recording();
void Speaking();
UINT16 MemoryRead(UINT32);
void MemoryWrite(UINT32,UINT16);
void RecordMem_End(UINT32);
void ShowStatus(int);
/*主函数*/
int main()
{
Init_All();
while(1)
{
if(FUNC_MODE==0) //Audio模式,主模式
{
/*根据模式选择功能,可扩展更多功能*/
switch(AUDIO_MODE_INDEX)
{
case 0: Recording();break;
case 1: Speaking();break;
case 2: SD_Card_Player();break;
}//end switch
}//end if(FUNC_MODE==0)
}//end while(1)
/*测试部分*/
// test_cfi_flash();
//test_sdram();
}
/*放音函数定义*/
void Speaking()
{
IOWR(AUDIO_CTRL_BASE,0,0); //对AUD_MOD写控制信号 0为向DAC FIFO输出
/*判断 最后一位Switch开关 如果是开的就继续*/
SpeValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);
if(SpeLastValid!=SpeValid)
{
ShowStatus(SpeValid);
}
SpeLastValid=SpeValid;
while(SpeValid)//valid
{
if(!IORD(AUDIO_FULL_BASE,0))
{
if(AUDIO_RD_ADD<=AUDIO_WR_ADD)
{
RD_DATA=MemoryRead(AUDIO_RD_ADD);
LED_red(RD_DATA);
IOWR(SEG7_DISPLAY_BASE,0,AUDIO_RD_ADD++);
IOWR(AUDIO_MOD_BASE,0,RD_DATA);
}
}
SpeValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);
}
}
/*录音程序定义*/
void Recording()
{
IOWR(AUDIO_CTRL_BASE,0,1); ////对AUD_MOD写控制信号 1为向ADC FIFO输出
RecValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);
if(RecLastValid!=RecValid)
{
ShowStatus(RecValid);
}
RecLastValid=RecValid;
while(RecValid)
{
if(!IORD(AUDIO_EMPTY_BASE,0))
{
if(AUDIO_WR_ADD<=Get_Mem_Max())
{
WR_DATA=IORD(AUDIO_MOD_BASE,0);
LED_red(WR_DATA);
MemoryWrite(AUDIO_WR_ADD,WR_DATA);
IOWR(SEG7_DISPLAY_BASE,0,AUDIO_WR_ADD++);
}
}
RecValid=(IORD(SWITCH_PIO_BASE,0)& 0x00001);
}
}
/*向内存中写入结束地址——作为系统Init后检查的标志*/
//暂时没有用到
void RecordMem_End(UINT32 addr)
{
UINT16 temp=0;
temp=(UINT16)addr;
IOWR(SRAM_0_BASE,MEM_BASE,temp);
temp=addr>>16;
IOWR(SRAM_0_BASE,MEM_BASE+1,temp);
}
/*录音、放音状态显示--改变LCD屏幕的显示 */
//根据当前的Audio状态显示不同内容的 Runnning Stop信息
//输入1 为Running 0 为Stoped
void ShowStatus(int status)
{
if(status) //running
{
LCD_Show(STR_ITEM[AUDIO_MODE_INDEX],STR_DOING[AUDIO_MODE_INDEX]);
}
else //stoped
{
LCD_Show(STR_ITEM[AUDIO_MODE_INDEX],STR_STOPED[AUDIO_MODE_INDEX]);
}
}
/*写存储器,对外封装为统一接口 根据全局变量MEM_CHOOSE来选择存储器
* 输入32位地址线,16位数据线
* */
void MemoryWrite(UINT32 Addr,UINT16 Data)
{
switch(MEM_CHOOSE )
{
case 0:{
IOWR_16DIRECT(SRAM_0_BASE,Addr,Data);break;
}
case 1:{
IOWR_16DIRECT(SDRAM_0_BASE,Addr,Data);break;
}
case 2:{
IOWR_8DIRECT(CFI_FLASH_0_BASE,Addr<<1,(BYTE)Data); //Low Bits
IOWR_8DIRECT(CFI_FLASH_0_BASE,(Addr<<1)+1,(BYTE)(Data>>8)); //High Bits
break;
}
}
}
/*写存储器,对外封装为统一接口 根据全局变量MEM_CHOOSE来选择存储器
* 输入32位地址线,16位数据线
* */
UINT16 MemoryRead(UINT32 Addr)
{
UINT16 readdata=0;
switch(MEM_CHOOSE )
{
case 0:{
readdata=IORD_16DIRECT(SRAM_0_BASE,Addr);break;
}
case 1:{
readdata=IORD_16DIRECT(SDRAM_0_BASE,Addr);break;
}
case 2:{
readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,(Addr<<1)+1); //High Bits
readdata<<=8;
readdata+=IORD_8DIRECT(CFI_FLASH_0_BASE,Addr<<1); //Low Bits
}
}
return readdata;
}
Functions.C
#include "functions.h"
/*引进外部变量*/
extern UINT32 AUDIO_RD_ADD;
extern UINT32 AUDIO_WR_ADD;
/*模式说明:
* FUNC_MOD=0 主模式(Audio模式)FUNC_MOD不为零 为其他模式(例如音量调节)
* 当为“其他模式”时,如果三秒钟买有按键,则自动跳转主模式(由定时器实现)
* */
int FUNC_MODE=0; /*模式标号*/
int AUDIO_MODE_INDEX=0; /*主模式中的子模式标号*/
BYTE VOL=127; /*音量调节模式*/
int MEM_CHOOSE=0; //0 SRAM ,1 SDRAM ,2 Flash RAM, 3 USB ,4 SD_Card
/* 存储器选择子模式 */
int CODEC_TYPE=0; //0 No Compress ,1 DPM ,2 ADPM,3 MP3&Other ....
/* 编码方案选择子模式(待扩展) */
int KEY_STATUS=0; /*按键码*/
int MENU_TIME_OUT=3000; //ms
int INIT_FLAG=0; /*初始化标识,*/
/*以下是字符串常量定义*/
char STR_TITLE[17]="HUST AC0506 IC08";
char STR_VOL[17]="";
char STR_ITEM[ITEM_NUM][17]={
"Audio Recorder ", // 0
"Audio Speaker ", // 1
"SD Music Player " // 2
};
char STR_DOING[ITEM_NUM][17]={
"Recording ... ", // 0
"Speaking ... ", // 1
"Music Playing..." // 2
};
char STR_STOPED[ITEM_NUM][17]={
"Recorder Stopped", // 0
"Speak Stopped. ", // 1
"SD Music Stopped" // 2
};
char STR_MEM[MEM_NUM][17]={
"Use 512K SRAM ", // 0
"Use 8M SDRAM ", // 1
"Use 4M CFI Flash" // 2
};
/*红色LED亮起*/
void LED_red(UINT32 num)
{
UINT32 led_red_mask=0x0000ffff; //right 18 bits
IOWR(LED_RED_BASE,0,led_red_mask&num);
}
/*绿色LED亮起*/
void LED_green(BYTE num)
{
UINT16 led_green_mask=0x0ff; //right 8 bits
IOWR(LED_GREEN_BASE,0,led_green_mask&num);
}
//设置按键中断函数
void Button_Irq_Init()
{
/* Enable all 4 button interrupts. */
set_pio_irq_mask(BUTTON_PIO_BASE, BUTTON_INT_MASK);
/* Reset the edge capture register. */
set_pio_edge_cap(BUTTON_PIO_BASE, 0x0);
/* Register the interrupt handler. */
alt_irq_register( BUTTON_PIO_IRQ, NULL, (void*)Button_Handle);
}
//设置定时器中断函数
void Timer_Irq_Init()
{
IOWR(TIMER_0_BASE,0,0x0); //最低一位To 写零清中断 第二位RUN为标志位,写无效
IOWR(TIMER_0_BASE,1,0x1); //最后四位依次为 Stop Start Cont ITO
// Stop Start 置一有效,Cont 置一循环,ITO中断使能;
//基址是4byte为一个单位,即一个偏移量
alt_irq_register( TIMER_0_IRQ, NULL, (void*)Mode_Recover_Timer_Handle);
}
//定时器三秒恢复函数(切换主模式)
void Mode_Recover_Timer_Handle()
{
if(FUNC_MODE)
{
FUNC_MODE=0;
LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);
}
//printf("sorry!");
}
//按键事件处理函数
int Button_Handle()
{
KEY_STATUS=get_pio_edge_cap(BUTTON_PIO_BASE); //捕捉按键码
outport(LED_GREEN_BASE,KEY_STATUS); //亮相应的灯xxms
set_pio_edge_cap(BUTTON_PIO_BASE,0x0);
usleep(BUTTON_STOP_TIME);
outport(LED_GREEN_BASE,0);
//do switch
/*如果程序运行Running,除复位键以外无效*/
if((IORD(SWITCH_PIO_BASE,0)& 0x00001)&&KEY_STATUS!=1)
{
return 0;
}
//判断模式,做相应的事情
switch(FUNC_MODE)
{
case 0: switch(KEY_STATUS) //菜单
{
case 1 : { INIT_FLAG=1;break;}
case 2 : { LCD_Show(STR_TITLE,Vol_Str(VOL));FUNC_MODE+=1;break; } //goto VOL Mode
case 4 : { Audio_Mode_Go(1);LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);break; }
case 8 : { Audio_Mode_Go(-1);LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);break; }
};
break;
case 1: switch(KEY_STATUS) // 音量
{
case 1 : {INIT_FLAG=1;break;}
case 2 : {LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);FUNC_MODE+=1;break;}
//goto Menu Mode
case 4 : {Vol_Go(1);LCD_Show(STR_TITLE,Vol_Str(VOL));break;}
case 8 : {Vol_Go(-1);LCD_Show(STR_TITLE,Vol_Str(VOL));break;}
};
break;
case 2: switch(KEY_STATUS) // 存储位置
{
case 1 : {INIT_FLAG=1;break;}
case 2 : {LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);FUNC_MODE=0;break;}
//goto Menu Mode
case 4 : {Mem_Choose_Go(1);LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);break;}
case 8 : {Mem_Choose_Go(-1);LCD_Show(STR_TITLE,STR_MEM[MEM_CHOOSE]);break;}
};
break;
default:break;
}
//Init DATA;
/*如果初始化Flag==1 则执行初始化*/
if(INIT_FLAG)
{
LCD_Show(STR_TITLE,"Init.");
msleep(300);
LCD_Show(STR_TITLE,"Init..");
msleep(300);
LCD_Show(STR_TITLE,"Init....");
msleep(300);
LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);
INIT_FLAG=0;
Init_All();
}
//非Audio状态超时自动切换到Audio状态
IOWR(TIMER_0_BASE,0,0x0);//清计时器中断
return 1;
}
void Audio_Mode_Go(int jump)
{
if(jump==1){
AUDIO_MODE_INDEX++;
}
else if(jump==-1)
{AUDIO_MODE_INDEX--;
}
else{;}
if(AUDIO_MODE_INDEX> ITEM_NUM-1) AUDIO_MODE_INDEX=0;
if(AUDIO_MODE_INDEX<0) AUDIO_MODE_INDEX=ITEM_NUM-1;
}
void Mem_Choose_Go(int jump)
{
if(jump==1){
MEM_CHOOSE++;
}
else if(jump==-1)
{MEM_CHOOSE--;
}
else{;}
if(MEM_CHOOSE> MEM_NUM-1) MEM_CHOOSE=0;
if(MEM_CHOOSE<0) MEM_CHOOSE=MEM_NUM-1;
//do some thing
AUDIO_RD_ADD=MEM_BASE_REC;
AUDIO_WR_ADD=MEM_BASE_REC;
}
UINT32 Get_Mem_Max()
{
switch(MEM_CHOOSE)
{
case 0:return SRAM_MAX;
case 1:return SDRAM_MAX;
case 2:return CFI_FLASH_MAX;
default:return 0;
}
}
void Vol_Go(int jump)
{
if(jump==1&&VOL!=255){
VOL+=32;
}
if(jump==-1&&VOL!=31)
{VOL-=32;
}
//set Volume I2C
if(AUDIO_MODE_INDEX==0)
{
I2C_Send(0x34,0x00,VOL);
I2C_Send(0x34,0x02,VOL);
}
else if(AUDIO_MODE_INDEX==1)
{
I2C_Send(0x34,0x04,VOL);
I2C_Send(0x34,0x06,VOL);
}
}
char * Vol_Str(BYTE in)
{
char tmp1[17]="";
strcpy(tmp1,"Volume : ");
char tmp2[3]="";
tmp2[0]='0'+VOL/32;
tmp2[1]='\0';
strcat(tmp1,tmp2);
return strcpy(STR_VOL,tmp1);
}
void Init_All()
{
//Init Varibles;
FUNC_MODE=0;
AUDIO_MODE_INDEX=0;
VOL=127;
MEM_CHOOSE=0;
CODEC_TYPE=0;
AUDIO_RD_ADD=MEM_BASE_REC;
AUDIO_WR_ADD=MEM_BASE_REC;
//-------------------------------
// Refresh LED
outport(LED_GREEN_BASE,LED_GREEN_VALUE);
outport(LED_RED_BASE,LED_RED_VALUE);
// Refresh SEG7
seg7_show(SEG7_DISPLAY_BASE,SEG7_VALUE);
// I2C Core Initial & Set Freq = 100 Khz
I2C_Init(10000000/I2C_FREQ-1);
// Check Video Encoder on I2C Bus, Address = 0x40
if(I2C_Send(0x40,1,1))
printf("\nFind Video Encoder on I2C Bus, Address = 0x40.\n");
else
printf("\nCan't Find Video Encoder on I2C Bus.\n");
// Check Audio CODEC on I2C Bus, Address = 0x34
if(I2C_Send(0x34,1,1))
printf("\nFind Audio CODEC on I2C Bus, Address = 0x34.\n");
else
printf("\nCan't Find Audio CODEC on I2C Bus.\n");
msleep(500);
outport(LED_GREEN_BASE,0);
outport(LED_RED_BASE,0);
seg7_show(SEG7_DISPLAY_BASE,0);
// Show LCD Test Text
LCD_Test();
msleep(1000);
LCD_Show(STR_TITLE,STR_ITEM[AUDIO_MODE_INDEX]);
// Set Button PIO Interrupts
Button_Irq_Init();
//Timer_Irq_Init();
}
/*测试函数*/
void Audio_test()
{
UINT16 out_temp=0x55AA;
UINT16 in_temp=0x0000;
IOWR(AUDIO_CTRL_BASE,0,1); //adc
while(1)
{
in_temp=IORD(AUDIO_MOD_BASE,0);
LED_red((UINT32)in_temp);
out_temp=~out_temp;
IOWR(AUDIO_MOD_BASE,0,out_temp);
usleep(125);
}
}
void test_sdram()
{
int key=0;
UINT16 j=0;
UINT32 r_add=0,w_add=0;
while(1)
{
key=IORD(SWITCH_PIO_BASE,0);
if(key){
IOWR(LED_RED_BASE,0,j);
IOWR_16DIRECT(SDRAM_0_BASE,w_add,j);
IOWR(SEG7_DISPLAY_BASE,0,w_add);
w_add++;
j++;
}
else
{
if(r_add<=w_add){
IOWR(SEG7_DISPLAY_BASE,0,r_add);
IOWR(LED_RED_BASE,0,IORD_16DIRECT(SDRAM_0_BASE,r_add));
r_add++;
}
}
//msleep(1);
}
}
void test_cfi_flash()
{
int key=0;
UINT16 j=10;
UINT32 temp=0;
BYTE t=0;
UINT16 readdata=0;
//BYTE readdata=0;
UINT32 r_add=0,w_add=0;
while(1)
{
key=IORD(SWITCH_PIO_BASE,0);
if(key){
LED_green(j);
//IOWR_8DIRECT(CFI_FLASH_0_BASE,w_add,j);
temp=(UINT32)(w_add<<1);
t=j;
printf("t=%d",t);
IOWR_8DIRECT(CFI_FLASH_0_BASE,temp,255); //Low Bits
t=(j>>8);
printf("t=%d\n",t);
IOWR_8DIRECT(CFI_FLASH_0_BASE,temp+1,255); //High Bits
msleep(500);
printf("%d-",IORD_8DIRECT(CFI_FLASH_0_BASE,temp)); //Low Bits
printf("%d=",IORD_8DIRECT(CFI_FLASH_0_BASE,temp+1)); //High Bits
IOWR(SEG7_DISPLAY_BASE,0,w_add);
printf("%d\t",j);
//printf("%d\t",IORD_8DIRECT(CFI_FLASH_0_BASE,w_add));
w_add++;
j++;
}
else
{
if(r_add<=w_add){
IOWR(SEG7_DISPLAY_BASE,0,r_add);
//readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,r_add);
readdata=IORD_8DIRECT(CFI_FLASH_0_BASE,(r_add<<1)+1); //High Bits
readdata<<=8;
readdata+=IORD_8DIRECT(CFI_FLASH_0_BASE,r_add<<1); //Low Bits
printf("%d\t",readdata);
LED_green(readdata);
r_add+=1;
}
}
msleep(1000);
}
}