小R科技-WIFI机器人网·机器人创意工作室

 找回密码
 立即注册
查看: 4931|回复: 0

STC12C5A60S2单片机驱动ISD1760语音模块程序

[复制链接]
发表于 2016-8-7 10:34:20 | 显示全部楼层 |阅读模式
单片机驱动语音模块实现定点播放语音
  1. /*************************************************
  2.         功  能:STC12C5A60S2驱动ISD1760语音模块
  3.         单片机:STC12C5A60S2
  4.         晶  振:11.0592M
  5.         作  者:苏义江根据1730改编
  6.         时  间:2016-8-4
  7.         说  明:单片机4个IO口接1760的SS,SCLK,MOSI,MOSO.
  8.                         地址从0x0010开始安自己所录得语音长度调节
  9.                         通过按键或传感器定点播放'你好欢迎光临。你好请避让。
  10.                         这是你点的菜谢谢。欢迎再次光临再见'
  11. ***************************************************/
  12. #include<stc12c5a60s2.h>
  13. #define uchar unsigned char
  14. #define uint unsigned int
  15. #define  PU                     0x01// 上电
  16. #define  STOP            0x02//停止
  17. #define  RESET            0x03//复位
  18. #define  CLI_INT           0x04//清除EOM标志和中断信号
  19. #define  RD_STATUS          0x05//返回状态寄存器内容
  20. //在1,2字节返回状态寄存器信息,2,3字节返回放音指针
  21. #define  RD_PLAY_PTR 0x06
  22. #define  PD                    0x07//芯片下电
  23. //在1,2字节返回状态寄存器信息,2,3字节返回录音指针
  24. #define  RD_REC_PTR  0x08
  25. #define  RD_DEVID          0x09//读取芯片ID号码
  26. #define  PLAY        0x40   //从当前地址放音
  27. #define  REC         0x41   //从当前地址录音
  28. #define  ERASE       0x42   //擦除当前语音段
  29. #define  G_ERASE     0x43   //擦除芯片所有语音
  30. //返回状态寄存器信息在1,2字节,APC寄存器信息在3字节
  31. #define  RD_APC            0x44
  32. //将<D11:D0>写入APC寄存器
  33. #define  WR_APC1            0x45
  34. #define  WR_NVCFG    0x46//将APC内容写入NVCFG
  35. #define  LD_NVCFG    0x47   //将NVCFG内容写入APC
  36. #define  FWD         0x48   //将放音指针指向下一段语音地址处
  37. #define  CHK_MEM          0x49//检查环状存储体系
  38. #define  EXTCLK      0x4a    //外部时钟使能
  39. //将<D11:D0>写入APC寄存器,并由<D2:D0>位控制音量
  40. #define  WR_APC2            0x65
  41. #define  SET_PLAY    0x80//从起始地址<S10:S0>放音到结束地址<E10:E0>结束
  42. #define  SET_REC            0x81//从起始地址<S10:S0>录音到结束地址<E10:E0>结束
  43. #define  SET_ERASE   0x82//从起始地址<S10:S0>擦除到结束地址<E10:E0>结束
  44. #define  HIGH 1
  45. #define  LOW 0
  46. #define  NOP _nop_()//定义除命令外剩余字节个数  
  47. #define Surplus_One_BYTE    1     //定义字节个数为4
  48. #define Surplus_Two_BYTE    2     //定义字节个数为2
  49. #define Surplus_Three_BYTE  3     //定义字节个数为3

  50. #define ENISD1760_SS        ISD1760_SS=0
  51. #define DISENISD1760_SS     ISD1760_SS=1
  52. #define ISD1760_MISO_L      ISD1760_MISO=0
  53. #define ISD1760_MISO_H      ISD1760_MISO=1
  54. #define ISD1760_MOSI_L      ISD1760_MOSI=0
  55. #define ISD1760_MOSI_H      ISD1760_MOSI=1
  56. #define ISD1760_SCLK_L      ISD1760_SCLK=0
  57. #define ISD1760_SCLK_H      ISD1760_SCLK=1
  58. ////接收1730内部返回的数
  59. uchar SR0H; // bdata
  60. uchar SR0L; // bdata
  61. uchar SR1;  // bdata
  62. uchar SR2;

  63. sbit ISD1760_SS  = P1^3;
  64. sbit ISD1760_SCLK= P1^2;
  65. sbit ISD1760_MOSI= P1^1;
  66. sbit ISD1760_MISO= P1^0;
  67. sbit led =P3^7;
  68. sbit s1=P3^0;
  69. sbit s2=P3^1;
  70. sbit s3=P2^6;
  71. sbit s4=P2^7;


  72. volatile uchar ISD1760_Spio(volatile uchar dat) ;
  73. void ISD1760_Write_APC2(void) ;

  74. void ISD1760_delay(uint Count)
  75. {
  76.         uint x,y;
  77.         for(x=Count;x>0;x--)
  78.         for(y=420;y>0;y--);
  79. }

  80. //功能:ISD1730 SPI驱动函数  
  81. //输入:dat:要传送到ISD1730的数据
  82. //返回:receive:接收的数据
  83. static uchar ISD1760_Spio(uchar dat)
  84. {      
  85.          uchar     i;   
  86. //        uchar    recevice;
  87.         ISD1760_SCLK_L; //SCLK==0
  88.         ENISD1760_SS ;//为低选择当前设备,并开启SPI      
  89.         for (i=0; i<8; i++)                       
  90.         //将dat字节的8个位数据一一送到MOSI线上     
  91.         {         
  92.                 ISD1760_SCLK_L;                       
  93.                 //先将SCLK拉低         
  94.         //        if(dat&0x01==0x01)   
  95.                 if(dat&0x01)//先发低位      
  96.                 {            
  97.                         ISD1760_MOSI_H; //输入到1760 上升沿输入        
  98.                 }         
  99.                 else         
  100.                 {            
  101.                         ISD1760_MOSI_L;                    
  102.         //MOSI和MISO信号同时改变数据,但有前后关系如:左程序         
  103.                 }         
  104.                 dat>>=1;  
  105.         //        ISD1760_delay(1);  
  106.         //        ISD1760_SCLK_H;  
  107.         //        ISD1760_delay(1);
  108.         //         recevice>>=1;  
  109.                 if(ISD1760_MISO == 1)
  110.                 {
  111.                     dat|=0x80;         
  112.                 }
  113.              ISD1760_SCLK_H;      
  114.         //        ISD1760_SCLK_L;                       
  115.         //SCLK来一个上升沿锁存MOSI信号     
  116.         }      
  117.         ISD1760_MOSI_L;                           
  118.         //非忙线时MOSI要拉低            
  119.         return(dat);
  120. }
  121. //功能:ISD1730上电操作
  122. static void ISD1760_PU(void)
  123. {
  124.         DISENISD1760_SS;
  125.         ISD1760_delay(1);
  126.         ISD1760_SCLK_H;
  127.         ISD1760_delay(1);
  128.         ISD1760_MOSI_L;
  129.         ISD1760_delay(1);
  130.         ENISD1760_SS;  
  131.         ISD1760_delay(1);  
  132.         SR0L = ISD1760_Spio(PU);   //发送命令字节
  133.         SR0H = ISD1760_Spio(0x00); //发送数据字节1
  134.         DISENISD1760_SS;
  135.         ISD1760_delay(10);
  136. }
  137. //功能:写入APC参数
  138. void ISD1760_Write_APC2(void)
  139. {      
  140.         DISENISD1760_SS;
  141.         ISD1760_delay(1);
  142.         ISD1760_SCLK_H;
  143.         ISD1760_delay(1);
  144.         ISD1760_MOSI_L;
  145.         ISD1760_delay(1);
  146.         ENISD1760_SS;  
  147.         ISD1760_delay(1);                    
  148.         //SPI总线准备好   
  149.         SR0L = ISD1760_Spio(WR_APC2); //发送命令字节   
  150.         SR0H = ISD1760_Spio(0x40);    //发送数据字节1   
  151. //        SR0H = ISD1760_Spio(0x70);    //发送数据字节1
  152.         SR1  = ISD1760_Spio(0x0C);
  153.    
  154.         DISENISD1760_SS;              //一个命令完毕
  155.         ISD1760_delay(10);
  156. }

  157. //功    能: 取出当前语音的首末地址
  158. void GetToneAdd(uchar NUM, uint *ipStartAdd, uint *ipEndAdd)
  159. {     
  160.         uint caToneAdd[]={

  161.                         0x0010,0x0020, 0x0021, 0x0031,0x0032,0x0042,
  162.                         0x0043,0x0058  
  163. //0x0010,0x00ff//
  164.                         };         
  165.         *ipStartAdd=caToneAdd[NUM*2];         
  166.         *ipEndAdd=caToneAdd[NUM*2+1];  
  167. }
  168. //定点地址播放
  169. void ISD1760_Set_Play(uchar VOICE_NUM)
  170. {
  171.         uint Add_ST, Add_ED; //ST起始地址,ED结束地址      
  172.         uchar Add_ST_H, Add_ST_L, Add_ED_H, Add_ED_L;
  173. //起始地址高8位,起始地址低8位,结束地址高8位,结束地址低8位      
  174.         GetToneAdd( VOICE_NUM, &Add_ST, &Add_ED);      
  175.         Add_ST_L=(uchar)(Add_ST&0x00ff);           
  176.         Add_ST_H=(uchar)((Add_ST>>8)&0x00ff);         
  177.         Add_ED_L=(uchar)(Add_ED&0x00ff);         
  178.         Add_ED_H=(uchar)((Add_ED>>8)&0x00ff);
  179.         DISENISD1760_SS;
  180.         ISD1760_delay(1);
  181.         ISD1760_SCLK_H;
  182.         ISD1760_delay(1);
  183.         ISD1760_MOSI_L;
  184.         ISD1760_delay(1);
  185.         ENISD1760_SS;
  186.         ISD1760_delay(1);
  187.         //发送命令  
  188.         SR0L = ISD1760_Spio(SET_PLAY);         
  189.         //发送命令字节  
  190.         SR0H = ISD1760_Spio(0x00);                  
  191.         //发送数据字节1
  192.         SR1 = ISD1760_Spio(Add_ST_L);
  193.         //发送数据字节2,放音起始地址低8位<S7:S0>  
  194.         SR2 = ISD1760_Spio(Add_ST_H);        
  195.         //发送数据字节3,放音起邕地址高3位<S10:S8>,ISD1730不用
  196.         SR0H = ISD1760_Spio(Add_ED_L);        
  197.         //发送数据字节4,放音结束地址低8位<E7:E0>
  198.         SR0H = ISD1760_Spio(Add_ED_H);        
  199.         //发送数据字节5,放音结束地址低8位<E10:E8>,ISD1730不用  
  200.         SR0H = ISD1760_Spio(0x00);        
  201.         //发送数据字节6 DISENISD1730_SS;  //
  202.         ISD1760_delay(10);
  203. }
  204. //功能:ISD1730下电命令
  205. void ISD1760_PD(void)
  206. {
  207.         DISENISD1760_SS;
  208.         ISD1760_delay(1);
  209.         ISD1760_SCLK_H;
  210.         ISD1760_delay(1);  
  211.         ISD1760_MOSI_L;
  212.         ISD1760_delay(1);
  213.         ENISD1760_SS;
  214.         ISD1760_delay(1);
  215.         SR0L = ISD1760_Spio(PD);        
  216.         //发送命令字节
  217.         SR0H = ISD1760_Spio(0x00);     
  218.         //发送数据字节1
  219.         DISENISD1760_SS;
  220.         ISD1760_delay(10);
  221. }
  222. //功能:播放指定的语音信息
  223. //输入:voice_num,语音索引编号(第几段:0 第一段,1第二段。。。)
  224. void ISD1760_PLAY(uchar voice_name)
  225. {      
  226.         ISD1760_PU();    // delay10ms(5);
  227.         ISD1760_delay(5);   
  228.         ISD1760_Set_Play(voice_name);    // delay10ms(350);
  229.         ISD1760_delay(50);      
  230.         ISD1760_PD(); // delay10ms(15);
  231.         ISD1760_delay(5);      
  232. }
  233. //功能: 停止
  234. void ISD_Stop(void)  
  235. {   
  236.         ENISD1760_SS;   
  237.         ISD1760_Spio(STOP); //停止当前操作   
  238.         ISD1760_Spio(0x00);   
  239.         DISENISD1760_SS;   
  240.         ISD1760_delay(50);  
  241. }
  242. //功能: 掉电
  243. void ISD_PD(void)  
  244. {   
  245.         ENISD1760_SS;   
  246.         ISD1760_Spio(PD); //Power down 掉电   
  247.         ISD1760_Spio(0x00);   
  248.         DISENISD1760_SS;  
  249.         ISD1760_delay(50);  
  250. }
  251. void keyscan()
  252. {
  253.         if(s1==0)
  254.         {
  255.                 ISD1760_delay(10);
  256.                 if(s1==0)
  257.                 {
  258.                         ISD1760_PLAY(0) ; //欢迎光临
  259.                        
  260.                         ISD_PD();
  261.                         ISD_Stop();
  262.                         led =~led;ISD1760_delay(3000);
  263.                 }
  264.         }
  265.         if(s2==0)
  266.         {
  267.                 ISD1760_delay(10);
  268.                 if(s2==0)
  269.                 {
  270.                         ISD1760_PLAY(1) ;//你好请避让
  271.                        
  272.                         ISD_PD();
  273.                         ISD_Stop();
  274.                         led =~led;ISD1760_delay(3000);
  275.                 }
  276.         }
  277.         if(s3==0)
  278.         {
  279.                 ISD1760_delay(10);
  280.                 if(s3==0)
  281.                 {
  282.                         ISD1760_PLAY(2) ; //你好这是你点的菜谢谢
  283.                        
  284.                         ISD_PD();
  285.                         ISD_Stop();
  286.                         led =~led;ISD1760_delay(3000);
  287.                 }
  288.         }
  289.         if(s4==0)
  290.         {
  291.                 ISD1760_delay(10);
  292.                 if(s4==0)
  293.                 {
  294.                         ISD1760_PLAY(3) ; //欢迎再次光临再见
  295.                        
  296.                         ISD_PD();
  297.                         ISD_Stop();
  298.                         led =~led;ISD1760_delay(3000);
  299.                 }
  300.         }
  301. }
  302. void main(void)  
  303. {      
  304. //        ISD1760_Write_APC2();   //设置芯片模拟输入方式:模拟寄存器APC2
  305.         while(1)
  306.         {       
  307.                 ISD1760_Write_APC2();
  308.                 keyscan();
  309.         }
  310. }
复制代码


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

新品特惠推荐上一条 /2 下一条

QQ|QQ技术咨询1|QQ技术咨询2|商务合作微信1:xiaorgeek001|商务合作微信2:XiaoRGEEK|诚聘英才|Archiver|手机版|小R科技-WIFI机器人网·机器人创意工作室 ( 粤ICP备15000788号-6 )

GMT+8, 2024-4-25 23:05 , Processed in 1.086031 second(s), 22 queries .

Powered by XiaoR GEEK X3.4

© 2014-2021 XiaoR GEEK

快速回复 返回顶部 返回列表