|
发表于 2012-9-27 14:02:38
|
显示全部楼层
我用STC12C5A60S2的芯片跑了这个程序,程序跑成功了,用的是该芯片的PCA模块1,头文件改成了PCA1.主函数和头文件改了下,CKA文件不变!我在研究楼主这个程序,想红外发射出来,还想压缩数据,保存到eeprom中去!
/***************************************************************
作品:捕获红外发射脉冲高、低电平时间,送串口显示
单片机:STC12C5410
晶振:12M
编译环境:Keil uVision4 V9.00
***************************************************************/
// 说明:1、适用于:1T系列含有PCA捕获的STC单片机
// 2、捕获引脚PCA2(也就是P2.0),3字节存放一个电平时间数据。
// 3、串口显示脉冲高低电平时间数据(串口:字符 57600bps 校验位N 数据位8 停止位1),
// 4、含NEC、RC5解码,如需其它解码请自己加入。
//
// NEC码:(芯片有 市场上用量最大的HT6121/6122及其兼容的IC芯片等)
// RC5码:(芯片有 SAA3006、SAA3010、SAA3027、PCA8521、PT2210 等)
#include <STC12C5A60S2.h>
#include <CKA.H>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit IR = P1^4; //捕获引脚PCA2 即红外接收端口
sbit P21=P2^1;
uchar xdata v[486];
uchar N[4];
uint t;
ulong nn;
bit VT; //捕获完成标志
bit B_Z; //丢弃第一次捕获标志
void ChuanKou(); //串口发送主程序
void IR_RC5(); //RC5解码
/********************************************
函数:10ms × n 延时程序 STC 1T@12MHz
*********************************************/
void YS10ms(uchar n)
{
uchar i,j,k;
for(i=n;i!=0;i--)
for(j=198;j!=0;j--)
for(k=150;k!=0;k--);
}
/********************************************
函数:接收初始化
*********************************************/
void JS_Init(void)
{
uint i;
B_Z = 1;
t = 0;
for(i=0;i<486;i++)
{
v[t]=0; //存储区清0
}
EPCA_LVD = 1; //PCA模块中断和低压检测中断允许位
CCAPM1|= 0x31; //PCA模块1:16位捕获模式,由CCP2的跳变触发。ECCF2=1,使能CCF2中断。
CMOD = 0x01; //ECF=1(CMOD.0=1)使能CF(CCON.7)位产生中断
EA = 1;
P21 = 0; //开始接收,指示灯打开
}
/********************************************
函数:主程序
*********************************************/
void main()
{
Uart_Init(12,1);
JS_Init();
YS10ms(10);
ZIFUC("\r\n\r\n\r\n ****** 开始接收,请按遥控 ******\r\n");
while(1)
{
if(VT)
{
VT = 0;
P21 = 1; //接收完成,指示灯关闭
ChuanKou(); //串口显示
YS10ms(200); //1秒后重新开始
JS_Init();
ZIFUC("\r\n\r\n\r\n ****** 可以重新接收,请按遥控 ******\r\n");
}
}
}
/***************************************************************
函数:PCA中断捕获程序(电位跳变捕获模式)
***************************************************************/
void PCA_isr(void) interrupt 6 using 1
{
if(CF) //是否是PCA定时器溢出
{
CF = 0; //必须软件清0 (PCA 定时器标志)
v[t]++; //PCA定时器溢出计数,保存数据最高字节
if(v[t]>1) //设置允许溢出次数,>131ms 终止捕获
{
CR = 0;
CF = 0;
CCAPM1 = 0;
CCF1=0;
VT=1; //捕获完成标志
v[t]=0;
return;
}
}
if(CCF1) //是否是电位跳变
{
CCF1 = 0; //必须软件清0 (PCA 模块1标志)
CL = 0; //先赋值低位
CH = 0;
if(B_Z)
{
CR =1; //启动PCA定时器
B_Z=0;
return;
} //丢弃第一次捕获数据
t++;
v[t]=CCAP1H; //保存数据高字节
t++;
v[t]=CCAP1L; //保存数据低字节
t++;
}
if(t >= 486) //捕获162个数据(1个电平时间3字节存放)
{
CCAPM1 = 0;
CCF1=0;
CR = 0;
CF = 0;
VT = 1; //捕获完成标志
}
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:串口发送主程序
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ChuanKou()
{
uchar i;
uint j,T;
ZIFUC("\r\n\r\n ****** 接收完成 ******");
ZIFUC("\r\n\r\n ( 以下是遥控器发射脉冲的波形数据 )");
ZIFUC("\r\n\r\n 序号 高电平时间(us) 低电平时间(us)\r\n\r\n");
i=0;
for(j=0;j<486;)
{
((uchar *)&nn)[0] = 0;
((uchar *)&nn)[1] = v[j++];
((uchar *)&nn)[2] = v[j++];
((uchar *)&nn)[3] = v[j++];
ZIFUC(" ");
JZ(i,10,2); //序号
ZIFUC(" ");
JZ(nn,10,8); //高电平时间
((uchar *)&nn)[0] = 0;
((uchar *)&nn)[1] = v[j++];
((uchar *)&nn)[2] = v[j++];
((uchar *)&nn)[3] = v[j++];
ZIFUC(" ");
JZ(nn,10,8); //低电平时间
if( (i%8)==0 )
ZIFUC("\r\n\r\n");
else
ZIFUC("\r\n");
i++;
}
///////////////// NEC解码 ////////////////
j=9; //引导码丢弃
for(i=0;i<32;i++)
{
j++;
((uchar *)&T)[0] = v[j++];
((uchar *)&T)[1] = v[j++];
j += 3;
N[i/8] >>= 1;
if((T<1900) && (T>1000))
{
N[i/8] |= 0x80;
}
}
if(N[2] == ~N[3]) //校验NEC操作码。错误则尝试RC5解码
{
ZIFUC("\r\n 【 NEC通用编码格式:引导码 + 32位编码(16位用户码+操作码正反码) 】\r\n");
ZIFUC("\r\n 用户码(高8位):0x");
JZ(N[0],16,1);
ZIFUC("\r\n 用户码(低8位):0x");
JZ(N[1],16,1);
ZIFUC("\r\n\r\n 操作码正码 :0x");
JZ(N[2],16,1);
ZIFUC("\r\n");
if(N[0] == ~N[1])
{
ZIFUC("\r\n\r\n 经对比,16位用户码是正反码,用户码正码:0x");
JZ(N[0],16,1);
}
return;
}
///////////////// 初略分析是否是RC5编码 ////////////////
j=0;
for(i=0;i<20;i++)
{
j++; //最高位丢弃(1个数据3字节);
((uchar *)&T)[0] = v[j++];
((uchar *)&T)[1] = v[j++];
if(T<600 || T>1800) //RC5码前20个脉冲数据600<nn<1800
{
ZIFUC("\r\n 【 解码失败,再试一试或者分析波形数据 】");
return;
}
}
///////////////// 将波形数据绘成图像 ////////////////
ZIFUC("\r\n 【 RC5编码发射波形 】 发射顺序:(低位)<--(高位)\r\n");
ZIFUC("\r\n___");
j=0;
for(i=0;i<26;i++)
{
j++; //最高位丢弃(1个数据3字节);
((uchar *)&T)[0] = v[j++];
((uchar *)&T)[1] = v[j++];
if(T>2000)
{
break;
}
if(i%2 != 1) //如果i是偶数
{
if(T<1000)
ZIFUC("▉");
else
ZIFUC("▉▉");
}
else
{
if(T<950)
ZIFUC("__");
else
ZIFUC("____");
}
}
ZIFUC("_____________");
ZIFUC("\r\n┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊\r\n");
IR_RC5(); //RC5解码
ZIFUC("\r\n┃起始位┃空┃ 系统位 ┃ 数据位 ┃\r\n");
ZIFUC("\r\n\r\n 【 RC5通用编码格式:14位编码 】\r\n");
ZIFUC("\r\n 起始位(2位):0x");
JZ(N[0],16,1);
ZIFUC(" 二进制: ");
JZ(N[0],2,2);
ZIFUC("\r\n 控制位(1位):");
if(N[1])
ZIFUC(" 1");
else
ZIFUC(" 0");
ZIFUC("\r\n 系统位(5位):0x");
JZ(N[2],16,1);
ZIFUC(" 二进制: ");
JZ(N[2],2,5);
ZIFUC("\r\n 数据位(6位):0x");
JZ(N[3],16,1);
ZIFUC(" 二进制:");
JZ(N[3],2,6);
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:根据收集的脉冲数据进行RC5解码
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void IR_RC5()
{
bit B_v,BV;
uchar x;
uchar n;
uint t;
BV = 1; //BV=1时检测(接收端)低电平时间,BV=0时检测(接收端)高电平时间。
x = 0;
t = 0;
N[0]=N[1]=N[2]=N[3]=0;
for(n=0;n<14;n++) //14位位码解码
{
x++; //最高位丢弃(1个数据3字节);
((uchar *)&t)[0] = v[x++];
((uchar *)&t)[1] = v[x++];
/*┈┈┈ 确认位码值 ┈┈┈*/
if(BV)
{
if(t < 950) //BV=1时,如果t<950uS,下次还是检测(接收端)低电平时间,且跳过高电平时间。
{
B_v=1;
x+=3;
}
else //BV=1时,如果t>950uS,下次检测(接收端)高电平时间
{
B_v=1;
BV=0;
}
}
else
{
if(t < 950)
{
B_v=0;
x+=3;
}
else
{
B_v=0;
BV=1;
}
}
/*┈┈┈ 装载位码值 ┈┈┈*/
if(n < 2)
{
N[0] >>= 1;
if(B_v)N[0] |= 0x02;
}
else if (n==2)
N[1] = B_v;
else if(n<8)
{
N[2] >>= 1;
if(B_v)N[2] |= 0x10;
}
else if(n<15)
{
N[3] >>= 1;
if(B_v)N[3] |= 0x20;
}
/*┈┈┈ 发射位码值 ┈┈┈*/
ZIFUC(" ");
if(B_v)
ZIFUC("1");
else
ZIFUC("0");
}
}
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机内核特殊功能寄存器 C51 Core SFRs
// 7 6 5 4 3 2 1 0 Reset Value
sfr ACC = 0xE0; //Accumulator 0000,0000
sfr B = 0xF0; //B Register 0000,0000
sfr PSW = 0xD0; //Program Status Word CY AC F0 RS1 RS0 OV F1 P 0000,0000
//-----------------------------------
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; //Stack Pointer 0000,0111
sfr DPL = 0x82; //Data Pointer Low Byte 0000,0000
sfr DPH = 0x83; //Data Pointer High Byte 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机系统管理特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr PCON = 0x87; //Power Control SMOD SMOD0 LVDF POF GF1 GF0 PD IDL 0001,0000
// 7 6 5 4 3 2 1 0 Reset Value
sfr AUXR = 0x8E; //Auxiliary Register T0x12 T1x12 UART_M0x6 BRTR S2SMOD BRTx12 EXTRAM S1BRS 0000,0000
//-----------------------------------
sfr AUXR1 = 0xA2; //Auxiliary Register 1 - PCA_P4 SPI_P4 S2_P4 GF2 ADRJ - DPS 0000,0000
/*
PCA_P4:
0, 缺省PCA 在P1 口
1,PCA/PWM 从P1 口切换到P4 口: ECI 从P1.2 切换到P4.1 口,
PCA0/PWM0 从P1.3 切换到P4.2 口
PCA1/PWM1 从P1.4 切换到P4.3 口
SPI_P4:
0, 缺省SPI 在P1 口
1,SPI 从P1 口切换到P4 口: SPICLK 从P1.7 切换到P4.3 口
MISO 从P1.6 切换到P4.2 口
MOSI 从P1.5 切换到P4.1 口
SS 从P1.4 切换到P4.0 口
S2_P4:
0, 缺省UART2 在P1 口
1,UART2 从P1 口切换到P4 口: TxD2 从P1.3 切换到P4.3 口
RxD2 从P1.2 切换到P4.2 口
GF2: 通用标志位
ADRJ:
0, 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器
1,10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器
DPS: 0, 使用缺省数据指针DPTR0
1,使用另一个数据指针DPTR1
*/
//-----------------------------------
sfr WAKE_CLKO = 0x8F; //附加的 SFR WAK1_CLKO
/*
7 6 5 4 3 2 1 0 Reset Value
PCAWAKEUP RXD_PIN_IE T1_PIN_IE T0_PIN_IE LVD_WAKE _ T1CLKO T0CLKO 0000,0000B
b7 - PCAWAKEUP : PCA 中断可唤醒 powerdown。
b6 - RXD_PIN_IE : 当 P3.0(RXD) 下降沿置位 RI 时可唤醒 powerdown(必须打开相应中断)。
b5 - T1_PIN_IE : 当 T1 脚下降沿置位 T1 中断标志时可唤醒 powerdown(必须打开相应中断)。
b4 - T0_PIN_IE : 当 T0 脚下降沿置位 T0 中断标志时可唤醒 powerdown(必须打开相应中断)。
b3 - LVD_WAKE : 当 CMPIN 脚低电平置位 LVD 中断标志时可唤醒 powerdown(必须打开相应中断)。
b2 -
b1 - T1CLKO : 允许 T1CKO(P3.5) 脚输出 T1 溢出脉冲,Fck1 = 1/2 T1 溢出率
b0 - T0CLKO : 允许 T0CKO(P3.4) 脚输出 T0 溢出脉冲,Fck0 = 1/2 T1 溢出率
*/
//-----------------------------------
sfr CLK_DIV = 0x97; //Clock Divder - - - - - CLKS2 CLKS1 CLKS0 xxxx,x000
//-----------------------------------
sfr BUS_SPEED = 0xA1; //Stretch register - - ALES1 ALES0 - RWS2 RWS1 RWS0 xx10,x011
/*
ALES1 and ALES0:
00 : The P0 address setup time and hold time to ALE negative edge is one clock cycle
01 : The P0 address setup time and hold time to ALE negative edge is two clock cycles.
10 : The P0 address setup time and hold time to ALE negative edge is three clock cycles. (default)
11 : The P0 address setup time and hold time to ALE negative edge is four clock cycles.
RWS2,RWS1,RWS0:
000 : The MOVX read/write pulse is 1 clock cycle.
001 : The MOVX read/write pulse is 2 clock cycles.
010 : The MOVX read/write pulse is 3 clock cycles.
011 : The MOVX read/write pulse is 4 clock cycles. (default)
100 : The MOVX read/write pulse is 5 clock cycles.
101 : The MOVX read/write pulse is 6 clock cycles.
110 : The MOVX read/write pulse is 7 clock cycles.
111 : The MOVX read/write pulse is 8 clock cycles.
*/
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机中断特殊功能寄存器
//有的中断控制、中断标志位散布在其它特殊功能寄存器中,这些位在位地址中定义
//其中有的位无位寻址能力,请参阅 新一代 1T 8051系列 单片机中文指南
// 7 6 5 4 3 2 1 0 Reset Value
sfr IE = 0xA8; //中断控制寄存器 EA ELVD EADC ES ET1 EX1 ET0 EX0 0x00,0000
//-----------------------
sbit EA = IE^7;
sbit EPCA_LVD = IE^6; //低压监测中断允许位
sbit EADC = IE^5; //ADC 中断允许位
sbit ES = IE^4;
sbit ET1 = IE^3;
sbit EX1 = IE^2;
sbit ET0 = IE^1;
sbit EX0 = IE^0;
//-----------------------
sfr IE2 = 0xAF; //Auxiliary Interrupt - - - - - - ESPI ES2 0000,0000B
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr IP = 0xB8; //中断优先级低位 PPCA PLVD PADC PS PT1 PX1 PT0 PX0 0000,0000
//--------
sbit PPCA = IP^7; //PCA 模块中断优先级
sbit PLVD = IP^6; //低压监测中断优先级
sbit PADC = IP^5; //ADC 中断优先级
sbit PS = IP^4;
sbit PT1 = IP^3;
sbit PX1 = IP^2;
sbit PT0 = IP^1;
sbit PX0 = IP^0;
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr IPH = 0xB7; //中断优先级高位 PPCAH PLVDH PADCH PSH PT1H PX1H PT0H PX0H 0000,0000
sfr IP2 = 0xB5; // - - - - - - PSPI PS2 xxxx,xx00
sfr IPH2 = 0xB6; // - - - - - - PSPIH PS2H xxxx,xx00
//-----------------------
//新一代 1T 8051系列 单片机I/O 口特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr P0 = 0x80; //8 bitPort0 P0.7 P0.6 P0.5 P0.4 P0.3 P0.2 P0.1 P0.0 1111,1111
sfr P0M0 = 0x94; // 0000,0000
sfr P0M1 = 0x93; // 0000,0000
sfr P1 = 0x90; //8 bitPort1 P1.7 P1.6 P1.5 P1.4 P1.3 P1.2 P1.1 P1.0 1111,1111
sfr P1M0 = 0x92; // 0000,0000
sfr P1M1 = 0x91; // 0000,0000
sfr P1ASF = 0x9D; //P1 analog special function
sfr P2 = 0xA0; //8 bitPort2 P2.7 P2.6 P2.5 P2.4 P2.3 P2.2 P2.1 P2.0 1111,1111
sfr P2M0 = 0x96; // 0000,0000
sfr P2M1 = 0x95; // 0000,0000
sfr P3 = 0xB0; //8 bitPort3 P3.7 P3.6 P3.5 P3.4 P3.3 P3.2 P3.1 P3.0 1111,1111
sfr P3M0 = 0xB2; // 0000,0000
sfr P3M1 = 0xB1; // 0000,0000
sfr P4 = 0xC0; //8 bitPort4 P4.7 P4.6 P4.5 P4.4 P4.3 P4.2 P4.1 P4.0 1111,1111
sfr P4M0 = 0xB4; // 0000,0000
sfr P4M1 = 0xB3; // 0000,0000
// 7 6 5 4 3 2 1 0 Reset Value
sfr P4SW = 0xBB; //Port-4 switch - LVD_P4.6 ALE_P4.5 NA_P4.4 - - - - x000,xxxx
sfr P5 = 0xC8; //8 bitPort5 - - - - P5.3 P5.2 P5.1 P5.0 xxxx,1111
sfr P5M0 = 0xCA; // 0000,0000
sfr P5M1 = 0xC9; // 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机定时器特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr TCON = 0x88; //T0/T1 Control TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 0000,0000
//-----------------------------------
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; //T0/T1 Modes GATE1 C/T1 M1_1 M1_0 GATE0 C/T0 M0_1 M0_0 0000,0000
sfr TL0 = 0x8A; //T0 Low Byte 0000,0000
sfr TH0 = 0x8C; //T0 High Byte 0000,0000
sfr TL1 = 0x8B; //T1 Low Byte 0000,0000
sfr TH1 = 0x8D; //T1 High Byte 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机串行口特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr SCON = 0x98; //Serial Control SM0/FE SM1 SM2 REN TB8 RB8 TI RI 0000,0000
//-----------------------------------
sbit SM0 = SCON^7; //SM0/FE
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; //Serial Data Buffer xxxx,xxxx
sfr SADEN = 0xB9; //Slave Address Mask 0000,0000
sfr SADDR = 0xA9; //Slave Address 0000,0000
//-----------------------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr S2CON = 0x9A; //S2 Control S2SM0 S2SM1 S2SM2 S2REN S2TB8 S2RB8 S2TI S2RI 00000000B
sfr S2BUF = 0x9B; //S2 Serial Buffer xxxx,xxxx
sfr BRT = 0x9C; //S2 Baud-Rate Timer 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机看门狗定时器特殊功能寄存器
sfr WDT_CONTR = 0xC1; //Watch-Dog-Timer Control register
// 7 6 5 4 3 2 1 0 Reset Value
// WDT_FLAG - EN_WDT CLR_WDT IDLE_WDT PS2 PS1 PS0 xx00,0000
//-----------------------
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机PCA/PWM 特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr CCON = 0xD8; //PCA 控制寄存器。 CF CR - - - - CCF1 CCF0 00xx,xx00
//-----------------------
sbit CF = CCON^7; //PCA计数器溢出标志,由硬件或软件置位,必须由软件清0。
sbit CR = CCON^6; //1:允许 PCA 计数器计数, 必须由软件清0。
//-
//-
sbit CCF1 = CCON^1; //PCA 模块1 中断标志, 由硬件置位, 必须由软件清0。
sbit CCF0 = CCON^0; //PCA 模块0 中断标志, 由硬件置位, 必须由软件清0。
//-----------------------
sfr CMOD = 0xD9; //PCA 工作模式寄存器。 CIDL - - - CPS2 CPS1 CPS0 ECF 0xxx,x000
/*
CIDL: idle 状态时 PCA 计数器是否继续计数, 0: 继续计数, 1: 停止计数。
CPS2: PCA 计数器脉冲源选择位 2。
CPS1: PCA 计数器脉冲源选择位 1。
CPS0: PCA 计数器脉冲源选择位 0。
CPS2 CPS1 CPS0
0 0 0 系统时钟频率 fosc/12。
0 0 1 系统时钟频率 fosc/2。
0 1 0 Timer0 溢出。
0 1 1 由 ECI/P3.4 脚输入的外部时钟,最大 fosc/2。
1 0 0 系统时钟频率, Fosc/1
1 0 1 系统时钟频率/4,Fosc/4
1 1 0 系统时钟频率/6,Fosc/6
1 1 1 系统时钟频率/8,Fosc/8
ECF: PCA计数器溢出中断允许位, 1--允许 CF(CCON.7) 产生中断。
*/
//-----------------------
sfr CL = 0xE9; //PCA 计数器低位 0000,0000
sfr CH = 0xF9; //PCA 计数器高位 0000,0000
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr CCAPM0 = 0xDA; //PCA 模块0 PWM 寄存器 - ECOM0 CAPP0 CAPN0 MAT0 TOG0 PWM0 ECCF0 x000,0000
sfr CCAPM1 = 0xDB; //PCA 模块1 PWM 寄存器 - ECOM1 CAPP1 CAPN1 MAT1 TOG1 PWM1 ECCF1 x000,0000
//ECOMn = 1:允许比较功能。
//CAPPn = 1:允许上升沿触发捕捉功能。
//CAPNn = 1:允许下降沿触发捕捉功能。
//MATn = 1:当匹配情况发生时, 允许 CCON 中的 CCFn 置位。
//TOGn = 1:当匹配情况发生时, CEXn 将翻转。
//PWMn = 1:将 CEXn 设置为 PWM 输出。
//ECCFn = 1:允许 CCON 中的 CCFn 触发中断。
//ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
// 0 0 0 0 0 0 0 0x00 未启用任何功能。
// x 1 0 0 0 0 x 0x21 16位CEXn上升沿触发捕捉功能。
// x 0 1 0 0 0 x 0x11 16位CEXn下降沿触发捕捉功能。
// x 1 1 0 0 0 x 0x31 16位CEXn边沿(上、下沿)触发捕捉功能。
// 1 0 0 1 0 0 x 0x49 16位软件定时器。
// 1 0 0 1 1 0 x 0x4d 16位高速脉冲输出。
// 1 0 0 0 0 1 0 0x42 8位 PWM。
//ECOMn CAPPn CAPNn MATn TOGn PWMn ECCFn
// 0 0 0 0 0 0 0 0x00 无此操作
// 1 0 0 0 0 1 0 0x42 普通8位PWM, 无中断
// 1 1 0 0 0 1 1 0x63 PWM输出由低变高可产生中断
// 1 0 1 0 0 1 1 0x53 PWM输出由高变低可产生中断
// 1 1 1 0 0 1 1 0x73 PWM输出由低变高或由高变低都可产生中断
//-----------------------
sfr CCAP0L = 0xEA; //PCA 模块 0 的捕捉/比较寄存器低 8 位。 0000,0000
sfr CCAP0H = 0xFA; //PCA 模块 0 的捕捉/比较寄存器高 8 位。 0000,0000
sfr CCAP1L = 0xEB; //PCA 模块 1 的捕捉/比较寄存器低 8 位。 0000,0000
sfr CCAP1H = 0xFB; //PCA 模块 1 的捕捉/比较寄存器高 8 位。 0000,0000
//-----------------------
// 7 6 5 4 3 2 1 0 Reset Value
sfr PCA_PWM0 = 0xF2; //PCA 模块0 PWM 寄存器。 - - - - - - EPC0H EPC0L xxxx,xx00
sfr PCA_PWM1 = 0xF3; //PCA 模块1 PWM 寄存器。 - - - - - - EPC1H EPC1L xxxx,xx00
//PCA_PWMn: 7 6 5 4 3 2 1 0
// - - - - - - EPCnH EPCnL
//B7-B2: 保留
//B1(EPCnH): 在 PWM 模式下,与 CCAPnH 组成 9 位数。
//B0(EPCnL): 在 PWM 模式下,与 CCAPnL 组成 9 位数。
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机 ADC 特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr ADC_CONTR = 0xBC; //A/D 转换控制寄存器 ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2 CHS1 CHS0 0000,0000
sfr ADC_RES = 0xBD; //A/D 转换结果高8位 ADCV.9 ADCV.8 ADCV.7 ADCV.6 ADCV.5 ADCV.4 ADCV.3 ADCV.2 0000,0000
sfr ADC_RESL = 0xBE; //A/D 转换结果低2位 ADCV.1 ADCV.0 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机 SPI 特殊功能寄存器
// 7 6 5 4 3 2 1 0 Reset Value
sfr SPCTL = 0xCE; //SPI Control Register SSIG SPEN DORD MSTR CPOL CPHA SPR1 SPR0 0000,0100
sfr SPSTAT = 0xCD; //SPI Status Register SPIF WCOL - - - - - - 00xx,xxxx
sfr SPDAT = 0xCF; //SPI Data Register 0000,0000
//--------------------------------------------------------------------------------
//新一代 1T 8051系列 单片机 IAP/ISP 特殊功能寄存器
sfr IAP_DATA = 0xC2;
sfr IAP_ADDRH = 0xC3;
sfr IAP_ADDRL = 0xC4;
// 7 6 5 4 3 2 1 0 Reset Value
sfr IAP_CMD = 0xC5; //IAP Mode Table 0 - - - - - MS1 MS0 0xxx,xx00
sfr IAP_TRIG = 0xC6;
sfr IAP_CONTR = 0xC7; //IAP Control Register IAPEN SWBS SWRST CFAIL - WT2 WT1 WT0 0000,x000
//--------------------------------------------------------------------------------
//*******************************************************
// 实验调试助手,串口字符显示(版本:2011/08/06)
//
// 串口说明:使用定时器1,字符发送,N,8,1
//
// ( 6MHz @ 1T) 28800bps
// (11.0592MHz @ 1T)115200bps
// ( 12MHz @ 1T) 57600bps
// (22.1184MHz @ 1T)256000bps
//
// ( 6MHz @12T) 2400bps
// (11.0592MHz @12T) 57600bps
// ( 12MHz @12T) 4800bps
//
// 【供用户调用的3个函数】
// void Uart_Init(uint8 M,uint8 T); //串口初始化
// void JZ(uint32 tem,uint8 num,uint8 i); //整形数据送串口显示
// void ZIFUC(uint8 code *p); //字符串发送
//*******************************************************
#ifndef _CKA_H_
#define _CKA_H_
#include <intrins.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define uint32 unsigned long
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:串口初始化
入口:(MHz,12T/1T)
举例:如使用 22.1184MHz晶振,STC 1T系列,
那么初始化时应为: Uart_Init(22,1),
与PC的串口助手通讯:波特率256000bps,字符,校验位N,数据位8,停止位1
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void Uart_Init(uint8 M,uint8 T)
{
bit BS,XT;
uint16 MT;
MT = M*100+T;
switch(MT)
{
//////////////////////////////////////////////【1T系列】
case 601: //28800bps@6MHz
BS = 1; //倍速
XT = 1; //1T模式
TL1 = 0xF3; //初值
break;
case 1101: //115200bps@11.0592MHz
BS = 0; //不倍速
XT = 1; //1T模式
TL1 = 0xFD; //初值
break;
case 1201: //57600bps@12MHz
BS = 1; //倍速
XT = 1; //1T模式
TL1 = 0xF3; //初值
break;
case 2201: //256000bps@22.1184MHz
BS = 1; //倍速
XT = 1; //1T模式
TL1 = 0xFB; //初值
break;
//////////////////////////////////////////////【12T系列】
case 612: //2400bps@6MHz
BS = 1; //倍速
XT = 0; //12T模式
TL1 = 0xF3; //初值
break;
case 1112: //57600bps@11.0592MHz
BS = 1; //倍速
XT = 0; //12T模式
TL1 = 0xFF; //初值
break;
case 1212: //4800bps@12MHz
BS = 1; //倍速
XT = 0; //12T模式
TL1 = 0xF3; //初值
break;
}
if(BS)
PCON |= 0x80; //使能波特率倍速位SMOD
else
PCON &= 0x7f; //波特率不倍速
SCON = 0x50; //8位数据,可变波特率
if(XT)
AUXR |= 0x40; //定时器1时钟为Fosc,即1T
else
AUXR &= 0xbf; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xfe; //串口1选择定时器1为波特率发生器
TMOD &= 0x0f; //清除定时器1模式位
TMOD |= 0x20; //设定定时器1为8位自动重装方式
TH1 = TL1; //重装值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:HEX转ASCII
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
uint8 HEX2ASCII(uint8 dat)
{
dat &= 0x0f;
if(dat <= 9) return(dat+'0'); //数字0~9 ('0' 0x30)
return (dat-10+'A'); //字母A~F ('A' 0x41,'a' 0x61)
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:串口发送
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void TxS(uint8 i)
{
SBUF=i;
while(!TI);
TI=0;
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:字符串发送
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void ZIFUC(uint8 code *p) //发送一串字符串
{
for(; *p != 0; p++) TxS(*p); //遇到停止符0结束
}
/*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
函数:整形数据送串口显示
入口:tem = 整形数据(送入1~4字节整形数据)
num = 以什么进制显示,2:二进制,10:十进制,16:十六进制
i = 显示低几位 (以二进制显示时)
= 显示个位算起几位数 (以十进制显示时)
= 显示几字节 (以十六进制显示时)
┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/
void JZ(uint32 tem,uint8 num,uint8 i)
{
uint8 j,z[10];
bit BT=0;
switch(num)
{
case 2: tem = _lror_(tem,i-1); //以二进制显示 长整数循环右移
while(i--)
{
if(tem & 1)
ZIFUC("1");
else
ZIFUC("0");
tem = _lrol_(tem,1);
}
/* 【 另一种算法 】
tem <<= (32-i);
while(i--)
{
if(tem & 0x80000000)
ZIFUC("1");
else
ZIFUC("0");
tem <<= 1;
}
*/
break;
case 10: for(j=0;j<i;j++) //以十进制显示
{
z[j] = tem%10; //nv[0]=个位,nv[1]=十位,······
tem /= 10;
}
while(i--)
{
if(z || (i==0))
BT=1; //数据有效标志
if(BT)
TxS(HEX2ASCII(z[i])); //数据有效前的“0”不显示, z z[i]
else
ZIFUC(" "); //用空格替换。
}
break;
case 16: for(j=4-i;j<4;j++) //十六进制显示
{
z[j] = ((uint8 *)&tem)[j];
TxS(HEX2ASCII(z[j]>>4)); //发送高4位
TxS(HEX2ASCII(z[j])); //发送低4位
}
break;
}
}
#endif
|
|