嵌入式的智能电梯控制系统的设计与实现

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

湖南文理学院
课程设计报告
评阅意见:
评阅教师日期
目录
一,设计题目 (1)
二,设计要求 (1)
三,设计作用目的 (1)
四,所用设备及软件 (1)
五,系统总体设计方案及硬件设计方案 (2)
5.1电梯控制系统硬件设计方案 (2)
5.1.1电梯控制系统基本组成 (2)
5.1.2 电梯主控制器硬件设计总体规划 (4)
5.2 电机驱动模块 (5)
5.3显示模块 (6)
5.4开关控制模块 (7)
5.5报警模块 (8)
六,系统软件设计 (8)
6.1 电梯主控制器软件流程设计 (8)
6.2 电梯工作的锁梯模式 (10)
七,设计中的问题及解决方法 (13)
八,嵌入式系统学习心得 (14)
九,参考文献 (14)
十附录A系统硬件总体结构图 (16)
十一附录B 程序源代码 (17)
基于嵌入式的智能电梯控制系统的设计与实现一,设计题目
基于嵌入式的智能电梯控制系统的设计与实现
二,设计要求
完成一种应用于电梯控制系统中的新型、高效的嵌入式控制系统的软件和硬件设计。

三,设计作用目的
随着以嵌入式处理器为核心的智能电梯控制系统的飞速发展和普及,对电梯控制系统的主控制器在功能、实时性、可靠性和软件编程的灵活性提出了更多更高的要求。

考虑到这些情况,有必要在电梯控制系统中引入嵌入式实时操作系统为软件开发平台,可以选用源码公开、成熟的操作系统。

在电梯控制系统中使用嵌入式实时操作系统,可以将应用程序分解成多任务,简化了应用系统软件的设计。

使得电梯控制系统的实时性得到保证,而且良好的多任务设计,有助于提高系统的稳定性与可靠性。

四,所用设备及软件
1.采用32位ARM7芯片LPC2378作为电梯主控制器的微控制器;
2.目前常用的电梯控制系统中,通常是在存储器ROM中存储了几条固定的电梯速度曲线,电梯运行前,选择一条速度曲线运行。

而本文研制的电梯主控制可以生成多条电梯运行速度曲线,并根据楼层间距生成最佳的速度曲线,提高了电梯的运行效率与舒适感; 3.电梯控制系统的负载转矩补偿采用模糊控制技术,以提高电梯起动时的舒适感。

五,系统总体设计方案及硬件设计方案
系统总体结构框图如图1。

图1 系统总体结构框图
5.1电梯控?制系统硬件设计方案
5.1.1电梯控制系统基本组成
电梯控制系统的核心部件是安装在控制柜内的电梯主控制器与变频器。

它电机构成了
一个闭环控制系统。

主控制器主要完成呼梯指令的登记与分配、安全回路检查、故障检测与处理、电梯速度控制、电梯工作模式的控制等功能。

主控制器通过CAN串行总线通信的方式与轿厢控制器、楼层控制器、负载称重装置实现信息与数据的实时、有效交换。

主控制器采集到轿厢控制器和楼层控制器发送的外呼、内选等呼梯请求后,按程序制定的电梯控制策略,经过逻辑与算术运算,向变频器和门机发出相关速度指令与控制指令,将电梯派往相应楼层,实现电梯轿厢的垂直运动控制。

同时主控制器还要根据井道位置开关、急停回路反馈、和安全回路的反馈信号判断当前电梯的位置、安全和故障状态。

轿厢控制器主要实现内选呼梯信号、开关门信号、操纵盘等开关信号的采集,并根据主控制器的相关控制指令完成对到站钟、语音报站器的控制。

楼层控制器主要完成采集外呼请求,并实时显示电梯的楼层号等功能。

变频器的主要功能是实现电机的VVVF驱动,它根据主控制器的相应控制信号,实现对电机的运转控制。

其中,主控制器可通过模拟量方式(给定模拟电压输出量)或者数字量方式(又称为多段速)控制变频器,实现电机的速度控制。

编码器是电机的测速装置,是电梯控制系统的重要组成部件之一,光电式编码器将转动量转换成数字脉冲式的输出信号,它具有精度高、抗干扰能力强、可靠性高等优点。

通常,光电式编码器分为增量式编码器和绝对值编码器两种。

增量式编码器的数字输出量是相对于某个基准点的相对增加或减少量,通常输出三组方波脉冲,分别为A、B和Z相。

其中A、B两组脉冲相位差900,由此可分辨出被测装置的旋转方向,而对A相或者B相脉冲的计数,可确定转速或者角度,Z相每转输出一个脉冲,用于基准点定位。

它的优点是原理构造简单,精度高,价格较为便宜,缺点是断电后,丢失了参考点的位置。

绝对值编码器的每一个转动位置对应一个数字输出量,在断电后,参考点不会丢失绝对值编码器的输出方式有并行输出、串行输出、总线型输出等。

与增量式编码器相比,绝对值编码器的抗干扰特性、数据可靠性得到了较高,目前在工控定位装置中取得了广泛的应用,但绝对值编码器的成本相对较高。

编码器的脉冲输出信号通常并不能直接输送至变频器和电梯主控制器,而要经过脉冲监视输出卡(又称PG卡)转换后,反馈至变频器和电梯主控制器。

由于编码器可分为增量式编码器和绝对值编码器两种,因此为匹配不同类型的编码器,PG卡的型号也有所不同。

同时,不同的变频器将匹配各自不同的PG卡,例如安川L7B变频器可匹配PG.B2卡和PG.X2卡,而富士Lift型变频器可匹配OPC.LMl.PR卡和OPC.LMl.PP卡等。

电梯控制系统中,当选定了变频器的型号后,通常是根据编码器的型号来选择采用某种型号的PG卡,因为编码器安装在电机中,其安装和拆卸比较复杂,而PG卡安装在变频器内部,安装和拆卸比较简单。

本文研制的电梯控制系统要求PG卡送给主控制器的速度脉冲信号是两相增量式脉冲信号,而对编码器的型号没有特殊要求。

5.1.2 电梯主控制器硬件设计总体规划
电梯主控制器的硬件整体设计方案如图2所示。

图2 电梯主控制器的硬件整体设计
从硬件功能上划分,本文设计的嵌入式电梯主控制器可分为如下五个模块:1.微处理器模块:微处理器是该电梯主控制器的核心部件,是电梯主控制器的中央处理器。

本文采用了恩智浦公司新近推出的以ARM7TDMI.S为内核的32位RISC芯片LPC2378作为微处理器,依靠其强大的功能与丰富的片上硬件资源,简化了主控制器的硬件成本与软件实现的复杂度,也同时提高了其稳定性与可靠性。

2.电机驱动模块:电机驱动采用L297环形计数分配器和L298大功率步进电机驱动器完成。

3.报警模块:本设计采用8550三极管驱动蜂鸣器。

4.开关控制模块:开关控制模块采用4*4矩阵形式电路。

5.人机交互模块:它主要有液晶显示接口电路(本设计用数码管)与键盘电路组成,友好的人机交互接口将为电梯调试、维护人员在调试电梯过程中带来很大的便利性,也使得系统的维护更为方便。

5.2 电机驱动模块
图3 电机驱动模块
电机驱动采用L297环形计数分配器和L298大功率步进电机驱动器完成。

本次设计采用步进电机,目的是方便智能控制,可实现调速功能。

电机使用的是二相步进电机,由于仅用来实验,所以电机采用5V电源供电即可,实际中必须使用大电压来供电方能带动重物(人等)。

环形分配器L297引脚图如图4
图4 环形分配器L297引脚图
L297功能介绍:
SYNC为斩波器输出端,多个L297一起用时用此端口连接在一起共用一组时钟振荡;HPME端为集电极开路输出端;
A~D为四相输入端;
INIH1,INIH2为控制A~D相驱动,此引脚为低电平时A~D相禁止输入;
ENABLE端为使能输入端,低电平阻止电机驱动;
RESET为复位端;
HALF/FULL为半角全角控制端,高电平时选择半步输入;
CLOCK为时钟输入端,控制电机速度;
CW/CCW为方向控制端;
OSC为斩波器频率输入端;
SEN1和SEN2为电流检测端。

5.3显示模块
人机交互模块:它主要有液晶显示接口电路,本设计用数码管。

5.4开关控制模块
图6 开关控制模块
开关控制模块采用4*4矩阵形式电路。

5.5报警模块
本设计采用8550三极管驱动蜂鸣器。

当高电平时,三极管处于截止状态,三极管Vce 电压约为VCC,蜂鸣器只有很少电流流过,没法驱动其发声。

当低电平时,三极管处于饱和导通状态,三极管Vce约为0.3V,蜂鸣器有较大电流流过,能驱动其报警发声。

图7 报警模块
六,系统软件设计
6.1 电梯主控制器软件流程设计
电梯处于自动运行模式下的软件流程见图8。

图8 总体流程图
当电梯主控制器静止停靠在某一楼层时,其当前层的内选是被静止的,因此收到呼梯请求后,将首先判断是否为当前楼层的外呼请求,若是则开门,否则将呼梯请求登记到运行队列中,并将在门关闭后启动电梯运行。

在电梯启动前,将根据楼层间距生成速度曲线。

当电梯运行后,收到顺向截梯并满足换速的呼梯请求(内选、外呼)后,电梯将响应此请求,准备换速停靠。

当电梯换速过程中,到达目的楼层的门区后,若检测到双门区信号,则抱
闸停车,实现平稳停靠,并清除当前楼层的内选和相应外呼请求。

6.2 电梯工作的锁梯模式
特殊情形下,电梯工作的锁梯模下的运行流程如图9所示。

图9 电梯工作的锁梯模式
6.3 电梯的检修运行模式
检修运行模式是调试、安装、维护人员的专用模式。

当检修运行至上下限位时,电梯将抱闸停车,并且下次启动运行只可以向相反方向运行。

当检修运行前,若门锁未接通,收到检修运行指令后,电梯将自动关门,门关好后,电梯方可运行,如图10。

图10 电梯的检修运行模式
6.4 速度控制模块软件设计
主控制器对电梯速度的控制是一种间接控制的方式,它通过控制变频器,再由变频器实现对电机的速度控制。

主控制器对变频器的速度控制分为两种控制方式:多段速数字量控制、电压模拟量控制。

多段速数字量控制方式时,电梯的运行曲线完全由变频器产生,而电压模拟量控制时,电梯的运行曲线由主控制器生成。

本文研制的电梯主控制器可通过
设定参数,使用两种控制方式中的任何一种实现对电梯的速度控制。

在多段速数字量控制方式下,电梯主控制器控制变频器的速度指令是3个速度控制端子的二进制组合,每一个组合代表了~种速度。

模拟量控制方式下,速度曲线由主控制器产生,同时应当将变频器的相应速度曲线参数设定为0,否则电机的运行曲线将是主控制器产生的速度曲线和变频器原有的速度曲线共同作用的结果,这样就给调试电梯的运行舒适感和平层精度带来了不便。

本文中的电梯主控制器上有一个模拟量输出端口,它的输出电压范围是0至10V,其中,0V对应的是电机的零速,而10V对应电机的额定转速。

电梯速度曲线的设计原则是既要满足电梯快速性运行的要求,同时也要保证电梯运行时的舒适感,而电梯的快速性和舒适感则是一个矛盾的统一体。

由于电梯是一个频繁起动和制动的运送设备,它在起动的加速阶段和制动的减速阶段所耗费的时间往往在电梯的整个运行时间中占有很大的比重,因此缩短电梯的加速和减速时间,将会很大程度上减少电梯的运行时间,满足快速运行的要求,目前使用的电梯理想速度曲线按照加速度的变化方式通常可分为两种:梯形速度曲线和正弦速度曲线。

由于正弦速度曲线光滑可导,因此正弦速度曲线是一种较好的速度曲线。

但正弦速度的加速度和加加速度均是正弦函数,因此与梯形速度曲线相比,计算较为复杂,所以本文设计的速度曲线将以梯形速度曲线为基础,同时梯形速度曲线也是目前使用较为广泛的一种速度曲线。

一条典型的梯形速度曲线如图11所示。

曲线ABCD段是电梯的加速运行段,DE段是电梯匀速运行段,EFGHIJ是电梯的减速运行段。

在加速运行曲线ABCD段中,AB段和CD段是变加速运行段。

在减速运行曲线EFGHIJ段中,EF段、GH段和U段是变减速运行段,HI段是爬行段。

H点的运行速度是电梯的爬行速度Vp,同时本文中将AB、CD、EF、GH、U段的运行时间分别定义为Tl、T2、T3、T4、T5。

当电梯运行时,主控制器将首先计算至目的楼层的楼层间距,然后在电梯额定速度和单层运行速度(该速度可设置)之间选择一个最高的速度,使得该速度所对应的运行距离(它是启动距离和制动距离的和)小于或者等于楼层间距,而这个选定的速基于ARM技术的嵌入式电梯控制系统研制。

若不能找到这样的一个合适的速度,则需要重新调整曲线的参数设置,或者减小单层运行速度,再重新运行电梯。

图11 梯形速度曲线
七,设计中的问题及解决方法
本课题研制的嵌入式电梯控制系统将基于LPC2378的主控制器与变频器相结合作为电梯的驱动与控制核心,通过总线组成主控制器与轿厢控制器、楼层控制器等之间的实时通
信网络,它可应用在客梯、货梯、观光梯、医疗梯、消防梯等多种应用场合。

其中,主控
制器采用高性能的、主频可运行在72Mhz的ARM7芯片LPC2378作为核心控制器,提高了整个控制器的实时性、可靠性和稳定性,同时通过设置主控制器中的相关参数,它可与多款变频器相匹配,以驱动异步电机和目前应用广泛的同步电机。

文中在分析了电梯各运行模式的基础上,研究和阐述了电梯的控制策略,完成了电梯主控制器的软件设计。

本文详细的分析了电梯梯形速度曲线的数学模型。

但受限于专业的有限,有一些问题并未得到较好的解决,如在系统软件设计部分,如何较好实现各部分系统的功能?没有得到深入探究。

随着社会的发展,计算机技术的不断进步,电梯的发展趋势是适应智能化楼宇建筑的要求,实现高速高效、节能、环保运行。

蓝牙技术、指纹和身份识别技术、以太网技术等已逐渐的应用在电梯行业中。

同时,为实现多台电梯的节能和高效运行,电梯并联和群控技术也是研究的热点。

因此,本课题还有很多的内容可以研究,如利用LPC2378的片上以太网资源实现实现多台电梯的远程监控系统,利用LPC2378的第2个CAN控制器实现多台电梯的群控和并联等等。

总之,社会在不断发展,电梯控制技术也将不断的向前进步。

八,嵌入式系统学习心得
总体来说,本次课程设计的时间还是比较紧张,对我来说,这次的智能电梯控制系统设计有一定难度,但在老师和同学的帮助下我还是完成了。

首先感谢敖章洪老师对我的帮助与指导,敖章洪老师渊博的知识、和讲求实干的工作精神更是给我留下了深刻的印象,同时也向在我的课题研究的过程中给我帮助的同学表示衷心的感谢。

在这次课程设计中我学习和温习了一些专业知识,并且锻炼了自己的动手能力。

同时我们也熟悉了嵌入式实时操作系统软件和它的简单运用。

本次课程设计让我们收获良多。

由于本人设计水平有限,设计中错误在所难免,希望老师给予批评指正。

九,参考文献
[1] 彭克荣,电梯技术的现状及发展趋势[J].建筑机械化,2001.2,10-15.
[2]李惠异,电梯控制技术[M].机械工业出版社,2003:1-2.
[3]韩耀中,电梯的发展趋势及动态[J],2004,5.
[4]康华光等,电子技术基础(模拟部分)[M].高等教育出版社,2003:331.332.
[5]阳宪惠,现场总线技术及其应用[M].清华大学出版社,1999:309.310.
[6]刘载文,李惠舁,钟亚林,电梯控制系统[M].电子工业出版社,1996,
11:7.14.
[7]高国贤,马福军,电梯正弦运行速度曲线的分析与设计[J].自动化技术及应用,
2007,26,11:19-20.
【1】李惠异,电梯控制技术【M】.北京:机械工业出版社,2003:1-2.
【2】韩耀中,电梯的发展趋势及动态【J】.山西:大众标准化,2004,5.
【3】杜眷雷,ARM体系结构与编程【M】.北京:清华大学出版社,2003.
【4】康华光等,电子技术基础(模拟部分)【M】.北京:高等教育出版社,2003:331.332.【5】阳宪惠,现场总线技术及其应用【M】.北京:清华大学出版社,1999:309.310.【6】王黎明,夏立,邵英,闫晓玲,CAN现场总线系统的设计与应用【M】.北京:电
子工业出版社,2008:382.384.
十附录A系统硬件总体结构图
十一附录B 程序源代码
USR_STACK_LEGTH EQU 64
SVC_STACK_LEGTH EQU 0
FIQ_STACK_LEGTH EQU 16
IRQ_STACK_LEGTH EQU 64
ABT_STACK_LEGTH EQU 0
UND_STACK_LEGTH EQU 0
AREA Example5,CODE,READONLY ;
CODE32 ;
#include "config.h"
// 定义LED控制口
#define LED1_CON (1<<11)
#define LED2_CON (1<<12)
#define LED3_CON (1<<4)
#define LED4_CON (1<<6)
// 定义蜂鸣器控制口
#define BEEP (1<<10)
#define BEEP_MASK (~BEEP)
#define MOTOA (1<<5)
#define MOTOB (1<<6)
#define MOTOC (1<<7)
#define MOTOD (1<<0)
#define GPIOSET(PIN) rGPCDAT = rGPCDAT | PIN
#define GPIOCLR(PIN) rGPCDAT = rGPCDAT & (~PIN) //步进电机
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
void RunBeep(void)
{
rGPHDAT = rGPHDAT & BEEP_MASK; // BEEP = 0 DelayNS(5);
rGPHDAT = rGPHDAT | BEEP; // BEEP = 1
DelayNS(5);
}
void LED_DispAllOn(void)
{
rGPEDAT = rGPEDAT | (0x03<<11);
rGPHDAT = rGPHDAT | (0x05<<4);
}
void LED_DispAllOff(void)
{
rGPEDAT = rGPEDAT & (~(0x03<<11));
rGPHDAT = rGPHDAT & (~(0x05<<4));
}
void LED_DispNum(uint32 dat)
{
dat = dat & 0x0000000F; // 参数过滤
// 控制LED4、LED3显示(d3、d2位)
if(dat & 0x08) rGPHDAT = rGPHDAT | (0x01<<6);
else rGPHDAT = rGPHDAT & (~(0x01<<6));
if(dat & 0x04) rGPHDAT = rGPHDAT | (0x01<<4);
else rGPHDAT = rGPHDAT & (~(0x01<<4));
// 控制LED2、LED1显示(d1、d0位)
rGPEDAT = (rGPEDAT & (~(0x03<<11))) | ((dat&0x03) << 11);
}
int main(void)
{
int i;
rGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22); // rGPECON[25:22] = 0101b,设置GPE11、GPE12为GPIO输出模式
rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8); // rGPHCON[13:8] = 01xx01b,设置GPH4、GPH6为GPIO输出模式
rGPHCON = (rGPHCON & (~(0x03<<20))) | (0x01<<20); // rGPHCON[21:20] = 01b,设置GPH10为GPIO输出模式
// 控制LED指示0~F的16进制数值
for(i=0; i<16; i++)
{
LED_DispNum(i);
DelayNS(5);
}
}
return(0);
}
uint8 ledcon = 0x00;
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
void IRQ_Eint4(void)
{
int i;
rGPFCON = rGPFCON & (~(0x03<<8));
for(i=0; i<10000; i++);
if(rGPFDAT&KEY_CON)
{
rGPFCON = rGPFCON | (0x02<<8);
// 清除中断标志
rEINTPEND = (1<<4);
rSRCPND = (1<<4);
rINTPND = rINTPND;
return;
}
rGPFCON = rGPFCON | (0x02<<8);
if(ledcon)
{
ledcon = 0;
rGPEDAT = rGPEDAT & (~LED1_CON) ;
}
else
{
ledcon = 1;
rGPEDAT = rGPEDAT | LED1_CON;
}
// 清除中断标志
rEINTPEND = (1<<4);
rSRCPND = (1<<4);
rINTPND = rINTPND;
}
void EINT_init(void)
{
rGPFCON = (rGPFCON & 0xFFFFFCFF) | (0x02<<8);
rEXTINT0 = (0x2<<16);
VICVectAddr[4] = (uint32) IRQ_Eint4;
rPRIORITY = 0x00000000;
rINTMOD = 0x00000000;
rEINTMASK = ~0x0000010;
}
void LED_DispAllOff(void)
{
rGPEDAT = rGPEDAT & (~(0x03<<11));
rGPHDAT = rGPHDAT & (~(0x05<<4));
rGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22);
// rGPECON[25:22] = 0101b,设置GPE11、GPE12为GPIO输出模式rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8);
// rGPHCON[13:8] = 01xx01b,设置GPH4、GPH6为GPIO输出模式LED_DispAllOff(); // 熄灭LED1--LED4
EINT_init(); // 外部中断初始化
IRQEnable(); // 使能IRQ中断(清零CPSR寄存器的I位) while(1); // 等待外部中断
return(0);
}
void DelayNS(uint32 dly)
{
uint32 i;
for(; dly>0; dly--)
for(i=0; i<50000; i++);
}
void MOTO_Mode2(uint8 dly)
{
uint32 i;
for(i=0; i<20; i++)
{
// AB相有效
GPIOSET(MOTOA);
GPIOSET(MOTOB);
DelayNS(dly);
GPIOCLR(MOTOA);
GPIOCLR(MOTOB);
// BC相有效
GPIOSET(MOTOB);
GPIOSET(MOTOC);
DelayNS(dly);
GPIOCLR(MOTOB);
GPIOCLR(MOTOC);
// CD相有效
GPIOSET(MOTOC);
GPIOSET(MOTOD);
DelayNS(dly);
GPIOCLR(MOTOC);
GPIOCLR(MOTOD);
// DA相有效
GPIOSET(MOTOD);
GPIOSET(MOTOA);
DelayNS(dly);
GPIOCLR(MOTOD);
GPIOCLR(MOTOA);
}
}
int main(void)
{
// 步进电机控制口设置
rGPCCON = (rGPCCON & (~0x0000FC03)) | (0x00005401); // GPC0、GPC5--7口设置为输出
rGPCUP = rGPCUP | 0x00E1;
rGPCDAT = rGPCDAT & (~0x00E1);
while(1)
{
MOTO_Mode2(1); // 控制步进电机正转
DelayNS(50); // 停止步进电机,延时
}
return(0);
}
int main (void)
{
OSInit ();
OSTaskCreate (Task0,(void *)0, &Task0Stk[Task0StkLengh - 1], 2);
OSTaskCreate (Task1,(void *)0, &Task1Stk[Task1StkLengh - 1], 3);
OSStart ();
return 0;
}
void Task0 (void *pdata)
{
pdata = pdata;
TargetInit ();
// 初始化I/O
rGPECON = (rGPECON & (~(0x0F<<22))) | (0x05<<22); // rGPECON[25:22] = 0101b,
// 设置GPE11、GPE12为GPIO 输出模式
rGPHCON = (rGPHCON & (~(0x33<<8))) | (0x11<<8); // rGPHCON[13:8] = 01xx01b,
// 设置GPH4、GPH6为GPIO输出模式
rGPHCON = (rGPHCON & (~(0x03<<20))) | (0x01<<20); // rGPHCON[21:20] = 01b,
// 设置GPH10为GPIO输出模式while (1)
{
RunBeep();
OSTimeDly(OS_TICKS_PER_SEC);
}
}
void Task1 (void *pdata)
{ uint8 i;
pdata = pdata;
while (1)
{
for(i=0; i<16; i++)
{
LED_DispNum(i);
OSTimeDly(OS_TICKS_PER_SEC/2);
}
}
}
void RunBeep(void)
{
rGPHDAT = rGPHDAT & BEEP_MASK; // BEEP = 0
OSTimeDly(OS_TICKS_PER_SEC/10);
rGPHDAT = rGPHDAT | BEEP; // BEEP = 1
OSTimeDly(OS_TICKS_PER_SEC/10);
}
void LED_DispNum(uint32 dat)
{
dat = dat & 0x0000000F; // 参数过滤
// 控制LED4、LED3显示(d3、d2位)
if(dat & 0x08) rGPHDAT = rGPHDAT | (0x01<<6);
else rGPHDAT = rGPHDAT & (~(0x01<<6));
if(dat & 0x04) rGPHDAT = rGPHDAT | (0x01<<4);
else rGPHDAT = rGPHDAT & (~(0x01<<4));
// 控制LED2、LED1显示(d1、d0位)
rGPEDAT = (rGPEDAT & (~(0x03<<11))) | ((dat&0x03) << 11);
}
static int cs8900_recv(void)
{
u16 status,length;
printk("in cs8900_recv ->0\n");
status = cs8900_read (cs8900_base_addr,PP_RxStatus);
length = cs8900_read (cs8900_base_addr,PP_RxLength);
rxlen = length;
if (!(status & RxOK)) {
return 1;
}
printk("in cs8900_recv ->1\n");
cs8900_frame_read (cs8900_base_addr,krbuf,length);
up(&net_sem);
printk("in cs8900_recv ->2\n");
printk("recv length %d\n", length);
return 0;
}
static int cs8900_send(int length)
{
spinlock_t slock;
u16 status;
printk("in sending...\n");
spin_lock_irq(&slock);
cs8900_write (cs8900_base_addr,PP_TxCMD,TxStart (After5));
cs8900_write (cs8900_base_addr,PP_TxLength, length);
status = cs8900_read (cs8900_base_addr,PP_BusST);
if ((status & TxBidErr)) {
spin_unlock_irq(&slock);
printk (KERN_WARNING "%s: Invalid frame size!\n",DEVICENAME);
return (1);
}
if (!(status & Rdy4TxNOW)) {
spin_unlock_irq(&slock);
printk (KERN_WARNING "%s: Transmit buffer not free!\n",DEVICENAME); return (1);
}
cs8900_frame_write (cs8900_base_addr,ktbuf, length);
spin_unlock_irq(&slock);
printk("send length %d\n", length);
printk("out sending...\n");
return (0);
}
static irqreturn_t cs8900_irq_isr(int irq, void *dev_id, struct pt_regs *regs) {
volatile u16 status;
irqreturn_t handled = 0;
printk("into irq...\n");
//clearIrq();
while ((status = cs8900_read (cs8900_base_addr, PP_ISQ))) { handled = 1;
switch (RegNum (status)) {
case RxEvent:
printk("receive Event\n");
cs8900_recv();
break;
case TxEvent:
printk("send Event\n");
if (!(RegContent (status) & TxOK)) {
printk("send error\n");
}else{
printk("send success\n");
}
break;
case BufEvent:
printk("Buf Event\n");
break;
case TxCOL:
printk("TxCOL Event\n");
break;
case RxMISS:
printk("RxMiss Event\n");
break;
default:
printk ("interrupt not success!\n");
break;
}
printk ("out switch...\n");
}
printk ("out while...\n");
return IRQ_RETVAL(handled);
}
static int cs8900_probe(void)
{
int i,result;
u16 value;
spinlock_t slock;
u_char dev_addr[ETH_ALEN];
printk("into probe...\n");
dev_addr[0] = 0x00;
dev_addr[1] = 0x12;
dev_addr[2] = 0x34;
dev_addr[3] = 0x56;
dev_addr[4] = 0x78;
dev_addr[5] = 0x9a;
//dev_addr[5] = 0x9b;
spin_lock_init(&slock);
cs8900_base_addr = vSMDK2410_ETH_IO + 0x300;
net_irq = SMDK2410_ETH_IRQ;
if ((result = check_mem_region (cs8900_base_addr, 16))) {
printk (KERN_ERR "%s: can't get I/O port address 0x%lx\n", DEVICENAME, (unsigned long)cs8900_base_addr);
return (result);
}
request_mem_region (cs8900_base_addr, 16, DEVICENAME);
if ((value = cs8900_read (cs8900_base_addr,PP_ProductID)) != EISA_REG_CODE) {
printk (KERN_ERR "%s: incorrect signature 0x%.4x\n", DEVICENAME, value);
return (-ENXIO);
}
value = cs8900_read (cs8900_base_addr,PP_ProductID + 2);
if (VERSION (value) != CS8900A) {
printk (KERN_ERR "%s: unknown chip version 0x%.8x\n", DEVICENAME, VERSION (value));
return (-ENXIO);
}
cs8900_write (cs8900_base_addr,PP_IntNum,0);
/*setup Mac address*/
for (i = 0; i > 8));
}
printk ("\n");
return (0);
}
static ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {
down_interruptible(&net_sem);
printk("ready to copy_to_user...\n");
copy_to_user(buf, krbuf, rxlen);
printk("end to copy_to_user...\n");
printk("out read...\n");
return rxlen;
}
static ssize_t scull_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
printk("into write...\n");
copy_from_user(ktbuf, buf, count);
cs8900_send(count);
return 0;
int result;
//clearIrq();
//disable_irq(net_irq);
printk("into open...\n");
set_irq_type(net_irq, IRQT_RISING);
cs8900_set (cs8900_base_addr,PP_RxCFG,RxOKiE | BufferCRC | CRCerroriE | RuntiE | ExtradataiE);
cs8900_set (cs8900_base_addr,PP_RxCTL,RxOKA | IndividualA | BroadcastA | PromiscuousA);
cs8900_set (cs8900_base_addr,PP_TxCFG,TxOKiE | Out_of_windowiE | JabberiE);
cs8900_set (cs8900_base_addr,PP_BufCFG,Rdy4TxiE | RxMissiE | TxUnderruniE | TxColOvfiE | MissOvfloiE);
cs8900_set (cs8900_base_addr,PP_LineCTL,SerRxON | SerTxON);
cs8900_set (cs8900_base_addr,PP_BusCTL,EnableRQ);
cs8900_set (cs8900_base_addr,PP_RxCTL,MulticastA);
//FULL_DUPLEX
//cs8900_set (cs8900_base_addr,PP_TestCTL,FDX);
sema_init(&net_sem, 0);
udelay(1000);
if ((result = request_irq (net_irq, &cs8900_irq_isr, 0, DEVICENAME, NULL))
}。

相关文档
最新文档