STC15W408AS PCA模块实现脉宽捕获

## STC15W408AS PCA计数器实现脉宽捕获
**写在前头:1、主函数只完成PCA模块捕获功能,串口通信功能请复制下面函数块;2、主函数中包含的reg52.h文件较keil51自带有所增加,请注意区别和替换**
/*

//MCU:STC15W408AS
//功能:用PCA模块实现PWM脉宽测量(修改后亦可测量脉冲周期)
//Date:2021/06/22

*/

#include "reg52.h"
#include "intrins.h"
#include "usart.h"

#define FOSC	22118400L	 //主频:22.1184MHz
#define CCP_S0	0x10
#define CCP_S1	0x20

#define PLUSE_T		(FOSC/12/1000)	//12T模式
// time_p =(uint)(temp*1000.0/PLUSE_T);	//将计数器中值转换为十进制时间数值,单位为us
uint temp=0;  	//存储信号长度
uint time_p = 0;
sbit P11 = P1^1;

//PCA脉宽捕获初始化
void PCA_Init()
{
	ACC = P_SW1;
	ACC	&= ~(CCP_S0|CCP_S1);
	P_SW1 = ACC;	//PCA捕获端口IO映射,第一组IO

	CCON = 0x00;	//初始化PCA控制器


	CL = 0;
	CH = 0;
					
	CCAP0L = 0;		//此脉宽捕获功能中未用到
	CCAP0H = 0;		//此脉宽捕获功能中未用到
	CMOD = 0x00;	//设置PCA时钟源为系统时钟 SYSCLK/12(12分频),且禁止PCA计数溢出中断

//	CCAPM0 = 0x21;	//PCA模块0为16位捕获模式(上升沿捕获,且产生捕获中断)
					

//	CCAPM0 = 0x11;	//PCA模块0为16位捕获模式(下降沿捕获,且产生捕获中断)
	CCAPM0 = 0x31;	//PCA模块0为16位捕获模式(上升沿/下降沿 捕获,且产生捕获中断)
	
	CR = 0;			//禁止PCA定时器工作
	EA = 1;
}

void PCA_isr()	interrupt 7 using 1	 		//PCA脉冲捕获中断响应处理函数
{
	if(CCF0)	//PCA模块0中断标志位 ,当出现匹配或捕获时,该位由硬件置位,必须软件清0
	{
		CCF0 = 0; 	//清楚中断标志位
		if (P11 == 1)		//CCP0模块引脚P1.1捕获,若为上升沿捕获
		{
			CL = 0;	   		//PCA定时器低字节,直接清零 PCA计数器值(若PCA计数器还需用到定时功能,
							//请通过CCAPxL转存该值)
			CH = 0;			//PCA定时器高字节,直接清零 PCA计数器值(若PCA计数器还需用到定时功能,
							//请通过CCAPxH转存该值)
			temp = 0;	    //计数值暂存变量(16位长度)
			CR = 1;	        //启动PCA定时器计数
		}
		
		else  		        //若为下降沿捕获
		{
			CR = 0;			//关闭PCA定时器
			temp = CL;		//暂存低8位
			temp |= CH<<8;	//暂存高8位
			CL = 0;	   		//PCA定时器低字节,直接清0 PCA计数器值(若PCA计数器还需用到定时功能,
							//请通过CCAPxL转存该值)
			CH = 0;			//PCA定时器高字节,直接清0 PCA计数器值(若PCA计数器还需用到定时功能,
							//请通过CCAPxH转存该值)
		}
	
	}

}


void main()
{
	Uart_Init(115200); 	//串口初始化
	PCA_Init();		 	//PCA模块捕获功能初始化

	 while(1)
	 {
	 	time_p =(uint)(temp*1000.0/PLUSE_T);	//将计数器中值转换为十进制时间数值,单位为us
	 	SendData(0xFF);	//数据引导标志
		SendData((time_p>>8)&0xff);	 //高8位在前
		SendData(time_p&0xff);		 //低8位在后
	 
	 }

}

//一下为USART1功能函数块 usart.c(请另建文档保存,且被主函数包括含)
#include "usart.h"

//sfr AUXR	= 0x8e;		//辅助寄存器
sfr	T2H 	= 0xd6;	    //
sfr T2L		= 0xd7;

bit busy;
uint Rdata;	 	//receiver buf

void Uart_Init(unsigned long BAUD)	//8位MCU传递大于65536的数值需用4个字节		 
{

	#if (PARITYBIT==NONE_PARITY)
		SCON = 0x50;	//8位可变波特率	
	#elif ((PARITYBIT==ODD_PARITY)||(PARITYBIT==EVEN_PARITY)||(PARITYBIT==MARK_PARITY))	
		SCON = 0xda;
	#elif (PARITYBIT==SPACE_PARITY)
		SCON=0xd2;
	#endif
	 EA = 0;
	 T2L = (65536 - (FOSC/4/BAUD));	//设置波特率重装值
	 T2H = (65536 - (FOSC/4/BAUD))>>8;

	 AUXR = 0x14;	//设置 T2为1T模式,并启动定时器2
	 AUXR |=0x01;	//选定定时器2为串口1的波特率发生器
	 ES = 1;	//使能串口1中断
	 EA = 1;	//打开总中断
}

/*.................

USART中断服务程序	
.................*/
void Uart() interrupt 4 using 1
{
	if(RI)	//接收标志位
	{
		Rdata = SBUF;	//取出接收到的
		RI = 0;
	
	}
	if(TI)
	{
		TI = 0;	  	//clear TI flag
		busy = 0;	//clear busy flag
	}
}

/*................
Uart发送字节数据
.................*/
void SendData(BYTE dat)
{
	while(busy);	//wait for the last data send over
	ACC = dat;	   	//获取校验位P(PSW.0)
	if(P)
	{
		#if (PARITYBIT == ODD_PARITY)
		TB8 = 0;
		#elif(PARITYBIT == EVEN_PARITY)
		TB8 = 1;	//
		#endif 
	}
	else
	{
		#if(PARITYBIT==ODD_PARITY)
			TB8 = 1;
		#elif(PARITYBIT==EVEN_PARITY)
			TB8 = 0;
		#endif
	}
		busy = 1;
		SBUF = ACC;	//写数据到UART数据寄存器
}

/*.............
发送字符串
...............*/
void SendString(char *s)
{
	while(*s)
	{
		SendData(*s++);	//发送当前字符
	}
}


//续2:usart.h文件(请另建文档保存,且被主函数包含)

#ifndef _USART_H
#define _USART_H
#include "reg52.h"
#include "stdio.h"

//typedef unsigned char BYTE;
//typedef unsigned int WORD;

#define uchar unsigned char	
#define uint  unsigned int

#define FOSC	22118400L	//system frequency
//#define BAUD	115200	//baud RATE 115200 bps,由于函数采用参数赋值波特率,这里屏蔽波特率宏定义

#define NONE_PARITY	0	//non chack
#define ODD_PARITY	1	//odd chack
#define EVEN_PARITY	2	//even chack
#define MARK_PARITY	3	//mark chack
#define SPACE_PARITY 4	//block chack

#define PARITYBIT	EVEN_PARITY	//slect even_parity

//void Uart_Init();	 	//原串口初始化函数没有形参输入
void Uart_Init(unsigned long BAUD);  //无符号长整型数据,4字节 0~(2^32-1)
void SendData(BYTE dat);
void SendString(char *s);


#endif

//续3:若编译报错,请将一下reg52.h头文件替换原头文件
/*--------------------------------------------------------------------------
REG52.H

Header file for generic 80C52 and 80C32 microcontroller.
Copyright (c) 1988-2002 Keil Elektronik GmbH and Keil Software, Inc.
All rights reserved.
--------------------------------------------------------------------------*/

#ifndef __REG52_H__
#define __REG52_H__

/*  BYTE Registers  */
sfr P0    = 0x80;	//PORT0
sfr P1    = 0x90;	//PORT1
sfr P2    = 0xA0;	//PORT2
sfr P3    = 0xB0;	//PORT3
sfr PSW   = 0xD0;
sfr ACC   = 0xE0;	//累加器
sfr B     = 0xF0;
sfr SP    = 0x81;
sfr DPL   = 0x82;
sfr DPH   = 0x83;
sfr PCON  = 0x87;
sfr TCON  = 0x88;
sfr TMOD  = 0x89;
sfr TL0   = 0x8A;
sfr TL1   = 0x8B;
sfr TH0   = 0x8C;
sfr TH1   = 0x8D;
sfr IE    = 0xA8;
sfr IP    = 0xB8;
sfr SCON  = 0x98;
sfr SBUF  = 0x99;

/*  8052 Extensions  */
sfr T2CON  = 0xC8;
sfr RCAP2L = 0xCA;
sfr RCAP2H = 0xCB;
sfr TL2    = 0xCC;
sfr TH2    = 0xCD;

/* self add 2020/08/20 */

//GPIO_MODE SFR
sfr	P0M1 = 0x93;	//93H
sfr	P0M0 = 0x94;	//94H
sfr	P1M1 = 0x91;
sfr P1M0 = 0x92;
sfr P3M1 = 0xB1;
sfr P3M0 = 0xB2;


/*  BIT Registers  */
/*  PSW  */
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; //8052 only

/*  TCON  */
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;


/*  IE  */
//sfr  IE	=	0XA8;	//中断允许寄存器(可位寻址)
sfr	 IE2	=	0xAF;	//中断允许寄存器(不可位寻址),T2中断允许控制位:ET2
sbit EA    = IE^7;  //CPU总中断允许位
sbit ELVD  =IE^6;	//低压检测中断允许位 
sbit ET2   = IE^5;  //8052 only
//sbit EADC	=	IE^5	//A/D转换中断允许位
sbit ES    = IE^4;	//串口1中断允许位
sbit ET1   = IE^3;	//定时/计数器1溢出中断允许位
sbit EX1   = IE^2;	//外部中断1中断允许位
sbit ET0   = IE^1;	//定时/计数器0溢出中断允许位
sbit EX0   = IE^0;	//外部中断0中断允许位

/*  IP  */
//sfr	 IP	=	0XB8;	//中断优先级控制寄存器(可位寻址)
sbit PPCA  = IP^7;	//PCA中断优先级控制位
sbit PLVD  = IP^6;	//低压检测中断优先级控制位
sbit PADC  = IP^5;	//A/D转换中断优先级控制位
//sbit PT2   = IP^5;//STC15系列 定时器2不能进行优先级设置
sbit PS    = IP^4;	//串口1中断优先级控制位
sbit PT1   = IP^3;	//定时器1中断优先级控制位
sbit PX1   = IP^2;	//外部中断1优先级控制位
sbit PT0   = IP^1;	//定时器0中断优先级控制位
sbit PX0   = IP^0;	//外部中断0优先级控制位

/*  P3  */
sbit RD    = P3^7;
sbit WR    = P3^6;
sbit T1    = P3^5;
sbit T0    = P3^4;
sbit INT1  = P3^3;
sbit INT0  = P3^2;
sbit TXD   = P3^1;
sbit RXD   = P3^0;

/*  SCON  */
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;

/*  P1  */
sbit T2EX  = P1^1; // 8052 only
sbit T2    = P1^0; // 8052 only
             
/*  T2CON  */
sbit TF2    = T2CON^7;
sbit EXF2   = T2CON^6;
sbit RCLK   = T2CON^5;
sbit TCLK   = T2CON^4;
sbit EXEN2  = T2CON^3;
sbit TR2    = T2CON^2;
sbit C_T2   = T2CON^1;
sbit CP_RL2 = T2CON^0;

/* CCP/PCA */
sfr  CCON = 0xD8;	//PCA 控制寄存器
sbit CCF0 =CCON^0;	//PCA模块0中断标志位
sbit CCF1 =CCON^1;	//PCA模块1中断标志位
sbit CR = CCON^6;	//PCA定时器运行控制寄存器
sbit CF = CCON^7;	//PCA定时器溢出寄存器
sfr CMOD = 0xD9;	//PCA模式寄存器
sfr CL =0xE9;	//PCA定时器低字节
sfr CH =0xF9;	//PCA定时器高字节

sfr CCAPM0=0xDA;	//PCA模块0模式寄存器
sfr CCAP0L=0xEA;	//PCA模块0捕获寄存器LOW 
sfr CCAP0H=0xFA;	//PCA模块0捕获寄存器HIGH

sfr CCAPM1 =0xDB;	//PCA模块1模式寄存器
sfr CCAP1L=0xEB;	//PCA模块1捕获寄存器LOW 
sfr CCAP1H=0xFB;	//PCA模块1捕获寄存器HIGH

sfr CCAPM2 =0xDC;	//PCA模块2模式寄存器
sfr CCAP2L=0xEC;	//PCA模块2捕获寄存器LOW 
sfr CCAP2H=0xFC;	//PCA模块2捕获寄存器HIGH

sfr PCA_PWM0=0xF2;	//PCA模块0的PWM寄存器
sfr PCA_PWM1=0xF3;	//PCA模块1的PWM寄存器
sfr PCA_PWM2=0xF4;	//PCA模块2的PWM寄存器

sfr P_SW1 = 0xA2;   //外设功能切换寄存器1
sfr P_SW2 = 0xBA;   //外设功能切换寄存器2

sfr	AUXR = 0x8E;		//辅助寄存器


typedef unsigned char	uchar;
typedef  unsigned char 	BYTE;	
typedef unsigned int	uint;
typedef  unsigned long 	DWORD;
//#define DWORD	unsigned long

#endif


  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值