main.c
/*****************************************************************************
* 项 目: 基于科大讯飞XF-S4040语音播放小系统
* 功 能: 实现SPI转UART(spi从机模式)
* 目标系统: ATmega8L-8AU
* 时 钟: 7.3728MHz
* 开发软件: AVR Studio4.14
* 版 本: Version 1.0
* 原版时间: 2009-05-13
* 修改时间:
* 说 明:
* 开发人员: zjf
* 说 明: spi从模式MOSI刚开始设置为输入时未发生spi中断,设置为输出中断发生,有待进一步验证!
进一步测试,设置为输入也可以进入中断,奇怪!!!
*****************************************************************************/
#include<avr/io.h>
#include <avr/wdt.h>
#include<util/delay.h>
#include<avr/eeprom.h>
#include<avr/pgmspace.h>
#include<avr/interrupt.h>
#include<avr/signal.h>
#include"uart.h"
#define CHECK_4040 (PINC&0x02) //判S4040状态,1=忙,0=就绪
#define BUSY_4040 (PORTC=PORTC|0x01) //输出S4040忙信号
#define READY_4040 (PORTC=PORTC&0xFE) //输出S4040就绪信号
/*----------------SPI端口定义-----------------*/
#define SPI_CS_DDR DDRB
#define SPI_CS_PORT PORTB
#define SPI_CS_BIT 2
#define SPI_SCK_DDR DDRB
#define SPI_SCK_PORT PORTB
#define SPI_SCK_BIT 5
#define SPI_MOSI_DDR DDRB
#define SPI_MOSI_PORT PORTB
#define SPI_MOSI_BIT 3
#define SPI_MISO_DDR DDRB
#define SPI_MISO_PORT PORTB
#define SPI_MISO_BIT 4
#define SPI_PORT_INI {\
SPI_CS_PORT |= 1<<SPI_CS_BIT;\
SPI_SCK_PORT |= 1<<SPI_SCK_BIT;\
SPI_MOSI_PORT |= 1<<SPI_MOSI_BIT;\
SPI_MISO_PORT |= 1<<SPI_MISO_BIT;\
\
SPI_CS_DDR &= ~(1<<SPI_CS_BIT);\
SPI_SCK_DDR &= ~(1<<SPI_SCK_BIT);\
SPI_MOSI_DDR &= ~(1<<SPI_MOSI_BIT);\
SPI_MISO_DDR |= 1<<SPI_MISO_BIT;\
}
unsigned char spi_buf[850]={0,0,0,0,0,0,0,0,0};//语音信息存储区
volatile unsigned char spi_ok=0;
unsigned int spi_rxd_count=0;
unsigned int data_length=0;
unsigned char is_head=0;
unsigned char tmp="0";
//格式:帧头(1字节)数据区长度(2字节)数据区(包括命令字 文本编码格式 待合成文本)
//测试音“科大讯飞”
//unsigned char com_buf[13]={0XFD,0X00,0X0A,0X01,0X00,0XBF,0XC6,0XB4,0XF3,0XD1,0XB6,0XB7,0XC9};
/************************************************************
* 函数名称:void SPI_Low()
* 功 能:SPI初始化为低速模式
* 入口参数:无
* 出口参数:无
************************************************************/
void SPI_Low(void)
{
SPCR &= ~_BV(DORD);
SPCR = _BV(SPE)|_BV(MSTR)|_BV(SPR0);
SPSR &= ~_BV(SPI2X);
}
/************************************************************
* 函数名称:void SPI_High()
* 功 能:SPI初始化为高速模式
* 入口参数:无
* 出口参数:无
************************************************************/
void SPI_High(void)
{
//从模式下速率取决于主机
//SPCR &= ~_BV(MSTR);//从模式,默认为从机,不用重配置
SPCR = _BV(SPE)|_BV(SPIE);/* 使能 SPI,中断允许 */
// SPSR |= _BV(SPI2X);
}
/************************************************************
* 函数名称:void SPI_Init()
* 功 能:SPI初始化
* 入口参数:无
* 出口参数:无
************************************************************/
void SPI_Init(void)
{
SPI_High();
SPI_PORT_INI; /* Spi Initialize */
SPSR = 0x00;
tmp = SPSR;
tmp = SPDR; //清空SPI,和中断标志,使SPI空闲
}
/************************************************************
* 函数名称: void port_init(void)
* 功 能:端口初始化
* 入口参数:无
* 出口参数:无
************************************************************/
void port_init(void)
{
PORTC=0xfe;//1111 1110 PC0上电输出4040为就绪状态
DDRC=0xfd;//1111 1101 PC1检测4040状态,配置为输入; PC0输出4040状态
PORTD = 0x00;//无上拉
DDRD = 0x00;//输入
}
/************************************************************
* 函数名称:init_devices()
* 功 能:系统初始化
* 入口参数:无
* 出口参数:无
************************************************************/
void init_devices(void)
{
//stop errant interrupts until set up
cli(); //disable all interrupts
port_init();
uart_init();
SPI_Init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x00; //timer interrupt sources
sei(); //re-enable interrupts
//all peripherals are now initialized
}
/************************************************************
* 函数名称:SIGNAL(SIG_SPI)
* 功 能:spi中断
* 入口参数:无
* 出口参数:无
************************************************************/
SIGNAL(SIG_SPI)//spi中断
{
tmp="SPDR";
if(is_head==0)
{
if(tmp==0xfd) //判断帧头
is_head=1;
}
if(is_head==1)
{
spi_buf[spi_rxd_count]=tmp; //存入spi数据存储区
spi_rxd_count++; //spi接收数据计数加1
}
if(spi_rxd_count==3) //如果接收到了3个字节,则计算数据长度,共两字节,高字节在前,低字节在后
{
data_length=spi_buf[1];
data_length=(data_length<<8)|spi_buf[2];
}
if(spi_rxd_count==(data_length+3))//判断一帧数据是否结束
{
spi_ok=1;
}
}
/************************************************************
* 函数名称:int main()
* 功 能:主函数
* 入口参数:无
* 出口参数:无
************************************************************/
int main()
{
init_devices();
//_delay_ms(1000); _delay_ms(1000); _delay_ms(1000);
//send_string(com_buf , 13); //测试音“科大讯飞”
wdt_enable(WDTO_1S); //看门狗初始化为1秒
wdt_reset();//喂狗
while(1)
{
if(spi_ok)
{
cli();//关中断
BUSY_4040;//忙
_delay_ms(10);
wdt_reset();//喂狗
send_string(spi_buf ,spi_rxd_count ); //向语音芯片发送信息
wdt_reset();//喂狗
spi_ok=0;
spi_rxd_count=0;
data_length=0;
is_head=0;
_delay_ms(10);
sei();//开中断
}
if(CHECK_4040==0) //检测语音芯片状态
{
READY_4040; //就绪
}
else BUSY_4040;//忙
wdt_reset();//喂狗
}
}
|