Board logo

标题: [原创,项目]6位LED绕线机计数器的原理图、C语言源代码、proteus仿真 [打印本页]

作者: zcllom    时间: 2008-11-12 01:02     标题: [原创,项目]6位LED绕线机计数器的原理图、C语言源代码、proteus仿真

yQAJAYaW.jpg


图片附件: [[原创,项目]6位LED绕线机计数器的原理图、C语言源代码、proteus仿真] yQAJAYaW.jpg (2008-11-12 00:43, 103.37 KB) / 下载次数 252
http://bbs.eccn.com/attachment.php?aid=5455&k=78c396dd617a59bbde426f25af47d3a5&t=1732228140&sid=lH1tD1


作者: zcllom    时间: 2008-11-12 01:13

最近正在搞这个东东,各种功能还没有完善,使用的单片机型号为PIC16F73,EEPROM型号为24LC02。数码管型号为共阴。原理是,利用PIC单片机的CCP模块捕捉光电编码器传送过来的脉冲信号进行计数,并且能够判断绕线轮盘是正转还是反转。设置的各种参数和记录的绕线圈数保存到24LC02中,这样掉电后,所有的参数和记录都不会丢失。
作者: zcllom    时间: 2008-11-12 01:26

源代码是由几个部分拼凑起来,其中一个重要的部分就是单片机对24LC02进行I2C总线读写,这部分是从一个例子中得到,但是原来的例子中有错误,原班不动地照抄到你自己的程序中去,就会发现单片机根本无法对24LC02读写。经过纠正,可以仿真通过了。纠正的地方我已经做了记号,也就是“!!!!!!!!!!!!”。

//24C02读写的C程序
//晶振对24C02影响特别大,排版要避开。
//试验证实必须接上拉电阻
//I2C 24LC02 C读写例程(PIC16F73单片机)

/*******************************************************************
一、程序说明:
1, 24LC02器件地址是1010000R/W.
2, 数组写入24LC02采取页写方式.
3, 数组code从24LC02读出时采取自由读方式.
4, 采用4.00M晶体。 (后来改成20M,所以延时参数有所调整。)
5,采用软件I2C。

二、硬件连接:
1, SDA------->15 pin.(当然你可以任意选择脚位)
2, SCL------->14 Pin.(当然你可以任意选择脚位)

*******************************************************************/
void start_i2c();
void stop_i2c();
void send_byte(uchar c);
uchar receive_byte();
void I_send_str(uchar sla,uchar suba,uchar *s,uchar no);
void delay_250ms();
void i2c_error ();

/*******************************************************************
起动总线函数
函数原型: void start_i2c();
Function: start on the I2C bus
*******************************************************************/
void start_i2c()
{
SDA=1; //发送启始条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop(); //24LC02要求建立时间大于4.7uS
SDA=0; //发送起始信号
nop();nop();nop();nop();nop();
SCL=0; //钳住I2C总线,准备发送数据或接收数据
nop();nop();
}

/*******************************************************************
停止总线函数
函数原型: void stop_i2c();
Function: stop the I2C bus
*******************************************************************/
void stop_i2c()
{
SDA=0; //发送结束条件的数据信号
nop();
SCL=1;
nop();nop();nop();nop();nop();
SDA=1;
nop();nop();nop();nop();
}

/*=================================================================
字节数据传送函数
函数原型: void send_byte(uchar c);
Function: 将数据C发送出去,可以是地址,也可以是数据,发完后等待回应,并对此状态
位进行操作(不应答或非应答都使ack=0 ),发送数据正常,ack=1;ack=0
表示被控器无应答或损坏。
==================================================================*/
void send_byte(uchar c)
{
uchar bit_count;
for (bit_count=0;bit_count<8;bit_count++)
{
if ((c<<bit_count)&0x80) {SDA=1;}
else {SDA=0;}
nop();
SCL=1;
nop();nop();nop();nop();nop();
SCL=0;
}
nop();nop();
SDA=1;
TRISC4=1; //SDA改成输入口!!!!!!!!!!!!!!!!!!!!!!!!!
nop();nop();
SCL=1;
nop();nop();nop();
if (SDA==1) ack=0;
else ack=1; //用ASK=1为有应答信号
SCL=0;
nop();
TRISC4=0; //SDA改成输出口!!!!!!!!!!!!!!!!
nop();nop();
}

/*==================================================================
字节数据接收函数
函数原型: uchar receive_byte();
FUNCTION: 用来接收从器件传来的数据,并判断总线错误(不发应答信号),
发完后请用应答函数。
===================================================================*/
uchar receive_byte()
{
uchar retc,bit_count;
retc=0;
SDA=1;
TRISC4=1; //SDA改成输入口!!!!!!!!!
for (bit_count=0;bit_count<8;bit_count++)
{
nop();
SCL=0;
nop();nop();nop();nop();nop();
SCL=1;
nop();nop();
retc=retc<<1;
if (RC4==1) retc=retc+1;
nop();nop();
}
SCL=0;
nop();nop();
TRISC4=0; //SDA改成输出口!!!!!!!!!!!!!!!!!!
return (retc);
}


/*================================================================
向有子地址器件发送多字节数据函数
函数原型: bit I_send_str(uchar sla,uchar suba,uchar *s,uchar no);
Function: 从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla。如果
返回1表示操作成功,否则操作有误。
=================================================================*/
void I_send_str(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
start_i2c();
send_byte(sla);
if (ack==0) i2c_error();
send_byte(suba);
if (ack==0) i2c_error();
for (i=0;i<no;i++)
{
send_byte(*s);
if (ack==0) i2c_error();
s++;
}
stop_i2c();
// return(1);
}

/*****************************************************************
延时函数
函数原型: void delay_250ms();
FUNCTION: 延明250ms
*****************************************************************/
void delay_250ms()
{
unsigned int d=24999;
while (--d);
}

/*****************************************************************
总线错误函数
函数原型: void i2c_error();
*****************************************************************/
void i2c_error ()
{
uchar i;
for (i=0;i<8;i++)
{
delay_250ms();
delay_250ms();
}

}


作者: zcllom    时间: 2008-11-12 01:29

定义、声明的头文件

#define uchar unsigned char
#define nop() asm("nop")
#define SCL TRISC3
#define SDA TRISC4

unsigned char sao_miao_LED; //数码管扫描记数
//unsigned char j; //数组传递控制变量
unsigned char A_PORT;
unsigned long ccp1_count,ccp2_count; //脉冲计数
unsigned long quan_shu[7]; //转过的圈数缓冲数组

unsigned char FLAG @ 0XEF;
#define FLAGIT(adr,bit) ((unsigned)(&adr)*8+(bit)) //绝对寻址位操作指令
static bit FLAG1 @ FLAGIT(FLAG,0); //按键对应的寄存器中的某位
static bit FLAG2 @ FLAGIT(FLAG,1);
static bit FLAG3 @ FLAGIT(FLAG,2);
static bit FLAG4 @ FLAGIT(FLAG,3);
static bit FLAG5 @ FLAGIT(FLAG,4);
static bit FLAG6 @ FLAGIT(FLAG,5);

unsigned char disbuffer[4]; //定义一个显示缓冲数组

uchar code[]={0x00,0x01,0x03,0x07,0x0f,0x1f,0x3f,0x7f,0xff};
uchar no,ack,c,data;

const unsigned char table[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//不带小数点的显示段码表
const unsigned char Local[13]={0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x10,0x11,0x12,0x13,0x14,0x15,0x16};//(12个数码管动态扫描 + 6个LED公共回路)位选控制字,

__CONFIG(XT&UNPROTECT&WRTEN&BORDIS&WDTDIS);


作者: zcllom    时间: 2008-11-12 01:31

/********************************************************************************************
* 文 件 名:main.c
* 功 能:绕线机计数器动态数码管显示
* 硬件条件:1.CPU型号:PIC16F73(SOP28脚)
* 2.晶振:20.000MHz
3.数码管:共阴
* 作 者:ZC
* 日 期:2008年10月1号
*********************************************************************************************/


#include <pic.h>
#include <stdio.h>
#include <math.h>

#include "DingYi.h"
#include "IIC.h"

//CCP模块工作于捕捉方式初始化子程序
void ccpint( )
{
CCP1CON=0X05; //首先设置CCP1 捕捉每个脉冲的上升沿
CCP2CON=0X05; //首先设置CCP2 捕捉每个脉冲的上升沿
PEIE=1; //外围中断允许(此时总中断关闭)
CCP1IE=1; //允许CCP1 中断
CCP2IE=1; //允许CCP2 中断
}

//PIC初始化
void picini(void)
{
ADCON1=0b00000110; //RA口作为数字量输入、输出通道!
TRISC=0Xff; //C口设为输入 RC3为SCL线,RC4为SDA线。
TRISB=0x00; //设置B口为输出方式,送字型到LED显示
TRISA=0b00100000; //设置A口的RA0~RA4为输出入方式,RA5为输入方式
INTCON=0x00; //禁止B口的中断功能(第二功能)
OPTION=0b11010110; //128分频
TMR1IE=1; //定时器1中断允许

}

void time0int(void)
{
T0CS=0; //TMR0工作于定时器方式
T0IF=0; //清除TMR0的中断标志
T0IE=1; //TMR0中断允许
GIE=1; //总中断允许
}

//中断服务程序
void interrupt time(void)
{

if (CCP1IF)
{
CCP1IF=0; //清除中断标志
ccp1_count++;
if(ccp1_count>=999999)
ccp1_count=0;
}

if (T0IE && T0IF) //判TMR0 中断
{
T0IF = 0; //清除TMR0 中断标志
PORTB = 0x00; //在此加入TMR0 中断服务
A_PORT = A_PORT&0xE0;
if(sao_miao_LED > 5) sao_miao_LED = 0;
PORTA = A_PORT|Local[sao_miao_LED];
PORTB = table[ quan_shu[sao_miao_LED] ];
sao_miao_LED++;

}


}


//***************************************************//
//把已经转过的圈数(十六进制数)转换成十进制数,并送到quan_shu[]中
//***************************************************//
void HexToDecimal(unsigned long Hexm)
{
quan_shu[5]= Hexm/100000; //十万位
quan_shu[4]= Hexm/10000%10; //万位
quan_shu[3]= Hexm/1000%10; //千位
quan_shu[2]= Hexm/100%10; //百位
quan_shu[1]= Hexm/10%10; //十位
quan_shu[0]= Hexm%10; //个位

}

main( )
{
uchar i;
ccpint( ); //CCP模块工作于捕捉方式初始化
picini( ); //系统其它部分初始化
time0int( );
CCP1IF=0; //清除CCP1的中断标志,以免中断一打开就进入中断
CCP2IF=0; //清除CCP2的中断标志,以免中断一打开就进入中断


while(1)
{

HexToDecimal(ccp1_count);

if(RA5==0)
{
I_send_str(0xa0,0x00,code,9); //页写入code数组到24LC02,器件地址为0Xa0,子地址为0X00,共9个数。
delay_250ms();
for (i=0x00;i<0x09;i++)
{
start_i2c();
send_byte(0xa0); //发送器件地址,即DEVICE ADDRESS。
if (ack==0) i2c_error(); //如果24LC02无应答。则进入I2C ERROR错误指示。
send_byte(i); //发送字地址,即WORD ADDRESS。D口显示数组。
if (ack==0) i2c_error();
start_i2c(); //重新启动总线。
send_byte(0xa1); //发送读命令和器件地址DEVICE ADDRESS。
if (ack==0) i2c_error();
data=receive_byte();
stop_i2c();
delay_250ms();
}
ei( );
}

}
}


作者: zcllom    时间: 2008-11-12 01:38

目前实现的功能就是CCP捕捉脉冲模块能记数了,也能通过I2C对24LC02进行读写了,数码管也可以显示圈数了。下一步的目标是,继续增加I2C读写的内容,实现判断电动机正转、反转的功能,正转时计数器显示值递加,反转时显示值递减,在停电前瞬间,检测到IO口的电压跌落,通过电解电容残存的电量,把记录值和各种人工设置的参数写到EEPROM芯片24LC02中。下次来电时,继续上次的记录进行记数。
作者: zcllom    时间: 2008-11-12 01:45

等各种功能都调通了,就把源代码,原理图,仿真文件传上来给大家下载。
作者: smofx    时间: 2008-11-20 09:36

期待.....
好人啊!!
[em02][em02]
作者: zcllom    时间: 2008-12-2 14:51

还是没有全部做完,发上来做个备份,以后有完整的就把这个覆盖。

长度计:

qwEoba55.rar (106.17 KB)

[此贴子已经被作者于2008-12-5 13:15:42编辑过]



附件: [[原创,项目]6位LED绕线机计数器的原理图、C语言源代码、proteus仿真] Ffu8rQAQ.rar (2008-12-2 14:31, 107.33 KB) / 下载次数 533
http://bbs.eccn.com/attachment.php?aid=5711&k=4833871f5697212de1475329fb0b5def&t=1732228140&sid=lH1tD1

附件: qwEoba55.rar (2008-12-5 12:56, 106.17 KB) / 下载次数 458
http://bbs.eccn.com/attachment.php?aid=5746&k=344b2e9d0a6dfcd7ae8074055a01e175&t=1732228140&sid=lH1tD1
作者: oyjpt    时间: 2009-3-30 19:08

很是期待

[em01][em01]
作者: cjcheng    时间: 2009-4-20 19:01

很是期待
作者: oyjpt    时间: 2009-5-20 23:24

老大什么时候能做完咯,很是期待啊[em59][em59]
作者: baggiotracy311    时间: 2010-3-25 10:05

高手啊~期待ING...
作者: hanyy1988    时间: 2010-4-16 21:16

高手啊,期待中




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0