标题:
单片机红外遥控计算器源码(个位数相加)
[打印本页]
作者:
1061700625
时间:
2017-12-5 17:21
标题:
单片机红外遥控计算器源码(个位数相加)
通过红外遥控,实现简单地计算器,并通过数码管显示出来
0.png
(7.29 KB, 下载次数: 61)
下载附件
2017-12-5 22:24 上传
单片机源程序如下:
#include "stc15.h"
#include "intrins.h"
#include "gpio.h"
#include "uart.h"
#include "595hc.h"
#define MAIN_Fosc 11059200L //定义主时钟
#define SysTick 10000 // 次/秒, 系统滴答频率, 在4000~16000之间
#define Timer0_Reload (65536UL - ((MAIN_Fosc + SysTick/2) / SysTick)) //Timer 0 中断频率, 在config.h中指定系统滴答频率, 在4000~16000之间.
u8 i=0,j,k;
u8 number;
u8 cnt_1ms; //1ms基本计时
bit B_1ms; //1ms标志
/************* 红外接收程序变量声明 **************/
sbit P_IR_RX = P3^6; //定义红外接收输入IO口
u8 IR_SampleCnt; //采样计数
u8 IR_BitCnt; //编码位数
u8 IR_UserH; //用户码(地址)高字节
u8 IR_UserL; //用户码(地址)低字节
u8 IR_data; //数据原码
u8 IR_DataShit; //数据移位
bit P_IR_RX_temp; //Last sample
bit B_IR_Sync; //已收到同步标志
bit B_IR_Press; //安键动作发生
u8 IR_code; //红外键码
u16 UserCode; //用户码
/*********************************/
#define IR_SAMPLE_TIME (1000000UL/SysTick) //查询时间间隔, us, 红外接收要求在60us~250us之间
#if ((IR_SAMPLE_TIME <= 250) && (IR_SAMPLE_TIME >= 60))
#define D_IR_sample IR_SAMPLE_TIME //定义采样时间,在60us~250us之间
#endif
#define D_IR_SYNC_MAX (15000/D_IR_sample) //SYNC max time
#define D_IR_SYNC_MIN (9700 /D_IR_sample) //SYNC min time
#define D_IR_SYNC_DIVIDE (12375/D_IR_sample) //decide data 0 or 1
#define D_IR_DATA_MAX (3000 /D_IR_sample) //data max time
#define D_IR_DATA_MIN (600 /D_IR_sample) //data min time
#define D_IR_DATA_DIVIDE (1687 /D_IR_sample) //decide data 0 or 1
#define D_IR_BIT_NUMBER 32 //bit number
#define SysTick 10000 // 次/秒, 系统滴答频率, 在4000~16000之间
//*******************************************************************************************
//**************************** IR RECEIVE MODULE ********************************************
void IR_RX_NEC(void)
{
u8 SampleTime;
IR_SampleCnt++; //Sample + 1
F0 = P_IR_RX_temp; //Save Last sample status
P_IR_RX_temp = P_IR_RX; //Read current status
if(F0 && !P_IR_RX_temp) //Pre-sample is high,and current sample is low, so is fall edge
{
SampleTime = IR_SampleCnt; //get the sample time
IR_SampleCnt = 0; //Clear the sample counter
if(SampleTime > D_IR_SYNC_MAX) B_IR_Sync = 0; //large the Maxim SYNC time, then error
else if(SampleTime >= D_IR_SYNC_MIN) //SYNC
{
if(SampleTime >= D_IR_SYNC_DIVIDE)
{
B_IR_Sync = 1; //has received SYNC
IR_BitCnt = D_IR_BIT_NUMBER; //Load bit number
}
}
else if(B_IR_Sync) //has received SYNC
{
if(SampleTime > D_IR_DATA_MAX) B_IR_Sync=0; //data samlpe time too large
else
{
IR_DataShit >>= 1; //data shift right 1 bit
if(SampleTime >= D_IR_DATA_DIVIDE) IR_DataShit |= 0x80; //devide data 0 or 1
if(--IR_BitCnt == 0) //bit number is over?
{
B_IR_Sync = 0; //Clear SYNC
if(~IR_DataShit == IR_data) //判断数据正反码
{
UserCode = ((u16)IR_UserH << 8) + IR_UserL;
IR_code = IR_data;
B_IR_Press = 1; //数据有效
}
}
else if((IR_BitCnt & 7)== 0) //one byte receive
{
IR_UserL = IR_UserH; //Save the User code high byte
IR_UserH = IR_data; //Save the User code low byte
IR_data = IR_DataShit; //Save the IR data byte
}
}
}
}
}
//*********************************** MODULE END ********************************************
//*******************************************************************************************
///********************** Timer0初始化 ************************/
void Timer0Init(void) //1毫秒 @11.0592MHz
{
AUXR = 0x80; //定时器时钟1T模式
TMOD = 0x00; //设置定时器模式
TL0 = (u8)(Timer0_Reload % 256); //设置定时初值
TH0 = (u8)(Timer0_Reload / 256); //设置定时初值
EA = 1; //开启总中断
ET0 = 1; //允许定时器0中断
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
///********************** Timer0中断函数 ************************/
void timer0 (void) interrupt 1
{
IR_RX_NEC();
if(--cnt_1ms == 0)
{
cnt_1ms = SysTick / 1000;
B_1ms = 1; //1ms标志
DisplayScan(); //1ms扫描显示一位
}
}
int Addend; //数
int Augend; //被数
int Sum_Sub; //和_差
int Middle_Number; //中间数
int Buffer; //缓冲暂存
bit Catch_Flag = 0;
u8 Addition_Flag = 0;
void main(void)
{
GPIO();
Timer0Init();
cnt_1ms = SysTick / 1000;
for(i=0; i<8; i++) LED8[i] = 16;
LED8[0] = 12; //C
LED8[1] = 10; //A
LED8[2] = 21; //L
LED8[3] = 12; //C
LED8[4] = 25; //U
LED8[5] = 21; //L
LED8[6] = 10; //A
LED8[7] = 17; //-
while (1)
{
if(B_1ms) //1ms到
{
B_1ms = 0;
if(B_IR_Press) //检测到收到红外键码
{
B_IR_Press = 0;
// LED8[0] = (u8)((UserCode >> 12) & 0x0f); //用户码高字节的高半字节
// LED8[1] = (u8)((UserCode >> 8) & 0x0f); //用户码高字节的低半字节
// LED8[2] = (u8)((UserCode >> 4) & 0x0f); //用户码低字节的高半字节
// LED8[3] = (u8)(UserCode & 0x0f); //用户码低字节的低半字节
// LED8[6] = IR_code >> 4;
// LED8[7] = IR_code & 0x0f;
switch(IR_code)
{
case 0x16: Middle_Number = 0;Catch_Flag = 1;
break;
case 0x0C: Middle_Number = 1;Catch_Flag = 1;
break;
case 0x18: Middle_Number = 2;Catch_Flag = 1;
break;
case 0x5E: Middle_Number = 3;Catch_Flag = 1;
break;
case 0x08: Middle_Number = 4;Catch_Flag = 1;
break;
case 0x1C: Middle_Number = 5;Catch_Flag = 1;
break;
case 0x5A: Middle_Number = 6;Catch_Flag = 1;
break;
case 0x42: Middle_Number = 7;Catch_Flag = 1;
break;
case 0x52: Middle_Number = 8;Catch_Flag = 1;
break;
case 0x4A: Middle_Number = 9;Catch_Flag = 1;
break;
case 0x07: Middle_Number = 10;Catch_Flag = 1; // -
break;
case 0x15: Middle_Number = 11;Catch_Flag = 1; // +
break;
case 0x09: Middle_Number = 12;Catch_Flag = 1; // =
break;
}
if(Catch_Flag == 1)
{
Catch_Flag = 0;
if(Addition_Flag == 0)
{
First:
for(i=0;i<8;i++) LED8[i] = 16; //清屏
Augend = Middle_Number;
LED8[0] = Augend;
Addition_Flag = 1;
}
else if(Addition_Flag == 1)
{
Buffer = Middle_Number;
if((Buffer - 10) < 0) goto First; //如果不是符号,则跳转
if(Buffer == 10) LED8[1] = 17;
if(Buffer == 11) LED8[1] = 24;
Addition_Flag = 2;
}
else if(Addition_Flag == 2)
{
Addend = Middle_Number;
LED8[2] = Addend;
Addition_Flag = 3;
}
if(Middle_Number == 12)
{
if(Buffer == 10)
{
Sum_Sub = Augend - Addend;
if(Sum_Sub < 0)
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
红外遥控 - 计算器(个位数相加).rar
(43.2 KB, 下载次数: 34)
2017-12-5 17:20 上传
点击文件名下载附件
下载积分: 黑币 -5
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1