STM32实现的语音识别的智能垃圾桶

STM32实现的语音识别的智能垃圾桶-LD3320语音识别篇

  • main.h
  • LD3320.h
  • LD3320.c
  • main.c
  • Reg.h
  • Reg.c
  • STC11XX.h
  • usart.h
  • usart.c

main.h

#ifndef _MAIN_H
#define _MAIN_H

typedef signed           char int8_t;
typedef signed short     int  int16_t;
typedef signed           int  int32_t;
typedef signed long 	 int  int64_t;
typedef unsigned         char uint8_t;
typedef unsigned short   int  uint16_t;
typedef unsigned         int  uint32_t;
typedef unsigned long    int  uint64_t;

#define ENABLE  1
#define DISABLE  0

#include <intrins.h>
#include "STC11XX.h"
#include "LD3320.h"
#include "Reg.h"
#include "usart.h"
sbit LED=P4^2;	//信号指示灯

#define TEST		 //测试命令

#endif

LD3320.h

#ifndef LD_CHIP_H
#define LD_CHIP_H

#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long
//ASR识别:Automatic Speech Recognition,自动语音识别
//#define 简单的替换
//以下五个状态定义用来记录程序是在运行ASR识别过程中的哪个状态
#define LD_ASR_NONE			0x00	 /*表示没有在作ASR识别*/
//LD3320 语音识别 没有        
#define LD_ASR_RUNING		0x01	 /*表示LD3320正在作ASR识别中*/
#define LD_ASR_FOUNDOK		0x10	 /*表示一次识别流程结束后,有一个识别结果*/
#define LD_ASR_FOUNDZERO 	0x11	 /*表示一次识别流程结束后,没有识别结果*/
#define LD_ASR_ERROR	 	0x31	 /*表示一次识别流程中LD3320芯片内部出现不正确的状态*/


#define CLK_IN   		    22.1184	 /*用户注意修改输入的晶振时钟大小*/
#define LD_PLL_11			(uint8)((CLK_IN/2.0)-1)
#define LD_PLL_MP3_19		0x0f
#define LD_PLL_MP3_1B		0x18
#define LD_PLL_MP3_1D   	(uint8)(((90.0*((LD_PLL_11)+1))/(CLK_IN))-1)

#define LD_PLL_ASR_19 		(uint8)(CLK_IN*32.0/(LD_PLL_11+1)-0.51)
#define LD_PLL_ASR_1B 		0x48
#define LD_PLL_ASR_1D 		0x1f

//函数声明
void LD_Reset();
void LD_Init_Common();
void LD_Init_ASR();
uint8 RunASR(void);
void LD_AsrStart();
uint8 LD_AsrRun();
uint8 LD_AsrAddFixed();
uint8 LD_GetResult();

//识别码客户修改处 
#define CODE_START  0
#define CODE_CMD1   1      
#define CODE_CMD2	2	
#define CODE_CMD3	3	   
#define CODE_CMD4   4	
#define CODE_CMD5   5	
#define CODE_CMD6   6		
#define CODE_CMD7   7   
#define CODE_CMD8	8	
#define CODE_CMD9	9	   
#define CODE_CMD10  10		
#define CODE_CMD11  11	
#define CODE_CMD12  12
#define CODE_CMD13  13    
#define CODE_CMD14	14	
#define CODE_CMD15	15	   
#define CODE_CMD16  16		
#define	CODE_CMD17  17
#define	CODE_CMD18  18
#define	CODE_CMD19  19
#define	CODE_CMD20  20
#define	CODE_CMD21  21
#define	CODE_CMD22  22
#define	CODE_CMD23  23
#define	CODE_CMD24  24
#define	CODE_CMD25  25
#define	CODE_CMD26  26
#define	CODE_CMD27  27
#define	CODE_CMD28  28
#define	CODE_CMD29  29
#define	CODE_CMD30  30
#define	CODE_CMD31  31
#define	CODE_CMD32  32
#define	CODE_CMD33  33
#define	CODE_CMD34  34
#define	CODE_CMD35  35
#define	CODE_CMD36  36
#define	CODE_CMD37  37
#define	CODE_CMD38  38
#define	CODE_CMD39  39
#define	CODE_CMD40  40

//数值越大越灵敏识别距离越远,但误识别率就越大, 根据自己的实际情况调节。
#define MIC_VOL 0x55	 //咪头增益(灵敏度调节) 范围:00-7f 
#endif

LD3320.c

#include "main.h"

extern unsigned char idata nAsrStatus;
extern void delay(unsigned long uldata);
unsigned char idata ucRegVal;
void ProcessInt0(void);
/************************************************************************
功能描述:复位LD模块
入口参数:none
返 回 值:none
其他说明:none
**************************************************************************/
void LD_Reset()
{
	RSTB=1;
	delay(5);
	RSTB=0;
	delay(5);
	RSTB=1;

	delay(5);
	CSB=0;
	delay(5);
	CSB=1;
	delay(5);
}
/************************************************************************
功能描述: LD模块命令初始化
入口参数: none
返 回 值: none
其他说明: 该函数为出厂配置,一般不需要修改;
**************************************************************************/
void LD_Init_Common()
{
	LD_ReadReg(0x06);  
	LD_WriteReg(0x17, 0x35); 
	delay(10);
	LD_ReadReg(0x06);  

	LD_WriteReg(0x89, 0x03);  
	delay(5);
	LD_WriteReg(0xCF, 0x43);   
	delay(5);
	LD_WriteReg(0xCB, 0x02);
	
	LD_WriteReg(0x11, LD_PLL_11);       
	LD_WriteReg(0x1E,0x00);
	LD_WriteReg(0x19, LD_PLL_ASR_19); 
	LD_WriteReg(0x1B, LD_PLL_ASR_1B);		
	LD_WriteReg(0x1D, LD_PLL_ASR_1D);
	delay(10);
	
    LD_WriteReg(0xCD, 0x04);
//	LD_WriteReg(0x17, 0x4c); 
	delay(5);
	LD_WriteReg(0xB9, 0x00);
	LD_WriteReg(0xCF, 0x4F); 
	LD_WriteReg(0x6F, 0xFF); 
}
/************************************************************************
功能描述:LD模块 ASR功能初始化
入口参数:none
返 回 值:none
其他说明:该函数为出厂配置,一般不需要修改;
**************************************************************************/
void LD_Init_ASR()
{
	LD_Init_Common();
	LD_WriteReg(0xBD,0x00);
	LD_WriteReg(0x17,0x48);
	delay(10);
	LD_WriteReg(0x3C,0x80);    
	LD_WriteReg(0x3E,0x07);
	LD_WriteReg(0x38,0xff);    
	LD_WriteReg(0x3A,0x07);
	LD_WriteReg(0x40,0);          
	LD_WriteReg(0x42,8);
	LD_WriteReg(0x44,0);    
	LD_WriteReg(0x46,8); 
	delay(1);
}
/************************************************************************
功能描述:中断处理函数
入口参数:none
返 回 值:none
其他说明:当LD模块接收到音频信号时,将进入该函数,
		  判断识别是否有结果,如果没有从新配置寄存器准备下一次的识别。
**************************************************************************/
void ProcessInt0(void)
{
	unsigned char nAsrResCount=0;
	EX0=0;
	ucRegVal=LD_ReadReg(0x2B);
	LD_WriteReg(0x29,0);
	LD_WriteReg(0x02,0);
	if((ucRegVal&0x10)&&LD_ReadReg(0xb2)==0x21&&LD_ReadReg(0xbf)==0x35)			/*识别成功*/
	{	
		nAsrResCount=LD_ReadReg(0xba);
		if(nAsrResCount>0&&nAsrResCount<=4) 
		{
			nAsrStatus=LD_ASR_FOUNDOK;
		}
		else
	    {
			nAsrStatus=LD_ASR_FOUNDZERO;
		}	
	}															 /*没有识别结果*/
	else
	{	 
		nAsrStatus=LD_ASR_FOUNDZERO;
	}		
	LD_WriteReg(0x2b,0);
	LD_WriteReg(0x1C,0);	//写0:ADC不可用
	LD_WriteReg(0x29,0);
	LD_WriteReg(0x02,0);
	LD_WriteReg(0x2B,0);
	LD_WriteReg(0xBA,0);	
	LD_WriteReg(0xBC,0);	
	LD_WriteReg(0x08,1);	//清除FIFO_DATA
	LD_WriteReg(0x08,0);	//清除FIFO_DATA后再次写0
	EX0=1;
}
/************************************************************************
功能描述:运行ASR识别流程
入口参数:none
返 回 值:asrflag:1->启动成功, 0—>启动失败
其他说明:识别顺序如下:
						1、RunASR()函数实现了一次完整的ASR语音识别流程
						2、LD_AsrStart()函数实现了ASR初始化
						3、LD_AsrAddFixed()函数实现了添加关键词语到LD3320芯片中
						4、LD_AsrRun()函数启动了一次ASR语音识别流程					
						任何一次ASR识别流程,都需要按照这个顺序,从初始化开始
**************************************************************************/
unsigned char RunASR(void)
{
	unsigned char i=0;
	unsigned char asrflag=0;
	for(i=0;i<5;i++)			//防止由于硬件原因导致LD3320芯片工作不正常,所以一共尝试5次启动ASR识别流程
	{
		LD_AsrStart();
		delay(50);
		if(LD_AsrAddFixed()==0)
		{
			LD_Reset();			//LD3320芯片内部出现不正常,立即重启LD3320芯片
			delay(50);			//并从初始化开始重新ASR识别流程
			continue;
		}
		delay(10);
		if(LD_AsrRun()== 0)
		{
			LD_Reset();			//LD3320芯片内部出现不正常,立即重启LD3320芯片
			delay(50);			//并从初始化开始重新ASR识别流程
			continue;
		}
		asrflag=1;
		break;					//ASR流程启动成功,退出当前for循环。开始等待LD3320送出的中断信号
	}
	return asrflag;
}
/************************************************************************
功能描述:检测LD模块是否空闲
入口参数:none
返 回 值:flag:1-> 空闲
其他说明:none
**************************************************************************/
unsigned char LD_Check_ASRBusyFlag_b2()
{
	unsigned char j;
	unsigned char flag = 0;
	for(j=0;j<10;j++)
	{
		if(LD_ReadReg(0xb2)==0x21)
		{
			flag=1;
			break;
		}
		delay(10);		
	}
	return flag;
}
/************************************************************************
功能描述:启动ASR
入口参数:none
返 回 值:none
其他说明:none
**************************************************************************/
void LD_AsrStart()
{
	LD_Init_ASR();
}
/************************************************************************
功能描述:运行ASR
入口参数:none
返 回 值:1:启动成功
其他说明:none
**************************************************************************/
unsigned char LD_AsrRun()
{
	EX0=0;
	LD_WriteReg(0x35,MIC_VOL);
	LD_WriteReg(0x1C,0x09);
	LD_WriteReg(0xBD,0x20);
	LD_WriteReg(0x08,0x01);
	delay(1);
	LD_WriteReg(0x08, 0x00);
	delay(1);

	if(LD_Check_ASRBusyFlag_b2()==0)
	{
		return 0;
	}
//	LD_WriteReg(0xB6,0xa); 		//识别时间	 1S
//	LD_WriteReg(0xB5,0x1E); 	//背景音段时间 300ms
//	LD_WriteReg(0xB8,10); 		//结束时间
//	LD_WriteReg(0x1C,0x07); 	//配置双通道音频信号做为输入信号
	LD_WriteReg(0x1C,0x0b); 	//配置麦克风做为输入信号
	LD_WriteReg(0xB2,0xff);
	delay(1);	
	LD_WriteReg(0x37,0x06);
	delay(1);
	LD_WriteReg(0x37,0x06);
	delay(5);
	LD_WriteReg(0x29,0x10);	
	LD_WriteReg(0xBD,0x00);
	EX0=1;
	return 1;
}
/************************************************************************
功能描述:向LD模块添加关键词
入口参数:none
返 回 值:flag:1->添加成功
其他说明:用户修改.
1、根据如下格式添加拼音关键词,同时注意修改sRecog 和pCode 数组的长度和对应变了k的循环置。拼音串和识别码是一一对应的。
2、开发者可以学习"语音识别芯片LD3320高阶秘籍.pdf"中关于垃圾词语吸收错误的用法,来提供识别效果。
3、”xiao jie “ 为口令,故在每次识别时,必须先发一级口令“小捷”
**************************************************************************/
unsigned char LD_AsrAddFixed()
{
	unsigned char k, flag;
	unsigned char nAsrAddLength;
	#define DATE_A 41   /*数组二维数值*/
	#define DATE_B 30	/*数组一维数值*/
	unsigned char code sRecog[DATE_A][DATE_B]={
"xiao jie",\
"can jin zhi",\
"shi zhi jin",\
"bao xian mo",\
"su liao dai",\
"yi ci xing can ju",\
"zhen tou",\
"da huo ji",\	
"tao ci zhi pin",\
"fei jiu bi xin",\
"hai mian",\
"shou ji dian chi",\
"deng pao",\
"sha chong ji",\
"xiao du ji",\
"lao shu yao",\
"you qi tong",\
"shui yin wen du ji",\
"guo qi yao pin",\
"fei nong yao",\
"fei deng guan",\	
"shi wu can zha",\	
"guo qi shi pin",\
"gu tou",\
"lan cai ye",\
"sheng fan",\
"guo pi",\
"fan qie jiang",\
"tiao wei liao",\
"hua sheng ke",\
"cha ye zha",\
"zhi he",\
"yin liao ping",\
"bo li ping",\
"su liao tong",\
"pao mo",\
"su liao",\
"jin shu",\
"bao zhi",\
"yi la guan",\
"tie ding"
};	/*添加关键词,用户修改*/
	unsigned char code pCode[DATE_A]={
CODE_START,\
CODE_CMD1,\
CODE_CMD2,\
CODE_CMD3,\
CODE_CMD4,\
CODE_CMD5,\
CODE_CMD6,\
CODE_CMD7,\
CODE_CMD8,\
CODE_CMD9,\
CODE_CMD10,\
CODE_CMD11,\
CODE_CMD12,\
CODE_CMD13,\
CODE_CMD14,\
CODE_CMD15,\
CODE_CMD16,\
CODE_CMD17,\
CODE_CMD18,\
CODE_CMD19,\
CODE_CMD20,\
CODE_CMD21,\
CODE_CMD22,\
CODE_CMD23,\
CODE_CMD24,\
CODE_CMD25,\
CODE_CMD26,\
CODE_CMD27,\
CODE_CMD28,\
CODE_CMD29,\
CODE_CMD30,\
CODE_CMD31,\
CODE_CMD32,\
CODE_CMD33,\
CODE_CMD34,\
CODE_CMD35,\
CODE_CMD36,\
CODE_CMD37,\
CODE_CMD38,\
CODE_CMD39,\
CODE_CMD40
};	/*添加识别码,用户修改*/	
	flag=1;
	for(k=0;k<DATE_A;k++)
	{			
		if(LD_Check_ASRBusyFlag_b2()==0)
		{
			flag=0;
			break;
		}	
		LD_WriteReg(0xc1,pCode[k]);
		LD_WriteReg(0xc3,0);
		LD_WriteReg(0x08,0x04);
		delay(1);
		LD_WriteReg(0x08,0x00);
		delay(1);
		for(nAsrAddLength=0;nAsrAddLength<DATE_B;nAsrAddLength++)
		{
			if(sRecog[k][nAsrAddLength]==0)
				break;
			LD_WriteReg(0x5,sRecog[k][nAsrAddLength]);
		}
		LD_WriteReg(0xb9,nAsrAddLength);
		LD_WriteReg(0xb2,0xff);
		LD_WriteReg(0x37,0x04);
	}
    return flag;
}
/************************************************************************
功能描述:获取识别结果
入口参数:none
返 回 值:LD_ReadReg(0xc5 );读取内部寄存器返回识别码。
其他说明:none
**************************************************************************/
unsigned char LD_GetResult()
{		
	return LD_ReadReg(0xc5);
}

main.c

#include "main.h"
/************************************************************************************/
//	nAsrStatus 用来在main主程序中表示程序运行的状态,不是LD3320芯片内部的状态寄存器
// 下面的五个状态都在LD3320.h中定义
//	LD_ASR_NONE:		表示没有在作ASR识别
//	LD_ASR_RUNING:		表示LD3320正在作ASR识别中
//	LD_ASR_FOUNDOK:		表示一次识别流程结束后,有一个识别结果
//	LD_ASR_FOUNDZERO:	表示一次识别流程结束后,没有识别结果
//	LD_ASR_ERROR:		表示一次识别流程中LD3320芯片内部出现不正确的状态
/***********************************************************************************/
unsigned char idata nAsrStatus=0;	
unsigned char G0_flag=DISABLE;		//运行标志,ENABLE:运行。DISABLE:禁止运行 
void MCU_init(); 					//单片机初始化
void ProcessInt0(); 				//识别处理函数
void delay(unsigned long uldata);	//延时函数
void User_handle(unsigned char dat);//用户执行操作函数
void delay200ms();					//延时200ms
void Led_test(void);				//单片机工作指示

/***********************************************************
* 名    称:void main(void)
* 功    能:主函数程序入口
* 入口参数:  
* 出口参数:
* 说    明: 					 
* 调用方法: 
**********************************************************/ 
void main(void)
{
	unsigned char idata nAsrRes;
	unsigned char i=0;
	Led_test();					//LED灯测试
	MCU_init();					//单片机初始化
	LD_Reset();					//LD3320复位
	UartIni(); 					//串口初始化
	nAsrStatus=LD_ASR_NONE;		//初始状态:没有在作ASR

	while(1)
	{
		switch(nAsrStatus)
		{
			case LD_ASR_RUNING:
			case LD_ASR_ERROR:break;
			case LD_ASR_NONE:
			{
				nAsrStatus=LD_ASR_RUNING;
				if(RunASR()==0)					//启动一次ASR识别流程:ASR初始化,ASR添加关键词语,启动ASR运算
				{
					nAsrStatus = LD_ASR_ERROR;
				}
				break;
			}
			case LD_ASR_FOUNDOK: 				//一次ASR识别流程结束,去取ASR识别结果
			{				
				nAsrRes = LD_GetResult();		//获取结果
				User_handle(nAsrRes);			//用户执行函数
				nAsrStatus = LD_ASR_NONE;
				break;
			}
			case LD_ASR_FOUNDZERO:
			default:
			{
				nAsrStatus = LD_ASR_NONE;
				break;
			}
		}			
	}
}
/***********************************************************
* 名    称:LED灯测试
* 功    能:单片机是否工作指示
* 入口参数:无 
* 出口参数:无
* 说    明: 					 
**********************************************************/
void Led_test(void)
{
	LED=~ LED;
	delay200ms();
	LED=~ LED;
	delay200ms();
	LED=~ LED;
	delay200ms();
	LED=~ LED;
	delay200ms();
	LED=~ LED;
	delay200ms();
	LED=~ LED;
}
/***********************************************************
* 名    称: void MCU_init()
* 功    能: 单片机初始化
* 入口参数:  
* 出口参数:
* 说    明: 					 
* 调用方法: 
**********************************************************/ 
void MCU_init()
{
	P0=0xff;
	P1=0xff;
	P2=0xff;
	P3=0xff;
	P4=0xff;

	P1M0=0xff;	//P1端口设置为推挽输出功能,即提高IO口驱动能力,从驱动继电器模块工作
	P1M1=0x00;

	LD_MODE=0;	//设置MD管脚为低,并行模式读写
	IE0=1;
	EX0=1;
	EA=1;
}
void delay200us(void)
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=97;a>0;a--);
}
void delay(unsigned long uldata)
{
	unsigned int j=0;
	unsigned int g=0;
	while(uldata--)
	delay200us();
}
void delay200ms(void)
{
    unsigned char a,b,c;
    for(c=4;c>0;c--)
        for(b=116;b>0;b--)
            for(a=214;a>0;a--);
    _nop_();
}
void ExtInt0Handler(void) interrupt 0  
{ 	
	ProcessInt0();				
}
/***********************************************************
* 名    称:用户执行函数 
* 功    能:识别成功后,执行动作可在此进行修改 
* 入口参数:无 
* 出口参数:无
* 说    明: 					 
**********************************************************/
void User_handle(uint8 dat)
{
	UARTSendByte(dat);//串口识别码(十六进制)
	if(0==dat)
	{
	 	G0_flag=ENABLE;
		LED=0;
	}
	else if(ENABLE==G0_flag)
	{	
	 	G0_flag=DISABLE;
		LED=1;
	}	
	else 	
	{
	}
}

Reg.h

#ifndef REG_RW_H
#define REG_RW_H

//驱动端口定义
sbit LD_MODE=P4^3; 	/*读写模式选择*/
sbit RSTB=P3^5;	 	/*复位端口*/
sbit CSB=P2^1;	 	/*模块片选端口*/

void LD_WriteReg(unsigned char address, unsigned char dataout);
unsigned char LD_ReadReg(unsigned char address);

#endif

Reg.c

#include "main.h"
#define LD_INDEX_PORT		(*((volatile unsigned char xdata*)(0x8100))) 
#define LD_DATA_PORT		(*((volatile unsigned char xdata*)(0x8000))) 
//0x8100的二进制是 10000001 00000000		CSB=0 AD=1
//                 ^     ^
//0x8000的二进制是 10000000 00000000		CSB=0 AD=0
//                 ^     ^		
void LD_WriteReg( unsigned char address,unsigned char dataout )
{
	LD_INDEX_PORT=address;         
	LD_DATA_PORT=dataout;          
}
unsigned char LD_ReadReg(unsigned char address )
{
	LD_INDEX_PORT=address;         
	return (unsigned char)LD_DATA_PORT;     
}

STC11XX.h

sfr ACC  = 0xE0;                                                          
sfr B    = 0xF0;
sfr PSW  = 0xD0; 
sbit CY  = PSW^7;
sbit AC  = PSW^6;
sbit F0  = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV  = PSW^2;
sbit P   = PSW^0;
sfr SP   = 0x81;                                   
sfr DPL  = 0x82;                                        
sfr DPH  = 0x83;                                  
sfr PCON   = 0x87;
sfr AUXR  = 0x8E;
sfr AUXR1 = 0xA2;
sfr WAKE_CLKO = 0x8F;
sfr CLK_DIV = 0x97;
sfr BUS_SPEED = 0xA1; 
sfr IE      = 0xA8; 
sbit EA       = IE^7;
sbit ELVD     = IE^6; 
sbit EADC     = IE^5;
sbit ES       = IE^4;
sbit ET1      = IE^3;
sbit EX1      = IE^2;
sbit ET0      = IE^1;
sbit EX0      = IE^0;
sfr IE2       = 0xAF;
sfr IP      = 0xB8;
sbit PPCA     = IP^7;
sbit PLVD     = IP^6; 
sbit PADC     = IP^5;
sbit PS       = IP^4;
sbit PT1      = IP^3;
sbit PX1      = IP^2;
sbit PT0      = IP^1;
sbit PX0      = IP^0;                               
sfr IPH   = 0xB7; 
sfr IP2   = 0xB5; 
sfr IPH2  = 0xB6; 
sfr P0   = 0x80; 
sfr P0M0 = 0x94;                   
sfr P0M1 = 0x93;                                                                 
sfr P1   = 0x90;
sfr P1M0 = 0x92; 
sfr P1M1 = 0x91; 
sfr P1ASF = 0x9D;
sfr P2   = 0xA0; 
sfr P2M0 = 0x96;                                                                    
sfr P2M1 = 0x95;                                                                  
sfr P3   = 0xB0; 
sfr P3M0 = 0xB2;                                                                        
sfr P3M1 = 0xB1;                                                                       
sfr P4   = 0xC0; 
sfr P4M0 = 0xB4;                                                                       
sfr P4M1 = 0xB3;                                                                     
sfr P4SW = 0xBB;
sfr P5   = 0xC8;
sfr P5M0 = 0xCA;
sfr P5M1 = 0xC9;
sfr TCON = 0x88;
sbit TF1 = TCON^7;
sbit TR1 = TCON^6;
sbit TF0 = TCON^5;
sbit TR0 = TCON^4;
sbit IE1 = TCON^3;
sbit IT1 = TCON^2;
sbit IE0 = TCON^1;
sbit IT0 = TCON^0;
sfr TMOD = 0x89;
sfr TL0  = 0x8A; 
sfr TH0  = 0x8C;
sfr TL1  = 0x8B;
sfr TH1  = 0x8D; 
sfr SCON = 0x98;
sbit SM0 = SCON^7;
sbit SM1 = SCON^6;
sbit SM2 = SCON^5;
sbit REN = SCON^4;
sbit TB8 = SCON^3;
sbit RB8 = SCON^2;
sbit TI  = SCON^1;
sbit RI  = SCON^0;
sfr SBUF = 0x99;                                               
sfr SADEN = 0xB9;                                                
sfr SADDR = 0xA9;                                                                             
sfr S2CON = 0x9A;
sfr S2BUF = 0x9B;
sfr BRT = 0x9C;
sfr WDT_CONTR = 0xC1; 
sfr CCON   = 0xD8;
sbit CF     = CCON^7; 
sbit CR     = CCON^6;
sbit CCF1   = CCON^1;
sbit CCF0   = CCON^0; 
sfr CMOD  = 0xD9;
sfr CL     = 0xE9;
sfr CH     = 0xF9; 
sfr CCAPM0 = 0xDA;
sfr CCAPM1 = 0xDB; 
sfr CCAP0L = 0xEA;
sfr CCAP0H = 0xFA;
sfr CCAP1L = 0xEB; 
sfr CCAP1H = 0xFB;
sfr PCA_PWM0 = 0xF2;
sfr PCA_PWM1 = 0xF3;
sfr ADC_CONTR = 0xBC;
sfr ADC_RES  = 0xBD;  
sfr ADC_RESL = 0xBE;  
sfr SPCTL  = 0xCE; 
sfr SPSTAT = 0xCD; 
sfr SPDAT  = 0xCF; 
sfr IAP_DATA    = 0xC2;
sfr IAP_ADDRH   = 0xC3;
sfr IAP_ADDRL   = 0xC4;
sfr IAP_CMD     = 0xC5; 
sfr IAP_TRIG    = 0xC6;
sfr IAP_CONTR   = 0xC7;


usart.h

#ifndef __USART_H
#define __USART_H

void UartIni(void);//串口初始化
void UARTSendByte(uint8_t DAT);	//串口发送一字节数据
void PrintCom(uint8_t *DAT); //打印串口字符串数据

#endif

usart.c

//每次识别都需要说“小杰”这个口令,才能进行下一步识别
#include "main.h"
#define FOSC 22118400L      //系统时钟
uint32_t baud=9600;         //串口波特率
//FOSC = 晶振	BAUD = 波特率
/************************************************************************
函数描述:串口初始化
功能描述:STC10L08XE单片机串口初始化,
返回函数:none
其他说明:none
**************************************************************************/
void UartIni(void)
{
    SCON=0x50;            			
    //SCON 是串行口控制寄存器,设置成串口1的工作方式,
    //允许中断接收8位可变波特率,无奇偶校验位	
	//0x50换成二进制就是0101 0000
	//对应到scon寄存器结构表
	//SCON SM0 SM1 SM2 REN TB8 RB8 TI RI
	//写到这里应该就差不多了,接着写下面的程序;

    TMOD=0x20;            			
    //Set Timer1 as 8-bit auto reload mode
    //TMOD是定时/计数器方式控制寄存器
    //所以TMOD=0x20是将定时计数器1设置为工作方式2
    TH1=TL1=-(FOSC/12/32/baud); 	
    //Set auto-reload vaule
    TR1=1;                			
    //Timer1 start run
    //启动定时器1,开始计时
    ES=1;                 			
    //Enable UART interrupt
    EA=1;                 			
    //Open master interrupt switch
}
/***********************************************************
*名称:
* 功能描述
* 入口参数:无
* 出口参数:无
* 说明:
**********************************************************/
void Uart_Isr() interrupt 4 using 1
{	
	if(RI)
	{	  
	}
}
/************************************************************************
功能描述:串口发送一字节的数据
入口参数:DAT:待发送的数据
返回值:none
其他说明:none
**************************************************************************/
void UARTSendByte(uint8_t DAT)
{
	ES=0;
	TI=0;
	SBUF=DAT;
	while(TI==0);
	TI=0;
	ES=1;
}

你可能感兴趣的:(嵌入式,单片机)