|
楼主 |
发表于 2020-4-30 00:52:38
|
显示全部楼层
#include "stc8.h" //STC头文件
#include "def.h" //宏定义 常用函数
#include "math.h"
#include "stdio.h"
char S[10]={0,0,0,0,'M'}; //定义到程序空间中
u16 M1=512,M2=0; //存储PCA脉冲捕捉次数
void delay_us(u16 us) //20MHz晶振
{
u16 i;
u8 m;
for(i=0;i<us;i++)
for(m=0;m<2;m++);
}
/*******************************************编码器CCP脉冲捕捉*********************************/
void PCAInit() //PCA初始化
{
P_SW1 |= 0X10; //**01**** 脉冲捕捉端口
P_SW1 &= 0XDF;
CCON = 0x00; //CF、CR均零,PCA中断标志清零
CMOD &= 0x7F; //CIDL位置0,空闲模式下PCA计数器仍然工作
CMOD &= 0xF9; //CP2、CP1、CP0设置为100,PCA时钟源选择为系统时钟 1/20 us
CMOD |= 0x08; //CP2、CP1、CP0设置为100,PCA时钟源选择为系统时钟
CMOD |= 0x01; //ECF位置1,允许寄存器CCON中CF位中断(PCA计时中断) (2^16)/20 us = 3276.8 us =3.2768 ms
CL = 0x00; //PCA计数器赋初值
CH = 0x00; //PCA计数器赋初值
CCAPM1 &= 0xBF; //ECOM1位置0,禁止比较器功能
CCAPM1 &= 0xDF; //CAPP2位置0,禁止上升沿捕获
CCAPM1 |= 0x10; //CAPN2位置1,允许下降沿捕获
CCAPM1 &= 0xF7; //MAT1位置0,禁止匹配控制位
CCAPM1 &= 0xFB; //TOG1位置0,禁止翻转控制位
CCAPM1 &= 0xFD; //PWM1位置0,禁止PWM模式
CCAPM1 |= 0x01; //ECCF1位置1,允许CCF1中断
CCAP1L = 0x00; //PCA捕获值寄存器赋初值
CCAP1H = 0x00; //PCA捕获值寄存器赋初值
CCAPM2 &= 0xBF; //ECOM2位置0,禁止比较器功能
CCAPM2 &= 0xDF; //CAPP2位置0,禁止上升沿捕获
CCAPM2 |= 0x10; //CAPN2位置1,允许下降沿捕获
CCAPM2 &= 0xF7; //MAT2位置0,禁止匹配控制位
CCAPM2 &= 0xFB; //TOG2位置0,禁止翻转控制位
CCAPM2 &= 0xFD; //PWM2位置0,禁止PWM模式
CCAPM2 |= 0x01; //ECCF2位置1,允许CCF2中断
CCAP2L = 0x00; //PCA捕获值寄存器赋初值
CCAP2H = 0x00; //PCA捕获值寄存器赋初值
}
void PCA_int () interrupt 7 //PCA中断服务程序
{
if(CF) //PCA计数器溢出
{
//V0 = (M0/1.024)* 1950 * PI/2 ; //速度 = ( (总脉冲数M / 编码器线数1024) * 编码器齿数 30/ 车模齿数20 ) * 轮周长65直径 / 脉冲读取时间2ms。
CF = 0; //将PCA计数器阵列溢出标志位软件清零
}
if(CCF1) //CCF1捕获中断
{
M1++;
CCF1 = 0; //将标志位软件清零
}
if(CCF2) //CCF3捕获中断
{
M2++;
CCF2 = 0; //将标志位软件清零
}
}
/******************************************电机PWM驱动*************************************************/
void PWM_Configuration() //PWM进行初始化
{
PWMCFG &= 0xBF; //将ETADC位置0,即PWM与ADC不关联
PWMCFG &= 0x7F; //将CBIF位置0,PWM计数器归零中断标志位,需软件清零
P_SW2 |= 0x80; //将EAXSFR位置1,以访问PWM在扩展RAM区的特殊功能寄存器
//对PWM0的初始化部分
PWM0CR &= 0xEF; //将C0_S[1:0]位置0 1,选择PWM0的输出引脚是P1.0
PWM0CR |= 0x08; //将C0_S[1:0]位置0 1,选择PWM0的输出引脚是P1.0
PWM0CR |= 0x80; //将ENC0O位置1,PWM0的端口为PWM输出口,受PWM波形发生器控制
PWM0CR |= 0x40;; //将C0INI位置0,设置PWM0输出端口的初始电平为低电平
PWMIF &= 0xFE; //将C0IF位置0,PWM0中断标志位,需软件清零
PWM0CR |= 0x04; //将EC0I位置1,使能PWM0中断
PWM0CR &= 0xFD; //将EC0T2SI位置0,关闭T2翻转时中断
PWM0CR &= 0xFE; //将EC0T1SI位置0,关闭T1翻转时中断
//对PWM1的初始化部分
PWM1CR &= 0xEF; //将C0_S[1:0]位置0 1,选择PWM1的输出引脚是P1.1
PWM1CR |= 0x08; //将C0_S[1:0]位置0 1,选择PWM1的输出引脚是P1.1
PWM1CR |= 0x80; //将ENC0O位置1,PWM0的端口为PWM输出口,受PWM波形发生器控制
PWM1CR |= 0x40;; //将C0INI位置0,设置PWM1输出端口的初始电平为低电平
PWMIF &= 0xFD; //将C0IF位置0,PWM1中断标志位,需软件清零
PWM1CR |= 0x04; //将EC0I位置1,使能PWM1中断
PWM1CR &= 0xFD; //将EC0T2SI位置0,关闭T2翻转时中断
PWM1CR &= 0xFE; //将EC0T1SI位置0,关闭T1翻转时中断
//对PWM2的初始化部分
PWM2CR &= 0xEF; //将C0_S[1:0]位置0 1,选择PWM2的输出引脚是P1.2
PWM2CR |= 0x08; //将C0_S[1:0]位置0 1,选择PWM2的输出引脚是P1.2
PWM2CR |= 0x80; //将ENC0O位置1,PWM2的端口为PWM输出口,受PWM波形发生器控制
PWM2CR |= 0x40;; //将C0INI位置0,设置PWM2输出端口的初始电平为低电平
PWMIF &= 0xFC; //将C0IF位置0,PWM2中断标志位,需软件清零
PWM2CR |= 0x04; //将EC0I位置1,使能PWM2中断
PWM2CR &= 0xFD; //将EC0T2SI位置0,关闭T2翻转时中断
PWM2CR &= 0xFE; //将EC0T1SI位置0,关闭T1翻转时中断
//对PWM3的初始化部分
PWM3CR &= 0xEF; //将C0_S[1:0]位置0 1,选择PWM3的输出引脚是P1.3
PWM3CR |= 0x08; //将C0_S[1:0]位置0 1,选择PWM3的输出引脚是P1.3
PWM3CR |= 0x80; //将ENC0O位置1,PWM3的端口为PWM输出口,受PWM波形发生器控制
PWM3CR |= 0x40; //将C0INI位置1,设置PWM3输出端口的初始电平为高电平
PWMIF &= 0xF7; //将C0IF位置0,PWM3中断标志位,需软件清零
PWM3CR |= 0x04; //将EC0I位置1,使能PWM3中断
PWM3CR &= 0xFD; //将EC0T2SI位置0,关闭T2翻转时中断
PWM3CR &= 0xFE; //将EC0T1SI位置0,关闭T1翻转时中断
PWMCKS = 0x00 ; //系统时钟
PWMC = 0x2000 ; //设置PWM周期为2^10个时钟 8192
P_SW2 &= 0x7F; //将EAXSFR位置0,恢复访问XRAM
//对PWM翻转计数器赋初值
PWM0T1 = 0x0000; //赋值PWM0第一次翻转计数器值 初始为高电平
PWM0T2 = 0x0000; //赋值PWM0第二次翻转计数器值 相同跳过,一直为低电平
//占空比0
PWM1T1 = 0x0000; //赋值PWM1第一次翻转计数器值(不断变化值)
PWM1T2 = 0X1000; //赋值PWM1第二次翻转计数器值(定值)
//占空比50%
PWM2T1 = 0x0000; //赋值PWM2第一次翻转计数器值(不断变化值)
PWM2T2 = 0x0001; //赋值PWM2第二次翻转计数器值(定值)
//占空比100%
PWM3T1 = 0x0000; //赋值PWM3第一次翻转计数器值(不断变化值)
PWM3T2 = 0x0000; //赋值PWM3第二次翻转计数器值(定值)
//占空比0
//PWM外部异常控制寄存器的操作
PWMFDCR &= 0xDF; //将ENFD位置0,关闭PWM外部异常检测功能
PWMFDCR &= 0xF7; //将ENDI位置0,关闭PWM异常检测中断
PWMFDCR &= 0xFB; //将FDCMP位置0,比较器与PWM无关
PWMFDCR &= 0xFD; //将FDIO位置0,P3.5的状态与PWM无关
PWMFDCR &= 0xFE; //将FDIF位置0,PWM异常检测中断标志位,需软件清零
IP2 |= 0x40; //将PPWM位置1,使能PWM中断为最高优先级中断
//使能PWM波形发生器
PWMCR |= 0x40; //将ECBI位置1,使能PWM计数器归零中断
}
void ISP_Check() //串口发送调用函数 串口1波特率为9600 STC内部晶振频率为11.0592MHz
{
unsigned char a;
a=0;
while(S[a]!= '\0')
{
SBUF = S[a]; //SUBF接受/发送缓冲器(又叫串行通信特殊功能寄存器)
while(!TI); //等特数据传送 (TI发送中断标志)
TI = 0; // 清除数据传送标志
a++; // 下一个字符
}
}
void main()
{
P1M1 &= 0xF0; P1M0 &= 0xF0;
PWM_Configuration(); //初始化PWM口
PCAInit(); //脉冲捕捉初始化
SCON=0x50; //REN=1允许串行接受状态,串口工作模式2
TMOD= 0x00; //定时器1为模式0(16位自动重载)
AUXR=0X40; //开启1T模式
TL1=(65535-(11059200/4/9600)); //设置波特率重装值
TH1=(65535-(11059200/4/9600))>>8;
TR1 = 1; //开启定时器1
EA = 1; // 开总中断
while(1)
{
S[0]=M1/100000+'0'; //取万位
S[1]=(M1/10000)%10+'0'; //取万位 //3ms 30
S[2]=(M1/1000)%10+'0'; //取千位
S[3]=(M1/1000)%10+'0'; //取百位
S[4]=(M1/100)%10+'0'; //取十位
S[5]=M1%10+'0'; //取个位
S[6]=",";
S[7]='\0';
ISP_Check(); //发送数据
P_SW2 |= 0x80; //将EAXSFR位置1,以访问PWM在扩展RAM区的特殊功能寄存器
PWMCR |= 0x80; //将ENPWM位置1,使能PWM波形发生器,PWM计数器开始计数
PWM0T1 = 0x0001; //赋值PWM0第一次翻转计数器值 初始为高电平
PWM0T2 = 0x01FF; //赋值PWM0第二次翻转计数器值 相同跳过,一直为低电平
//占空比
PWM1T1 = 0X01FE; //赋值PWM1第一次翻转计数器值(不断变化值)
PWM1T2 = 0x01FF; //赋值PWM1第二次翻转计数器值(定值)
//占空比
PWM2T1 = 0x0000; //赋值PWM2第一次翻转计数器值(不断变化值)
PWM2T2 = 0x0001; //赋值PWM2第二次翻转计数器值(定值)
//占空比100%
PWM3T1 = 0x0000; //赋值PWM3第一次翻转计数器值(不断变化值)
PWM3T2 = 0x0000; //赋值PWM3第二次翻转计数器值(定值)
//占空比0
M1=0; //清零
M2=0;
CR = 1; //启动PCA计数器阵列计数
delay_us(100);
}
} |
|