|
爱科技、爱创意、爱折腾、爱极致,我们都是技术控
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 xueyunmichen 于 2019-6-1 14:52 编辑
之前有人想要的 125KHZ ID卡 读卡 与 模拟卡一体合并的 现在奉上
验证 图片在二楼
用STC15W4K系列单片机的高级PWM 输出125khz载波信号;
以下代码
- #include <STC15.H>
- #define uchar unsigned char
- #define uint unsigned int
-
- #define FOSC 12000000L //系统频率
- #define BAUD 115200 //串口波特率
- #define S1_S0 0x40 //P_SW1.6
- #define S1_S1 0x80 //P_SW1.7
-
- sbit KEY1 = P3^4;
- void IntPWM(bit dat)
- {
- P2M0=0X20; //初始化PWM端口 P2^1 口
- P2M1=0X00;
- P_SW2 |= 0x80;
- PWMCFG = 0x00;
- PWMCKS = 0x00; //选择PWM的时钟为Fosc/1
- PWMC = 95; //设置PWM周期
- PWM2T1 = 0; //设置PWM2第1次反转的PWM计数
- PWM2T2 = 20; //设置PWM2第2次反转的PWM计数
- PWM3T1 = 48; //设置PWM3第1次反转的PWM计数
- PWM3T2 = 68; //设置PWM3第2次反转的PWM计数
- if(dat)
- {
- PWMCR = 0x00; //PWM通道2使能PWM信号输出
- }
- else
- {
- PWMCR = 0x03; //PWM通道2使能PWM信号输出
- PWMCR |= 0x80; //使能PWM模块
- }
- P_SW2 &= ~0x80;
- }
- void Timer0Init(bit dat) //定时器工作于计时模式
- {
- AUXR |= 0x80; //定时器时钟1T模式
- TMOD &= 0xF0; //设置定时器模式
- if(dat)
- {
- TL0 = 0x00; //设置定时初值 256微秒@12.000MHz
- TH0 = 0xF4; //设置定时初值
- TF0 = 0; //清除TF0标志
- ET0 = 1; //定时器中断
- TR0 = 1; //定时器计时
- }
- else
- {
- TL0 = 0x00; //设置定时初值
- TH0 = 0x00; //设置定时初值
- TF0 = 0; //清除TF0标志
- ET0 = 0; //定时器中断
- TR0 = 0; //定时器计时
- }
- }
- void Timer2Init(void) //1毫秒@12.000MHz
- {
- T2L = 0x20; //设置定时初值
- T2H = 0xD1; //设置定时初值
- AUXR |= 0x14; //定时器2开始计时
- IE2 |= 0X04;
- }
- void Uart_Init()
- {
- ACC = P_SW1;
- ACC &= ~(S1_S0 | S1_S1); //S1_S0=0 S1_S1=0
- P_SW1 = ACC; //(P3.0/RxD, P3.1/TxD)
- SCON = 0x50; //8位可变波特率
- AUXR = 0x40; //定时器1为1T模式
- TMOD = 0x00; //定时器1为模式0(16位自动重载)
- TL1 = (65536 - (FOSC/4/BAUD)); //设置波特率重装值
- TH1 = (65536 - (FOSC/4/BAUD))>>8;
- TR1 = 1; //定时器1开始启动
- ES = 1; //使能串口中断
- }
- uchar keyf=0; //按键有效
- uchar num_check=0;//低电平有效时间
- uchar anjian(void)
- {
- unsigned char num_key=0;//按键号
- static unsigned char temp_code=0;//保存按键值
- static unsigned char key_flag=0;//按键有效标识
- if(!KEY1) //如按键按下
- {
- keyf=1; //按键按下 定时器2中断函数中 num_check 每1毫秒自加
-
- temp_code = 1; //记录按键号
-
- if(num_check >= 50) //当按键有效时间到达50毫秒
- {
- num_check = 50; //保持计数时间
- key_flag = 1; //按键有效
- }
-
- }
- else //如松开按键
- {
- keyf=0; //按键松开停止计时
- num_check = 0; //计时时间清零
- if(key_flag == 1) //如果按键有效
- {
- key_flag = 0; //清除按键有效标识
- switch(temp_code)
- {
- case 1: num_key=1;//记录按键号
- break;
- }
- }
- else num_key = 0; //如果按键无效 清除按键号
- }
- return(num_key); //返回按键号
- }
- bit busy; //串口忙
- /*----------------------------
- 发送串口数据
- ----------------------------*/
- void SendData(uchar dat)
- {
- while (busy); //等待前面的数据发送完成
- busy = 1;
- SBUF = dat; //写数据到UART数据寄存器
- }
- bit jj; //开启串口打印标识
- uint time; //记录时间
- bit tou=0; //数据头
- bit FLAG=1; //端口状态
- bit kt=1; //空跳
- uchar k2=0; //位 接收数
- uchar k=0,k1=0; //数据头检测计数,数据缓存
- uchar i=0; //字节 接收数
- uchar SCK=0; //时钟周期
- bit dat1=0; //数据发送标识
- uchar DD[8]={0}; //数据接收缓存数组
- uchar DD1[8]={0xFF, 0x99, 0x20, 0x00, 0xE5, 0xe0, 0x52, 0xe2}; //发送数据
- bit ka=0; //1:模拟卡,0:读卡器
- void setka() //卡号调制函数
- {
- static uchar j1=0,k3,i1=0; //发送字节计数 ,待发送数据缓存,发送位计数
- if(i1==0) //若发送位计数为零
- k3 = DD1[j1]; //缓存下一个字节数据到发送缓存
-
- if(SCK==0) //如时钟在0*256us 开始准备数据 高位先发
- {
- if(!(k3&0x80)) P33 = 0; //如果待发送位 为“0” 需要上升沿 所以 数据发送口准备为 “0”
- if( k3&0x80) P33 = 1; //如果待发送位 为“1” 需要下降沿 所以 数据发送口准备为 “1”
- }
-
- if(SCK==1) //如果时钟到达第一个256us 开始发送 边沿
- {
- if(!(k3&0x80)) {P33 = 1;dat1 = 1;} //如果待发送位 为“0” 需要上升沿 所以 数据发送口发送上升沿 “1” 并记录数据已经发送
- if( k3&0x80) {P33 = 0;dat1 = 1;} //如果待发送位 为“1” 需要下降沿 所以 数据发送口发送下降沿 “0” 并记录数据已经发送
- }
-
- if(SCK >= 2) //如果时钟到达512us
- {
- SCK = 0; //时钟清零
-
- if(dat1 == 1) //如果数据已经发送
- {
- dat1 = 0; //清除数据发送标识
- i1++; //发送位 加1
- k3 = k3 << 1; //数据缓存左移 发送下一位
-
- if(i1==8) //如果已经发完8个位
- {
- i1=0; //发送位计数清零
- j1++; //发送字节计数自加
- if(j1 >= 8) j1 = 0; //如果发送完8个字节(发完全部数据) 清零字节计数
- }
- }
- }
- }
- //P32 读卡数据输入(中断解码)
- //P33 模拟卡调制端口
- //P34 按键端口
- //P35 指示灯 高电平为读卡器模式 低电平为模拟卡模式
- //P37 125KHZ输出
- void main()
- {
- uchar key=0;
- uchar j;
- P3M0=0XA8;
- P3M1=0X00; //初始化端口
- Uart_Init(); //串口初始化
- if(!ka) //如果为读卡器模式
- {
- IntPWM(0); //PWM初始化为125khz 占空比50%
- Timer0Init(0); //定时器0初始化为计时器
- EX0 = 1; //使能INT0中断
- }
- Timer2Init(); //定时器1初始化
- P33 = 0; //调制端口置低
- P32 = 1; //
- IT0 = 0; //设置INT0 上升沿和下降沿中断
- EA=1; //总中断开
- while(1)
- {
- key = anjian(); //检测按键
- if(key==1) //如果按键按下
- {
- key=0; //清除按键
-
- ka = ~ka; //改变模式
- P35 = ~P35; //改变指示灯状态
- if(ka) //如果模拟卡
- {
- EX0 = 0; //关闭外部中断
- IntPWM(1); //关闭PWM
- P37=0; //125KHZ端口置低
- TR0 = 0; //关闭计时
- TL0 = 0x00; //计时器清零
- TH0 = 0x00;
- Timer0Init(1); //定时器0初始化为定时器 256us
- SCK=0; //发送时钟清零
- }
- if(!ka) //如果读卡器模式
- {
- P33=0; //模拟卡调制端口置低
- tou=0; //清除读卡模式一些状态
- k=0; //清除读卡模式一些状态
- k1=0; //清除读卡模式一些状态
- k2=0; //清除读卡模式一些状态
- i=0; //清除读卡模式一些状态
- IntPWM(0); //开启PWM
- Timer0Init(0); //定时器0初始化为计时器
- EX0 = 1; //开启外部中断
- }
- }
- if(ka)setka(); //如果模拟卡 则运行模拟卡函数
- if(jj) //如果开启打印
- {
- jj=0;
- for(j=0;j<8;j++)
- {
- SendData(DD[j]);//串口打印接收到的8字节数据
- DD1[j]=DD[j]; //更新发送卡号数据
- }
- }
- }
- }
- uchar zdjs=0; //无卡计时
- uchar rcc=0; //读取校验计数
- void exint0() interrupt 0 //INT0中断入口
- {
- TR0 = 0; //关闭计时
- FLAG=P32; //记录信号状态(0:下降沿; 1:上升沿)
-
- time= ((TH0<<8) + TL0)/12; //记录中断事件
- TL0 = 0x00; //计时器清零
- TH0 = 0x00; //计时器清零
- TR0 = 1;
- if((time>200) && (time<520)) //过滤杂波信号 只处理中断时间为180-520微秒 的事件
- {
- if(time>400) kt=0; //如果时间大于400微妙 则认为非空跳(有效边沿)
- if(time<256) //如果时间小于256微秒
- {
- if(kt==0) kt=1; //如果上一次边沿 非空跳边沿 则记录为空跳
- else kt=0; //否则 记录为非空跳 (有效边沿)
- }
- if((!kt) && (rcc<48)) //如果是有效边沿
- {
- if(!tou) //如果没有接收到数据头 则记录数据头 (9个下降沿)
- {
-
- if(FLAG) k++; //如果为下降沿 开始记录
- if(!FLAG) k = 0; //过程中 收到上升沿 记录清零
-
- if(k == 9) {k=0; tou =1;DD[i++]=0xff;} //如果记录到9个下降沿 则已经取得数据头 头标识置位, 第一位数据记录为 0xff
- }
- if(tou) //如果已经获取数据头
- {
- k1 <<= 1; //数据左移一位 开始接收数据 高位在前 低位在后
- if(FLAG) k1 |= 0x01; //如果是下降沿 则为 “1” 如为上升沿 则记录为“0”
- k2++; //记录次数标识
- if(k2 == 8) //如果记录到8次 则已经接收完一个字节
- {
- k2=0; //记录次数清零
-
- if(DD[i] == k1) rcc++;
- else rcc=0;
- DD[i++] = k1; //将数据存入缓存 进行下一个字节的接收
- k1=0; //清零接收数据
- if(i==8) //如果接收到八个字节 则接收完成
- {
- i=0; //字节数清零
- tou=0; //清除数据头标识
- if((rcc>=16)&&(rcc<48)){jj=1;rcc=48;} //开启串口输出
- }
- }
- }
- }
- }
- else //清除读卡器接收状态
- {
- tou=0;
- k=0;
- k1=0;
- k2=0;
- i=0;
- jj=0;
- }
- zdjs=0; //清除无卡计时
- }
- //定时器0中断函数
- void Timer0Interrupt(void) interrupt 1
- {
- if(!ka)
- {
- TR0 = 0; //超时中断
- kt=0; //记录为非空跳
- }
- if(ka)SCK++;
- }
- //定时器2中断函数
- void Timer2Interrupt(void) interrupt 12
- {
- if(keyf) //如果按键按下
- num_check++;//按下时间计时
- zdjs++; //无卡计时
- if(zdjs>=2)rcc=0;//如2毫秒内无中断 则判断移除卡片
- }
- /*----------------------------
- UART 中断服务程序
- -----------------------------*/
- void Uart() interrupt 4 using 1
- {
- if (RI) RI = 0; //清除RI位
- if (TI)
- {
- TI = 0; //清除TI位
- busy = 0; //清忙标志
- }
- }
复制代码
125读卡模拟卡一体.rar
(26.63 KB, 下载次数: 77)
|
打赏
-
查看全部打赏
|