STC12C5A60S2单片机的总结

2024-06-26 1326阅读

STC12C5A60S2单片机的总结

文章目录

      • STC12C5A60S2单片机的总结
        • 引言:
        • 1.独立串口
          • 1.1 相关寄存器
          • 1.2 实验程序
          • 2.内置看门狗
            • 2.1 看门狗寄存器
            • 2.2 实验程序:
            • 3. EEPROM
              • 3.1 相关的寄存器
              • 3.2 实验程序
              • 4.内置ADC
                • 4.1 相关的寄存器
                • 4.2 实验程序
                • 5. PCA定时器做软件定时的功能
                  • 5.1 相关的寄存器
                  • 5.2 实验程序
                  • 6. PCA定时器做PWM输出的功能(一路输出)
                    • 6.1 相关寄存器
                    • 6.2 实验程序
                    • 7. PCA定时器做PWM输出的功能(两路输出)
                    • 8. PCA定时器用于扩展外部中断
                    • 9. PCA定时器用于输入捕获
                    • 10. PCA定时器用于生成高速脉冲
                      引言:

                      STC12C5A60S2系列主要性能:

                      STC12C5A60S2单片机的总结

                      • 高速: 1个时钟/机器周期,增型8051内核,速度比普通8051快6~12倍
                      • 宽电压: 5.5~4.0V, 2.1~3.6V( STC12LE5A60S2系列)
                      • 增加第二复位功能脚/P4.6(高可靠复位, 可调整复位门槛电压,频率 SCON=0X50; BRT=0Xfd; //一定要11.0592M晶振,BRT的值即为用定时器做波特率发生器方式的定时器匹配值; 9600波特率 AUXR=0x11; ES=1; EA=1; } void UART_SendData(uchar dat) { SBUF=dat; while(TI==0); TI=0; } void main() { ck_init(); while(1) { if(flag==1) { ES=0; //关串口中断 flag=0; SBUF=a; UART_SendData(a+0x30); ES=1; } } } void serial() interrupt 4 { flag=1; if(SBUF==0x01) { led1=0; } else led1=1; a=SBUF; RI=0; } uint x,y; for(x=t;x0;x--) for(y=920;y>0;y--); } void main() { WDT_CONTR=wdt_reset_counts; p20=0; delayms(500); p20=1; while(1) { delayms(5000); // 延时超过看门狗超时时间单片机会复位,p2.0口led不停闪烁 WDT_CONTR=wdt_reset_counts; } }
                        3. EEPROM

                        STC12C5A60S2系列单片机内部集成了的EEPROM是与程序空间是分开的,利用ISP/IAP技术可将内部Data Flash当EEPROM,擦写次数在10万次以上。EEPROM可分为若干个扇区,每个扇区包含512字节。使用时,建议同一次修改的数据放在同一个扇区,不是同一次修改的数据放在不同的扇区,不一定要用满。数据存储器的擦除操作是按扇区进行的。

                        3.1 相关的寄存器

                        STC12C5A60S2单片机的总结

                        底层寄存器的操作可以自行看单片机的官方手册,对于使用12单片机的EEPROM,只需要会调用EEPROM模块的API即可。

                        STC12C5A60S2单片机的EEPROM资源(每个扇区512字节):

                        STC12C5A60S2单片机的总结

                        3.2 实验程序
                        #include"stc12c5a60s2.h"
                        typedef unsigned int uint;
                        typedef unsigned char uchar;
                        #include"lcd.h"
                        #define	EEP_address	0x0000
                        uchar code ASCII[] = {'0','1','2','3','4','5','6','7','8','9'};
                        uchar a,ge,shi;
                        uchar	TestCnt;
                        uchar zf[]="num:";
                        uchar shu;
                        void	EEPROM_read_n(uint EE_address,uchar *DataAddress,uchar lenth);
                        void 	EEPROM_SectorErase(uint EE_address);
                        void 	EEPROM_write_n(uint EE_address,uchar *DataAddress,uchar lenth);
                        void delayms(uint t)
                        {
                        	uint x,y;
                        	for(x=t;x>0;x--)
                        	for(y=920;y>0;y--);
                        }
                        void main()
                        {
                        	LcdInit();
                        	delayms(5);
                        	EEPROM_read_n(EEP_address,&TestCnt,1);	//读出保存值   读N个字节函数 最多255字节一次
                        	TestCnt++;
                        	if(TestCnt>100) TestCnt=0;  // 如果开机次数大于100,清零
                        	
                        	
                        	EEPROM_SectorErase(EEP_address);  //扇区擦除函数,写入之前必须清楚扇区
                        	EEPROM_write_n(EEP_address,&TestCnt,1);	//写1个字节函数 最多255字节一次。把开机次数写入EEPROM中
                        	shi=TestCnt/10;ge=TestCnt%10;
                        	// 显示开机次数
                        	LcdWriteCom(0x80);
                        	for(shu=0;shu
                        		LcdWriteData(zf[shu]);	
                        	}
                        	while(1)
                        	{
                        		LcdWriteCom(0x05+0x80);LcdWriteData(ASCII[shi]);
                        		LcdWriteCom(0x06+0x80);LcdWriteData(ASCII[ge]);	
                        	}
                        }
                        
                        	uint	j;
                        	PrintString("****** STC12C5A60S2系列ADC程序 2011-02-27 ******\r\n");	//上电后串口发送一条提示信息
                        	P1ASF = (1 
                        		delay_ms(250);
                        		delay_ms(250);
                        		delay_ms(250);
                        		delay_ms(250);
                        		
                        		j = adc10_start(0);		// P1.0 ADC
                        		Tx1Send('A');
                        		Tx1Send('D');
                        		Tx1Send('0');
                        		Tx1Send('=');
                        		Tx1Send(j/1000 + '0');
                        		Tx1Send(j%1000/100 + '0');
                        		Tx1Send(j%100/10 + '0');
                        		Tx1Send(j%10 + '0');
                        		Tx1Send(0x0d);
                        		Tx1Send(0x0a);
                        		
                        	}
                        }
                        /********************* 做一次ADC转换 *******************/
                        uint	adc10_start(uchar channel)	//channel = 0~7
                        {
                        	uint	adc;
                        	uchar	i;
                        	ADC_RES = 0;
                        	ADC_RESL = 0;
                        	ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | channel; 
                        //	for(i=0; i
                        		if(ADC_CONTR & ADC_FLAG)
                        		{
                        			ADC_CONTR &= ~ADC_FLAG;
                        		//	adc = 0;
                        		//	adc = (ADC_RES 
                             unsigned int i;
                        	 do{
                        	      i = MAIN_Fosc / 14000;
                        		  while(--i)	;   //14T per loop
                             }while(--ms);
                        }
                        /********************** 模拟串口相关函数************************/
                        void	BitTime(void)	//位时间函数
                        {
                        	uint i;
                        	i = ((MAIN_Fosc / 100) * 104) / 140000L - 1;		//根据主时钟来计算位时间
                        	while(--i);
                        }
                        //模拟串口发送
                        void	Tx1Send(uchar dat)		//9600,N,8,1		发送一个字节
                        {
                        	uchar	i;
                        	EA = 0;
                        	P_TXD1 = 0;
                        	BitTime();
                        	for(i=0; i
                        		if(dat & 1)		P_TXD1 = 1;
                        		else			P_TXD1 = 0;
                        		dat = 1;
                        		BitTime();
                        	}
                        	P_TXD1 = 1;
                        	EA = 1;
                        	BitTime();
                        	BitTime();
                        }
                        void PrintString(unsigned char code *puts)		//发送一串字符串
                        {
                            for (; *puts != 0;	puts++)  Tx1Send(*puts); 	//遇到停止符0结束
                        }
                        
                        	uint	j;
                        	PrintString("****** STC12C5A60S2系列ADC程序 2011-02-27 ******\r\n");	//上电后串口发送一条提示信息
                        	P1ASF = (1 
                        		delay_ms(250);
                        		delay_ms(250);
                        		delay_ms(250);
                        		delay_ms(250);
                        		
                        		ADC_RES  = 0;
                        		ADC_RESL = 0;
                        		B_ADC_OK = 0;
                        		ADC_CONTR = (ADC_CONTR & 0xe0) | ADC_START | ADC_CH0; 
                        		while(!B_ADC_OK);	//等待ADC完成
                        		j = adc;
                        		Tx1Send('A');
                        		Tx1Send('D');
                        		Tx1Send('0');
                        		Tx1Send('=');
                        		Tx1Send(j/1000 + '0');
                        		Tx1Send(j%1000/100 + '0');
                        		Tx1Send(j%100/10 + '0');
                        		Tx1Send(j%10 + '0');
                        		Tx1Send(0x0d);
                        		Tx1Send(0x0a);
                        		
                        	}
                        }
                        /********************* ADC转换中断 *******************/
                        void	adc_interrupt(void)	interrupt 5		//channel = 0~7
                        {
                        	ADC_CONTR &= ~ADC_FLAG;		//clear ADC flag
                        	adc = (uint)ADC_RES;
                        	adc = (adc 
                             unsigned int i;
                        	 do{
                        	      i = MAIN_Fosc / 14000;
                        		  while(--i)	;   //14T per loop
                             }while(--ms);
                        }
                        /********************** 模拟串口相关函数************************/
                        void	BitTime(void)	//位时间函数
                        {
                        	uint i;
                        	i = ((MAIN_Fosc / 100) * 104) / 140000L - 1;		//根据主时钟来计算位时间
                        	while(--i);
                        }
                        //模拟串口发送
                        void	Tx1Send(uchar dat)		//9600,N,8,1		发送一个字节
                        {
                        	uchar	i;
                        	P_TXD1 = 0;
                        	BitTime();
                        	for(i=0; i
                        		if(dat & 1)		P_TXD1 = 1;
                        		else			P_TXD1 = 0;
                        		dat = 1;
                        		BitTime();
                        	}
                        	P_TXD1 = 1;
                        	BitTime();
                        	BitTime();
                        }
                        void PrintString(unsigned char code *puts)		//发送一串字符串
                        {
                            for (; *puts != 0;	puts++)  Tx1Send(*puts); 	//遇到停止符0结束
                        }
                        
                        	CCF0=0;		//中断标志位清0
                        	CCAP0L=value;	  //比较寄存器程序赋值(比上次加1倍)
                        	CCAP0H=value8;
                        	value=value+t100hz;	 //	value一直增加不会溢出??会CL、CH也会溢出。溢出后的数值会丢弃二进制中超过最高位的
                        	if(cnt--==0)	   //1s  t100hz=0.01s  0.01*100=1s
                        	{
                        		cnt=100;
                        		p20=~p20;
                        	}
                        }
                        void main()
                        {
                        	CCON=0;		   //cf cr ccf1 ccf0为0
                        	CL=0;		//pca计数值初始为0
                        	CH=0;
                        	CMOD=0X00;	 //CIDL=0、SYSclk/12、ECF = 0
                        	value=t100hz;  //0.01s
                        	CCAP0L=value;	//给比较寄存器赋值
                        	CCAP0H=value8;
                        	value=value+t100hz;	 //value加一倍
                        	CCAPM0=0x49;	  //ecmo0 mat0 eccf0为1;ECOM0= 1时,允许比较器功能;匹配将置位CCON寄存;使能CCF0中
                        	CR=1;  //起动 PCA计数器阵列计数,CCON寄存器的一位
                        	EA=1;
                        	cnt=0;
                        	while(1)
                        	{
                        		
                        	}
                        }
                        
                        	CCON=0;	   //CF(pca计数溢出标志) CR(是否启动pca计数) CCF1、CCF0(pca模块中断标志)  全清0
                        	CL=0;  //pca计数值 只有CL计数 8位
                        	CH=0;  //CH不计数
                        	CMOD=0X02;	  //选择pca/pwm时钟频率(决定了输出pwm波的频率)  是否中断
                        	CCAP0H=CCAP0L=0X80;	 //pwm输出通道0(CCP0)   50%占空比  CL与之比较
                        	CCAPM0=0X42;	 //ecom0 pwm0 置1(使能pwm通道0)
                        	CCAP1H=CCAP1L=0XFF;	 //pwm输出通道0(CCP1)   0占空比	    CL与之比较
                        	PCA_PWM1=0X03;		 //固定输出0
                        	CCAPM1=0X42;	 //ecom1 pwm1 置1(使能pwm通道1)
                        	CR=1;	//启动pca定时器
                        	while(1)
                        	{
                        		
                        	}
                        }
                        
                        	unsigned char i, j;
                        	_nop_();
                        	_nop_();
                        	i = 108;
                        	j = 144;
                        	do
                        	{
                        		while (--j);
                        	} while (--i);
                        }
                        void pwm_kz()
                        {
                        	if(pwm0255) pwm0=0;
                        	if(pwm1255) pwm1=0;
                        }
                        void	main(void)
                        {
                        	uint	i;
                        	//AUXR1 |= (1
                        		for(i=0;i
                        		 	pwm0++;
                        			pwm1++;
                        			pwm_kz();
                        			CCAP0H = pwm0;		//set PWM wide
                        			CCAP1H = pwm1;		//set PWM wide
                        			Delay10ms();
                        		}		
                        	}
                        }
                        
                        	if(CCF0==1)
                        	{
                        		CCF0=0;
                        		p10=~p10;
                        	}
                        }
                        void main()
                        {
                        	CCON=0;	  			//CF(pca计数溢出标志) CR(是否启动pca计数) CCF1、CCF0(pca模块中断标志)  全清0
                        	CL=CH=0;  			//pca计数值
                        	CMOD=0X00; 			//选择pca/pwm时钟频率(决定了输出pwm波的频率)  是否中断
                        	CCAPM0=0X11;	 //下降沿捕获
                        	//CCAPM0=0X21;	 //上升沿捕获
                        	//CCAPM0=0X21;	 //下降、上升都捕获
                        	CR=1;	  //启动pca定时器
                        	EA=1;	  //开启总中断
                        	while(1)
                        	{
                        		
                        	}
                        }
                        
                        	Tx1Send('P');
                        	Tx1Send('C');
                        	Tx1Send('A');
                        	Tx1Send(id + '0');
                        	Tx1Send('=');
                        	Tx1Send(dat/10000 + '0');
                        	Tx1Send(dat%10000/1000 + '0');
                        	Tx1Send(dat%1000/100 + '0');
                        	Tx1Send(dat%100/10 + '0');
                        	Tx1Send(dat%10 + '0');
                        	Tx1Send(0x0d);
                        	Tx1Send(0x0a);
                        }
                        /********************* 主函数 *************************/
                        void main(void)
                        {
                        	CCAPM0 = 0x11;	//CCAP0下降沿捕捉,允许中断		下降沿捕捉: 0x11,  上升沿捕捉: 0x21, 上升下降沿捕捉: 0x31
                        	CCAPM1 = 0x11;	//CCAP1下降沿捕捉,允许中断		下降沿捕捉: 0x11,  上升沿捕捉: 0x21, 上升下降沿捕捉: 0x31
                        	CMOD = (PCA_IDLE_DISABLE 
                        		if(B_Cap0)
                        		{
                        			B_Cap0 = 0;
                        			tx(0, CCAP0_tmp - CCAP0_Last);
                        			CCAP0_Last = CCAP0_tmp;	  //为什么要减去上次值,CL和CH没有清零
                        		}
                        		if(B_Cap1)
                        		{
                        			B_Cap1 = 0;
                        			tx(1, CCAP1_tmp - CCAP1_Last);
                        			CCAP1_Last = CCAP1_tmp;
                        		}
                        	}
                        }
                        //========================================================================
                        // 函数: void PCA_interrupt (void) interrupt 7
                        // 描述: PCA中断服务程序。
                        // 参数: 无。
                        // 返回: 无。
                        // 版本: VER1.0
                        // 日期: 2009-12-30
                        // 备注: 
                        //========================================================================
                        void PCA_interrupt (void) interrupt 7
                        {
                        	if(CCF0 == 1)		//PCA模块0中断
                        	{
                        		CCF0 = 0;		//清PCA模块0中断标志
                        		CCAP0_tmp = CCAP0H;	//读CCAP0H (CH CL值会自动装载到CCAP0H  CCAP0L)
                        		CCAP0_tmp = (CCAP0_tmp 
                        		CCF1 = 0;		//清PCA模块1中断标志
                        		CCAP1_tmp = CCAP1H;	//读CCAP0H
                        		CCAP1_tmp = (CCAP1_tmp 
                        		CF = 0;			//清PCA溢出中断标志
                        		P10 = ~P10;		//14HZ at 22.1184MHZ
                        	}
                        }
                        /********************** 模拟串口相关函数************************/
                        void	BitTime(void)	//位时间函数
                        {
                        	uint i;
                        	i = ((MAIN_Fosc / 100) * 104) / 140000L - 1;		//根据主时钟来计算位时间
                        	while(--i);
                        }
                        //模拟串口发送
                        void	Tx1Send(uchar dat)		//9600,N,8,1		发送一个字节
                        {
                        	uchar	i;
                        	P_TXD1 = 0;
                        	BitTime();
                        	for(i=0; i
                        		if(dat & 1)		P_TXD1 = 1;
                        		else			P_TXD1 = 0;
                        		dat = 1;
                        		BitTime();
                        	}
                        	P_TXD1 = 1;
                        	BitTime();
                        	BitTime();
                        }
                        void PrintString(unsigned char code *puts)		//发送一串字符串
                        {
                            for (; *puts != 0;	puts++)  Tx1Send(*puts); 	//遇到停止符0结束
                        }
                        
                        	PWMn_init();	//初始化PCA
                        	
                        	while(1)
                        	{
                        	
                        	}
                        }
                        //========================================================================
                        // 函数: void	PWMn_init(void)
                        // 描述: 初始化程序。
                        // 参数: 无。
                        // 返回: 无。
                        // 版本: VER1.0
                        // 日期: 2009-12-30
                        // 备注: 
                        //========================================================================
                        void	PWMn_init(void)
                        {
                        	#ifdef	STC12C5201AD
                        		P3M1 &= ~0xA0,	P3M0 |=  0xA0;		//CCAP0、CCAP1使用PUSH-PULL输出模式,STC12C5201AD系列。
                        	#else
                        		P1M1 &= ~0x18,	P1M0 |=  0x18;		//CCAP0、CCAP1使用PUSH-PULL输出模式,STC12C5A60S2系列。
                        	#endif
                        	CCON = 0;					//清除CF、CR、CCF0、CCF1
                        	IPH |= 0x80;				//PCA中断使用最高优先级
                        	PPCA = 1;
                        	CMOD = (PCA_IDLE_DISABLE 
                        	if(CCF0 == 1)		//PCA模块0中断
                        	{
                        		CCF0 = 0;		//清PCA模块0中断标志
                        		CCAP0_tmp +=2765 ;		//1KHZ  at   11.0592M  2765		
                        		CCAP0L = CCAP0_tmp%256;			//将影射寄存器写入捕获寄存器,先写CCAP0L   (自己改的是对的!!!!!)
                        		CCAP0H = CCAP0_tmp/256;	//后写CCAP0H
                        	}
                        	if(CCF1 == 1)	//PCA模块1中断
                        	{
                        		CCF1 = 0;		//清PCA模块1中断标志
                        		CCAP1_tmp +=28;		//2KHZ at 22.1184MHZ 5530			  11.0592M   28	    (这里例程是错的!!,自己计算的28)
                        		CCAP1L = (unsigned char)CCAP1_tmp;			//将影射寄存器写入捕获寄存器,先写CCAP0L
                        		CCAP1H = (unsigned char)(CCAP1_tmp  8);	//后写CCAP0H
                        	}
                        	if(CF == 1)	//PCA溢出中断
                        	{
                        		CF = 0;			//清PCA溢出中断标志
                        		P10 = ~P10;		//168.75HZ at 22.1184MHZ
                        	}
                        }
                        
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]