标题:
STM8红外程序(外中断接收)
[打印本页]
作者:
liuxin549521
时间:
2017-12-29 11:04
标题:
STM8红外程序(外中断接收)
STM8红外程序
单片机源程序如下:
#include "stm8s.h"
#include "stm8s003f3p.h"
#include "STM8_IR.h"
#include "STM8_DELAY.h"
#define IR_READ (PC_IDR&(0x01<<7))
volatile uchar Flag_ir_start = 0;//启动标志位
volatile uint IR_time = 0;
volatile unsigned long IR_data;
volatile uchar IR_temp[4];
void LED_Init(void)
{
PA_DDR |= (0x01<<3);//设置PA3为输出
PA_CR1 |= (0x01<<3);//设置PA3为推挽输出,速度为2MHz
PA_CR2 &=(uchar)(~(0x01<<3));
PA_ODR &=(uchar)(~(0x01<<3)); //关闭led
}
void TIM1_Init(void)
{
TIM1_CR1 = 0x00; //向上的计数方向,中断计数不停
TIM1_IER = 0x01;
TIM1_PSCRH = 0x00; //进行16分频
TIM1_PSCRL = 0x0f; //16Mhz/(15+1)=1Mhz-->1us
TIM1_ARRH = 0x00;
TIM1_ARRL = 20; //20us
TIM1_CR1 |=0x01;
}
//外中断接收红外数据
void EXIT_Init(void)
{
//01是PA,23是PB,45是PC,67是PD引脚
//P?IS[1:0] 设置触发方式,00是下降沿触发
EXTI_CR1 &=(uchar)(~(0x03<<4)); // PC下降沿触发
EXTI_CR1 |= (0x01<<5);
}
void IR_Init(void)
{
PC_DDR &=(uchar)(~(0x01<<7));
PC_CR1 &=(uchar)(~(0x01<<7));
//PC_CR1 |= (0x01<<7);//上拉输入
PC_CR2 |= (0x01<<7);//打开外部中断
EXIT_Init();//RISING and falling EDGE
}
//位反转算法
uchar reverse8( uchar c )
{
c = ( c & 0x55 ) << 1 | ( c & 0xAA ) >> 1;
c = ( c & 0x33 ) << 2 | ( c & 0xCC ) >> 2;
c = ( c & 0x0F ) << 4 | ( c & 0xF0 ) >> 4;
return c;
}
void IR_rx(void)
{
static uchar Flag_end=0;
static uchar IR_num = 0;
uchar i,temp;
//TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
TIM1_CR1 |= (0x01<<0); //开启计数器
//800us,17000us
if(IR_time<=40)////杂波
{
IR_data=0;
IR_num=0;
IR_time=0;
//TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
return ;
}
//13000us
if(IR_time >= 650)//13ms则启动成功
{
Flag_ir_start = 1;
IR_num = 0;
IR_data=0;
}
if((Flag_ir_start==1)&&(IR_time<=130))//2600us
{
IR_data<<=1;
if(IR_time>=85)//1700us
{
IR_data |= (0x01<<0);
}
IR_num++;
if(IR_num>31)
{
Flag_end = 1;
Flag_ir_start=0;
IR_time = 0;
}
}
if(Flag_end)
{
Flag_end = 0;
TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
IR_temp[0] = (uchar)((IR_data>>0)&0xff);
IR_temp[1] = (uchar)((IR_data>>8)&0xff);
IR_temp[2] = (uchar)((IR_data>>16)&0xff);
IR_temp[3] = (uchar)((IR_data>>24)&0xff);
IR_data=0;
IR_num=0;
if(IR_temp[0]!=(uchar)(~IR_temp[1]))
{
//校验失败
//PA_ODR ^= (0x01<<3);
}
else
{
IR_temp[1] = reverse8(IR_temp[1]);//位反转算法
if(IR_temp[1]==0x45)//0xa2
{
//PA_ODR ^= (0x01<<3);
PA_ODR |= (0x01<<3);
}
if(IR_temp[1]==0x46)
{
PA_ODR &=(uchar)(~(0x01<<3));
//PA_ODR |= (0x01<<3);
}
//PA_ODR &=(uchar)(~(0x01<<3));
}
}
IR_time = 0;
}
@far @interrupt void EXTI_PORTC_IRQHandler(void)
{
IR_rx();
}
//定时器1溢出中断服务
@far @interrupt void timer1_isr(void) //10us
{
//TIM1_CR1 &=~(0x01<<0); //关闭计数器
TIM1_SR1 &=~(0x01<<0); //清除中断标志
IR_time++;
//TIM1_CR1 |= (0x01<<0); //开启计数器
//PA_ODR |= (0x01<<3);
//return ;
}
/*
void IR_rx(void)
{
static uchar Flag_end=0;
static uchar IR_num = 0;
TIM1_CR1 &=(uchar)(~(0x01<<0));//关闭计数器
//800us,17000us
if(IR_time<=80)////杂波
{
IR_data=0;
IR_num=0;
IR_time=0;
//PA_ODR ^= (0x01<<3);
return ;
}//
//13000us
if(IR_time >= 1300)//13ms则启动成功
{
Flag_ir_start = 1;
IR_num = 0;
IR_data=0;
//
//PA_ODR |= (0x01<<3);
}
//
if((Flag_ir_start==1)&&(IR_time<=260))//2600us
{
IR_data<<=1;
if(IR_time>=170)//1700us
{
IR_data |= (0x01<<0);
}
IR_num++;
if(IR_num>31)
{
Flag_end = 1;
Flag_ir_start=0;
//PA_ODR ^= (0x01<<3);
}
}
if(Flag_end)
{
Flag_end = 0;
IR_temp[0] = (uchar)((IR_data>>0)&0xff);
IR_temp[1] = (uchar)((IR_data>>8)&0xff);
IR_temp[2] = (uchar)((IR_data>>16)&0xff);
IR_temp[3] = (uchar)((IR_data>>24)&0xff);
IR_data=0;
IR_num=0;
if(IR_temp[0]!=(uchar)(~IR_temp[1]))
{
}
else
{
//PA_ODR ^= (0x01<<3);
if(IR_temp[1]==0xa2)
{
//PA_ODR ^= (0x01<<3);
PA_ODR |= (0x01<<3);
}
if(IR_temp[1]<0x7f)
{
PA_ODR &=(uchar)(~(0x01<<3));
//PA_ODR |= (0x01<<3);
}
//PA_ODR &=(uchar)(~(0x01<<3));
}
}
IR_time = 0;
TIM1_CR1 |= (0x01<<0);//开计数器
}*/
复制代码
/********************************************\
_ooOoo_
o8888888o
88" . "88
(| -_- |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑 永无BUG
楠A407舍长出品
\********************************************/
#include "stm8s.h"
#include "stm8s003f3p.h"
#include "STM8_IR.h"
#define uchar unsigned char
#define uint unsigned int
_Bool Flag_ir = 0;
void STM8_CLK_Init(void)
{
CLK_HSICmd(ENABLE);//HSI = 16MHz
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); //f_psc = 16MHz/1
}
//--------------------主函数分割线---------------------
//
//
//-----------------------------------------------------
void main(void)
{
unsigned char re ;
unsigned char reg;
_asm("sim");//关全部中断
STM8_CLK_Init();//内部HSI,16MHz
LED_Init();
IR_Init();
TIM1_Init();
_asm("rim");//开全部中断
while(1)
{
//IR_test();
}
}
复制代码
所有资料51hei提供下载:
STM8_IR_test.rar
(4.02 MB, 下载次数: 79)
2017-12-29 11:03 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
chengfgc
时间:
2018-4-26 10:42
学习下,不知道能不能用上
作者:
hefeng898961
时间:
2018-7-23 08:55
感谢分享
作者:
Null520
时间:
2019-5-22 15:54
楼主程序不对呀
作者:
INIT0
时间:
2019-6-1 15:48
Null520 发表于 2019-5-22 15:54
楼主程序不对呀
是不对。。定时器是不是开早了。而且没见到差值或清0 CNTR
作者:
zhjf103
时间:
2019-7-9 21:58
不错,学习学习!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1