📄 020.c
字号:
//-------------------------------------------
//液面检测 分四等级 生化仪 BIOBASE
//-------------------------------------------
//-------------------------------------------
//在用编程器的时候,要做一下配置操作
//配置字:使用内部4MHZ晶振 看门狗使能
// 程序加密 其它关闭
//-------------------------------------------
//-------------------------------------------
//如:用 EasyPRO 80B 编程器
//选中 INTRC OSC/(I/O) ; WDTE enable
// /CP enable ; /CPD enable
//-------------------------------------------
//-------------------------------------------
//I use PIC12F675;
#include<pic12f6x.h>
//-------------------------------------------
//-------------------------------------------
//宏定义 数据类型的定义
#define u8 unsigned char
#define u16 unsigned int
//---------------------------------------------
//-------------------------------------------
//四个等级(0、 1 、2、 3) 的延时基数
//延时时间=延时基数*8.214ms
#define NUM0 0X02;
#define NUM1 0X02;
#define NUM2 0X02;
#define NUM3 0X02;
//---------------------------------------------
//---------------------------------------------
//四个等级的灵敏度参数
//灵敏范围=灵敏度参数*2
#define POINT0 0X01;
#define POINT1 0X02;
#define POINT2 0X03;
#define POINT3 0X04;
//---------------------------------------------
//-------------------------------------------
//全局变量的定义
u8 TMR0_H = 0X00; //定时器0每中断一次,TMR0_H++
u8 TMR0_H_TEMP = 0x00; //TMR0_H的 当前备份
u8 TMR0_H_TEMP_LAST = 0x00; //TMR0_H的 上一次值的备份
u8 TMR0_TEMP = 0x00; //TMR0的当前备份
u8 TMR0_TEMP_LAST = 0x00; //TMR0的上一次值的备份
u8 CLASS=0X00; //等级最终标志
u8 NUM=0X00; //延时最终参数
u8 POINT=0X00; //灵敏度最终参数
u16 INT_TMR0=0X00; //当前 定时器0在延时时间内一共溢出的次数(由于比较大,故用 16位来表示 最大可达 十进制65535)
u16 INT_TMR0_LAST=0X00; //上一次 定时器0在延时时间内一共溢出的次数(由于比较大,故用 16位来表示 最大可达 十进制65535)
//-------------------------------------------
//-------------------------------------------
void interrupt tmr0(void)//定时器0中断函数
{
GIE = 0; //关中断 避免一切可能干扰
if(T0IE&T0IF) //再次 检验中断标志位
{
TMR0_H++; //完成自加
}
else // 若执行这步,则程序跑飞,等待,直到被狗咬
{
while(1)
{
;
}
}
T0IF = 0; //软件清零中断标志位
GIE = 1; //开中断 释放中断权限
}
//-------------------------------------------
//-------------------------------------------
void init(void) //初始化
{
CMCON = 0X07; //关闭比较器
TRISIO = 0X2F; //除了GPIO4是输出模式 其它的都用输入模式
ANSEL = 0X02; //GPIO1 此脚不用,故设为模拟输入 其它的设为数字I/O方式
OPTION = 0XFA; //禁止各口的内部上拉,使能GPIO2的检测脉冲信号功能(下降沿触发);预分频器给开门狗 分频 1:4
T0IE = 1; //使能定时器0中断
OSCCAL = 0X10; //修正一下晶振,(其实该代码没什么用,先加着)
GPIO = 0X2F; //除了GPIO4 其它的初始值都是1
GIE = 1; //开全局中断
}
//-------------------------------------------
//-------------------------------------------
//等级越大,越不灵敏
void class(void) //确定 等级 延时参数 灵敏度参数
{
if(GPIO0==1 && GPIO5==1) //不插短路棒 等级:0 延时参数:NUM0 灵敏度参数:POINT0
{
CLASS=0X00;
NUM=NUM0;
POINT=POINT0;
}
if(GPIO0==1 && GPIO5==0)//在1处插了一个短路棒 等级:1 延时参数:NUM1 灵敏度参数:POINT1
{
CLASS=0X01;
NUM=NUM1;
POINT=POINT1;
}
if(GPIO0==0 && GPIO5==1)//在2处插了一个短路棒 等级:2 延时参数:NUM2 灵敏度参数:POINT2
{
CLASS=0X02;
NUM=NUM2;
POINT=POINT2;
}
if(GPIO0==0 && GPIO5==0)//在1、2处插了一个短路棒 等级:3 延时参数:NUM3 灵敏度参数:POINT3
{
CLASS=0X03;
NUM=NUM3;
POINT=POINT3;
}
//确保每次循环中的延时准确
TMR0_H = 0X00; //清0
TMR0 = 0X00; //清0
}
//-------------------------------------------
//-------------------------------------------
//延时函数 形式参数为 i
//内部喂狗了
void delay_gj(u8 i) // 当 i=1时 8.8ms
{
u8 j,k;
for(;i>0;i--)
for(j=41;j>0;j--)
for(k=49;k>0;k--)
asm("clrwdt");
}
//-------------------------------------------
//-------------------------------------------
void temp_baohu(void) //保护一下延时后的关于脉冲的参数
{
GIE = 0; //关中断 一直到本次循环完,不希望有中断的打扰,以使本循环在最短的时间内完成
TMR0_H_TEMP = TMR0_H;
TMR0_TEMP = TMR0;
if(TMR0_TEMP == 0) //由于关了中断,在次做了一下类似进位的处理,防止由于定时器溢出引起的255个脉冲的丢失
{
TMR0_H_TEMP = TMR0_H+1;
}
}
//-------------------------------------------
//-------------------------------------------
void doclass(void) // 当前脉冲数与上次脉冲数进行比较,在灵敏度范围内则 小LED灯亮,否则灭
{
//把8位计算转换成16位计算方便(不用考虑负数和类似进位的问题)
INT_TMR0=(u16)TMR0_H_TEMP*0XFF+(u16)TMR0_TEMP;
INT_TMR0_LAST=(u16)TMR0_H_TEMP_LAST*0XFF+(u16)TMR0_TEMP_LAST;
if( INT_TMR0 <=(INT_TMR0_LAST+(u16)POINT) && INT_TMR0 >=(INT_TMR0_LAST-(u16)POINT) )
{
GPIO4=1;
}
else
{
GPIO4=0;
}
}
//-------------------------------------------
//-------------------------------------------
void temp_rebulid(void)//脉冲判断完成,整理一下各个参数,准备下一次循环
{
TMR0_H_TEMP_LAST = TMR0_H_TEMP;
TMR0_TEMP_LAST = TMR0_TEMP;
TMR0_H_TEMP = 0x00;
TMR0_TEMP = 0x00;
CLASS=0X00;
NUM=0X00;
POINT=0X00;
T0IF = 0; //由于在之前关了中断,所以要清一下中断标志。
GIE = 1; //开全局中断使能
}
//-------------------------------------------
//-------------------------------------------
//主函数
void main(void)
{
//***********************************
//delay_gj(1) ; //调试用语句
//***********************************
init();
while(1)
{
class(); //定下等级,然后定下与等级相关的参数,最后对TMR0_H 、TMR0_清零
delay_gj(NUM); //延时
temp_baohu(); //保护用于脉冲计算的参数
doclass(); //进行脉冲计算并做出LED亮灭的判断
temp_rebulid(); //重新整理各个参数,准备下一次循环
}
}
//------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -