/***********************************************************/
//Title:ATMEGA128L-直接朗读文本的语音合成芯片驱动-串口发送查询接收中断方式
//ICC-AVR : 2009-5-24 12:25:40
// Target : M128
// Crystal: 8.0000Mhz
//Author :borlittle
//QQ:634172943
//Function:OSYNO6188 VOICE CHIP BEIJING driver
//备注 :本程序经调试好使,北京益世通利智能通讯技术有限公司
//OSYNO6188语音合成芯片驱动,不过串口如果查询接收不到数据可能造成死机
/***********************************************************/
#include <iom128v.h>
#include <macros.h>
#define uchar unsigned char //定义无符号字符为 uchar
#define uint unsigned int //定义无符号整型
#define Crystal 8000000 //晶振8MHZ
#define Baud 1200 //波特率
#define prog_fj_datalength 26
#define lj_datalength 6 //定义汉字语音数据内容字个数
#define prog_lj_datalength lj_datalength<<1 //定义汉字语音数据内容实际内存中个数
#define sj_datalength 7 //定义汉字语音数据内容字个数
#define prog_sj_datalength sj_datalength<<1 //定义汉字语音数据内容实际内存中个数
#define ks_datalength 4 //定义汉字语音数据内容字个数
#define prog_ks_datalength ks_datalength<<1 //定义汉字语音数据内容实际内存中个数
#define sd_datalength 5 //定义汉字语音数据内容字个数
#define prog_sd_datalength sd_datalength<<1 //定义汉字语音数据内容实际内存中个数
#define start_play 4
float V;
uint v1,v2,v3;
uchar erro_counter; //错误重发次数计数器
uchar play_voice_signal; //语音播放各函数重发标志
uchar music_count=0xB7;
uchar data_temp; //串口接收数据缓冲
uchar usart0_data_counter=0;//串口接收中断计数
//正式应用
uchar end[]={0x04};//结束字节
uchar data0[2]={0x00,0x00};
uchar set[]={0x01,0x80,0x84,0xC5,0x04};//帧数据设置
//发送起始字,不用中断,保持原来设置输出,波特率保持原来,正常工作不休眠
//不回传歌词,播放一遍,第一个字按姓处理,文本不朗读标点符号,‘1’不读为“幺1”
//反馈全部播音结束的回应,不要背景,音量6级
uchar music_data[2]={0x60,0xB0};
uchar out_data[]={0x01,0x90,0x80,0x80,0x04,0x95};//改成DA 输出
//改成PWM 输出: 0x01,0xa0,0x80,0x80,0x04,0xa5(其中0xa5为本数据帧校验字)
//改成DA 输出: 0x01,0x90,0x80,0x80,0x04,0x95(其中0x95为本数据帧校验字)
uchar usart0_data_receive[3]={0x0f,0x0f,0x0f};//接收串口数据
//提示音数据
uchar lj_data[]={"请输入轮径值"};
uchar sj_data[]={"请输入测试时间"};
uchar ks_data[]={"测试开始"};
uchar sd_data[]={"千米每小时"};
uchar fj_data[]={0xA3,0xB0,0xA3,0xB1,0xA3,0xB2,0xA3,0xB3,0xA3,0xB4,0xA3,0xB5,0xA3,0xB6,0xA3,0xB7,0xA3,0xB8,0xA3,0xB9,0xCA,0xAE,0xB0,0xD9,0xC7,0xA7};
//0,1,2,3,4,5,6,7,8,9,十,百,千
//函数声明
void port_init(void);
void usart0_init(void);
void init_devices(void);
void usart0_char_send(uchar i);
void usart0_str_send(char *s);
uchar usart0_char_receive(void);
void usart0_receive_data(void);
uchar usart0_char_receive(void);
void delay_1ms(void);
void delay_nms(uint n);
uchar checkbyte(uchar *t,uchar length);
void delay_1us(void);
void delay_nus(uint n);
void number_voice(uchar number);
void speed_unit(void);
void read_speed(void);
void test_start_voice(void);
void wheel_voice(void);
void play_music(void);
void test_time_voice(void);
void delay_nthms(uint n);
void conv(uint M);
void resend(void);
void out_change(void);
/******************延时1us**************************/
void delay_1us(void)
{asm("nop");
}
/************将变量i分解成待显示数并存入数组***********/
void conv(uint M)
{
v1=M/100;
delay_nus(3);
v2=(M/10)%10;
delay_nus(3);
v3=M%10;
}
/********************延时n us*************************/
void delay_nus(uint n)
{
uint i="0";
for (i=0;i<n;i++)
delay_1us();
}
/*****************延时1毫秒子函数*******************/
void delay_1ms(void)
{
uint i;
for(i=1;i<(8*143-2);i++) //8为晶振频率
;
}
/****************延时N毫秒子函数****************/
void delay_nms(uint n)
{
uint i;
for(i=0;i<n;i++)
delay_1ms();
}
/****************延时1秒子函数****************/
void delay_nthms(uint n)
{
uint i,j=1000*n;
for(i=0;i<j;i++)
delay_1ms();
}
/******************端口初始化*******************************/
void port_init(void)
{
PORTE = 0xFF; //设置RXD0和TXD0
DDRE = 0x02;
PORTB = 0x10; //设置PB4为上拉输入
DDRB = 0xEF;
PORTD = 0X00; //D口用于输出指示回应帧数据
DDRD = 0xFF; //初始为低电平
}
/*****************串口0初始化*********************************/
void usart0_init(void)
{
UCSR0B = 0x00; //禁止发送和接收
UCSR0A = 0x02; //倍速异步模式USX0=1
UCSR0C = 0x06; //0000 0110,UCSZ01=1,UCSZ00=1;8位字符,1位停止位
UBRR0L=(Crystal/8/(Baud+1))%256; //若为正常异步模式USX0=0则位(Crystal/16/(Baud+1))%256
UBRR0H=(Crystal/8/(Baud+1))/256; //参见ATMEGA128使用手册
UCSR0B=0x98; //允许发送和接收,接收结束中断使能
}
/******************初始化器件**************************************/
void init_devices(void)
{
port_init();
usart0_init();
}
//****************发送一个字符******************************
void usart0_char_send(uchar i)
{
while(!(UCSR0A&(1<<UDRE0)));
UDR0=i;
}
/******************发送一个字符串*************************/
void usart0_str_send(char *s)
{
while(*s)
{
usart0_char_send(*s);
s++;
}
}
/*********************发送一个数组**********************/
void usart0_str_sendArray(uchar *q,uchar len)
{
uchar i;
for(i=0;i<len;i++) //控制字符个数
{
usart0_char_send(*q);
q++;
}
}
/*******************校验发送错误重发****************************/
//如果缺少重发则可能造成实际工作不稳定,有时能读有时不读的现象
void resend(void)
{
erro_counter=0;
erro_counter++;
if((usart0_data_receive[1]==0x10)&(erro_counter<4))
{
PORTD|=0X01; //指示发错
switch(play_voice_signal)
{
case 0: out_change();break;
case 1: test_start_voice();PORTD |=0X02;break;//重发,并指示
case 2: wheel_voice();PORTD |=0X02;break;
case 3: test_time_voice();PORTD |=0X02;break;
//case 4: number_voice();PORTD |=0X02;break;
case 5: read_speed();PORTD |=0X02;break;
case 6: play_music();PORTD |=0X02;break;
case 7: speed_unit();PORTD |=0X02;break;
default:delay_nms(1);PORTD |=0X02;break;
}
}
if(usart0_data_receive[1]==0x11) //接收成功
PORTD|=0X04;
if(usart0_data_receive[1]==0x12) //播放完成
PORTD|=0X08;
}
/****************中断接收服务处理子程序*******************************/
#pragma interrupt_handler usart0_RX_interrupt:iv_USART0_RX // 19
void usart0_RX_interrupt(void)
{
data_temp = UDR0; //从数据缓冲器中接收数据
usart0_data_receive[usart0_data_counter]=data_temp;
usart0_data_counter++;
if(usart0_data_counter==3) //如果已接收到的字符个数为3
{
resend();
usart0_data_counter = 0; //计数复位
}
}
/**********************计算异或校验字节*****************/
uchar checkbyte(uchar *t,uchar length)
{
uchar i,checkword1;
checkword1=*t;
t++;
for(i=1;i<length;i++) //控制字符个数
{
checkword1=checkword1^(*t);
t++;
}
return(checkword1);
}
/*****************播放方式输出(单独数据帧)改变指令*******************************/
void out_change(void)
{
play_voice_signal=0;
usart0_str_sendArray(out_data,6);
}
/*****************测试开始提示发音*******************************/
void test_start_voice(void)
{
uchar checkword_set,checkword_ks_data,checkword;
play_voice_signal=1;
checkword_ks_data=checkbyte(ks_data,prog_ks_datalength);
checkword_set=checkbyte(set,5);
checkword=checkword_set^checkword_ks_data;
usart0_str_sendArray(set,4);
usart0_str_sendArray(ks_data,prog_ks_datalength);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/*****************输入轮径值提示发音*******************************/
void wheel_voice(void)
{
uchar checkword_set,checkword_lj_data,checkword;
play_voice_signal=2;
checkword_lj_data=checkbyte(lj_data,prog_lj_datalength);
checkword_set=checkbyte(set,5);
checkword=checkword_set^checkword_lj_data;
usart0_str_sendArray(set,4);
usart0_str_sendArray(lj_data,prog_lj_datalength);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/*****************输入测试时间提示发音*******************************/
void test_time_voice(void)
{
uchar checkword_set,checkword_sj_data,checkword;
play_voice_signal=3;
checkword_sj_data=checkbyte(sj_data,prog_sj_datalength);
checkword_set=checkbyte(set,5);
checkword=checkword_set^checkword_sj_data;
usart0_str_sendArray(set,4);
usart0_str_sendArray(sj_data,prog_sj_datalength);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/*****************单数字按键发音*******************************/
void number_voice(uchar number)
{
uchar number_data[2];
uchar checkword_set,checkword_number,checkword,seek_number;
play_voice_signal=4;
seek_number=number<<1;
number_data[0]=fj_data[seek_number];
number_data[1]=fj_data[seek_number+1];
checkword_set=checkbyte(set,5);
checkword_number=checkbyte(number_data,2);
checkword=checkword_number^checkword_set;
usart0_str_sendArray(set,4);
usart0_str_sendArray(number_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/*****************播放音乐*******************************/
void play_music(void)
{
uchar checkword_set,checkword_music_data,checkword;
play_voice_signal=6;
checkword_music_data=checkbyte(music_data,2);
checkword_set=checkbyte(set,5);
checkword=checkword_set^checkword_music_data;
usart0_str_sendArray(set,4);
usart0_str_sendArray(music_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/*****************播报速度语音*******************************/
void read_speed(void)
{
uchar checkword_set,checkword,seek_number,number;//定义校验数据变量
uchar checkword_consd1_data,checkword_consd2_data,checkword_consd3_data;
uchar checkword_shi_data,checkword_bai_data;
uchar con_data[3];
uchar bai_data[2],shi_data[2];//定义字库语音码变量
uchar v1_data[2],v2_data[2],v3_data[2];
play_voice_signal=5;
conv(V);//转换速度值
con_data[0]=v1;con_data[1]=v2;con_data[2]=v3;//获取转换后的值
//将每个值对应查出其字库语音码
number=con_data[0];
seek_number=number<<1;
v1_data[0]=fj_data[seek_number];
v1_data[1]=fj_data[seek_number+1];
number=con_data[1];
seek_number=number<<1;
v2_data[0]=fj_data[seek_number];
v2_data[1]=fj_data[seek_number+1];
number=con_data[2];
seek_number=number<<1;
v3_data[0]=fj_data[seek_number];
v3_data[1]=fj_data[seek_number+1];
number=10;
seek_number=number<<1;
shi_data[0]=fj_data[seek_number];
shi_data[1]=fj_data[seek_number+1];
bai_data[0]=fj_data[seek_number+2];
bai_data[1]=fj_data[seek_number+3];
checkword_set=checkbyte(set,5);
checkword_shi_data=checkbyte(shi_data,2);
checkword_bai_data=checkbyte(bai_data,2);
if(con_data[0]!=0) //百位不为0,朗读从百位开始
{
if(con_data[2]==0)//个位为0
{
if(con_data[1]==0)//十位个位都为0
{
checkword_consd1_data=checkbyte(v1_data,2);
checkword=checkword_consd1_data^checkword_set;
checkword=checkword_bai_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v1_data,2);
usart0_str_sendArray(bai_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
else{ //只有个位为0
checkword_consd1_data=checkbyte(v1_data,2);
checkword_consd2_data=checkbyte(v2_data,2);
checkword=checkword_consd1_data^checkword_set;
checkword=checkword_consd2_data^checkword;
checkword=checkword_shi_data^checkword;
checkword=checkword_bai_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v1_data,2);
usart0_str_sendArray(bai_data,2);
usart0_str_sendArray(v2_data,2);
usart0_str_sendArray(shi_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
}
else if((con_data[1]==0)&(con_data[2]!=0)) //只有十位为0
{
checkword_consd1_data=checkbyte(v1_data,2);
checkword_consd2_data=checkbyte(v2_data,2);
checkword_consd3_data=checkbyte(v3_data,2);
checkword=checkword_consd1_data^checkword_set;
checkword=checkword_consd2_data^checkword;
checkword=checkword_consd3_data^checkword;
checkword=checkword_bai_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v1_data,2);
usart0_str_sendArray(bai_data,2);
usart0_str_sendArray(v2_data,2);
usart0_str_sendArray(v3_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
else//个位、十位全不为0
{
checkword_consd1_data=checkbyte(v1_data,2);
checkword_consd2_data=checkbyte(v2_data,2);
checkword_consd3_data=checkbyte(v3_data,2);
checkword=checkword_consd1_data^checkword_set;
checkword=checkword_consd2_data^checkword;
checkword=checkword_consd3_data^checkword;
checkword=checkword_shi_data^checkword;
checkword=checkword_bai_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v1_data,2);
usart0_str_sendArray(bai_data,2);
usart0_str_sendArray(v2_data,2);
usart0_str_sendArray(shi_data,2);
usart0_str_sendArray(v3_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
}
else //百位为0
{
if(con_data[1]==0)//十位为0,只朗读个位
{
checkword_consd3_data=checkbyte(v3_data,2);
checkword=checkword_consd3_data^checkword_set;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v3_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
else if (con_data[2]==0)//只朗读十位,不朗读个位
{
checkword_consd2_data=checkbyte(v2_data,2);
checkword=checkword_consd2_data^checkword_set;
checkword=checkword_shi_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v2_data,2);
usart0_str_sendArray(shi_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
else //朗读十位和个位
{
checkword_consd2_data=checkbyte(v2_data,2);
checkword_consd3_data=checkbyte(v3_data,2);
checkword=checkword_consd2_data^checkword_set;
checkword=checkword_consd3_data^checkword;
checkword=checkword_shi_data^checkword;
usart0_str_sendArray(set,4);
usart0_str_sendArray(v2_data,2);
usart0_str_sendArray(shi_data,2);
usart0_str_sendArray(v3_data,2);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
}
}
/*****************播放速度单位*******************************/
void speed_unit(void)
{
uchar checkword_set,checkword_sd_data,checkword;
play_voice_signal=7;
checkword_sd_data=checkbyte(sd_data,prog_sd_datalength);
checkword_set=checkbyte(set,5);
checkword=checkword_set^checkword_sd_data;
usart0_str_sendArray(set,4);
usart0_str_sendArray(sd_data,prog_sd_datalength);
usart0_str_sendArray(end,1);
usart0_char_send(checkword);
}
/***************主函数*****************************/
void main(void)
{
uchar i;
CLI(); //总中断禁止
init_devices(); //初始化
SEI();
out_change();
delay_nms(800);//发送完改波特率或改输出方式的系统包后,要暂停几百毫秒,再改主机的波特率
delay_nms(800);
while(1)
{
if((PINB&0x10)!=0x10) //通过按键测试其连播性能,PB4被拉低?
{
V=114;
read_speed();
}
}
}
文章评论(0条评论)
登录后参与讨论