Chinaunix首页 | 论坛 | 博客
  • 博客访问: 212377
  • 博文数量: 27
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 360
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-14 17:06
文章分类

全部博文(27)

文章存档

2011年(1)

2009年(5)

2008年(21)

我的朋友

分类: C/C++

2009-06-16 00:06:11

  两周的硬件课程设计终于落下帷幕,回顾一下,总结总结甚微收获。
  这两周着实没啥可说的,硬件嘛,让学软件的人来做,还是有些头大的。第一周是组成原理的设计,基本模型机以及指令扩展,也就是连一大堆乱糟糟的线路,细心点好了,没啥好说的。
  第二周的接口就有点意思了,不过,我做的不很好,但是还是有一些可以总结地方。其实,这两周,我还在忙着给老师做网站,并没有投入所有的精力去做它,另外,NBA的总决赛我也不想错过O(∩_∩)O~
  一开始,我本打算跟大家一样用汇编,老老实实、本本分分的做一个交差得了,反正还有其他事要忙。本来我是挺喜欢汇编的,可是,最终我却发觉自己的心还是不安分的,当大家都用起来汇编的时候,我却怎么也提不起用汇编的兴趣了。思前想后,我还是输给那不不安分的心:用C嵌入式汇编写。
  这个决定真的很冒险,万一写不出来,课程设计就完了,但我做这个决定的时候没想那么多,觉得反正是学习嘛(玩吧~)。更冒险的是,我把自己的想法告诉了老师,这连一点退路都不给自己留啊(后来才想到~)。
  因为实验箱只能连在windows下,不得已,只能用windows下的嵌入式汇编了。其实我还是更喜欢linux下的嵌入式汇编,功能更强大,用法更灵活。。
一、工具的选择:
  在windows下做,又是16位的汇编,肯定要用到虚拟DOS的cmd了,不过,在linux下混久了,我还真习惯了命令行操作。
  一些基本必要的dos命令: cd切换目录、dir浏览目录、mkdir创建目录、rmdir删除目录、del删除文件及目录、rename改名、start启动另一个cmd、copy拷贝文件、move移动文件等等,更多的大家到网上搜一下dos命令,更详细,这里我只介绍我这个过程中常用到得。。
  编译器:既然是十六位的,我也就选一个简单的好了,Turbo C 3.0
  汇编器:既然是嵌入式汇编当然还要有汇编器,只好是masm(5.0)了,汗`
  还有一样,我比较懒,不想在dos下敲一大堆编译的命令,于是又找了个windows下的make工程管理工具。
  好了,东西准备齐了,该做菜~\(≧▽≦)/~啦
二、编译平台的搭建:
  只是有些工具是成不了事的,得把平台搭建好,也就是要建一个“灶台”,不然,怎么烧菜啊。
  把masm和tc3的路径添加到系统环境变量里。吃力不讨好的办法是,每次进入cmd都设置一下,如:masm(d:\masm),tc3(d:\tc3\bin)
  则:set path=%path%;d:\masm;d:\tc3\bin; 
  想偷懒,其实是在找麻烦,不如直接设置到系统的环境变量里了,不用每次都敲那么长了。(设置系统环境变量,参照Java的设置方法,这里就不多赘言了)。
三、开始编程:
  设定好自己的共作目录,比如我的:d:\lzel,则可以mkdir d:\lzel
  按照大家喜好,搭建好平台后,先编一个hello world测试一下平台是否搭建好。
四、Hello world:
   程序:
 
 

#include
 
int main()
{
char *msg = "hello world!$";
 
asm mov ax,cs;
asm mov dx,ax;
asm mov es,ax;
asm mov dx,msg;
asm mov ah,9h;
asm int 21h;
getchar();
return 0;
}
 
编译:
tcc -B -Id:\tc3\include -Ld:\tc3\lib hello.c
 
有两点要注意:
1. -B参数:用于开启tc的处理嵌入式汇编的选项
2. 源文件目录下,必须有tasm.exe汇编器
五、接口实验之一——步进电机驱动程序:
这程序主要使用到8255器件,其中使用C口做输入,用于获取按键信息,用A口做输出,用于连接操作步进电机。
程序源代码:


#include
#include
#include
 
#define IOY3 0xC480
//0xE8C0
 
#define P8255_A IOY3+0x00*4   
#define P8255_B IOY3+0x01*4   
#define P8255_C IOY3+0x02*4   
#define P8255_MODE IOY3+0x03*4
 
#define SPEED 0x10
 
#define S0 SPEED*1
#define S1 SPEED*2
#define S2 SPEED*3
#define S3 SPEED*4
#define S4 SPEED*5
#define S5 SPEED*6
#define S6 SPEED*7
 
typedef enum {
RIGHT, /*0*/
LEFT /*1*/
}FLAG;
 
//gobal var
int buffer = 0x33;
FLAG flag = RIGHT;
 
//declare func
void outb(int addr,int mode);
int inb(int addr);
void display(char *msg);
int is_key(void);
void dly_speed(int speed);
void set_speed(int speed,FLAG flag);
void do_key(int key);
 
void outb(int addr,int mode)
{
    asm mov dx,addr;
    asm mov ax,mode;
    asm out dx,ax;
}
int inb(int addr)
{
    asm mov dx,addr;
    asm in al,dx;
    asm xor ah,ah;
    return (_AX);
}
void display(char *msg)
{
    asm mov dx,msg;
    asm mov ah,09h;
    asm int 21h;
}
int is_key(void)
{
    asm mov ah,06h;
    asm mov dl,0ffh;
    asm int 21h;
    asm je nokey;
    asm mov ax,1;
    return (_AX);
nokey:
    asm mov ax,0;
    return (_AX);
}
void dly_speed(int speed)
{
    asm mov dx,speed;
dly:
    asm mov cx,0ffffh;
lp:
    asm loop lp;
    asm dec dx;
    asm jnz dly;
}
void set_speed(int speed,FLAG flag)
{
    outb(P8255_A,buffer);
    if (flag == RIGHT) {
     asm {
         mov ax,buffer;
         ror al,1;
         mov buffer,ax;
     }
    } else {
     asm {
         mov ax,buffer;
         rol al,1;
         mov buffer,ax;
     }
    }
    printf("buffer = %x\n",buffer);
    dly_speed(speed);
}
void do_key(int key)
{
    int time = 0;
 
    if (key == 0)
    {
        buffer = 0x33;
        outb(P8255_A,buffer);
        return;
    } else {
        printf("key = %d\t",key);
        flag = ((key & 0x0080) == 0? RIGHT: LEFT);
        printf("flag = %d\t",flag);
        time = (key & 0x007f);
        printf("time = %d\t",time);
if (time&0x01) {
printf("time&0x01=%d S0\t",time&0x01);
         set_speed(S0,flag);
} else if (time&0x02) {
printf("time=%d S1\t",time);
         set_speed(S1,flag);
} else if(time&0x04) {
printf("time=%d S2\t",time);
          set_speed(S2,flag);
        } else if (time&0x08) {
          set_speed(S3,flag);
          printf("S3\t");
        } else if (time&0x10) {
          set_speed(S4,flag);
          printf("S4\t");
        } else if(time&0x20) {
          set_speed(S5,flag);
          printf("S5\t");
        } else if (time&0x40) {
          set_speed(S6,flag);
          printf("S6\t");
        } else {
          printf("time&0x02=%d\tstop\t",time&0x80);
        }
    }
}
int main()
{
    int c;
 
    outb(P8255_MODE,0x90); //init 8255
    outb(P8255_A,buffer); //init buffer = 33h
    while (!is_key()) {
        c = inb(P8255_C);
        do_key(0xc0);
    }
    return 0;
}

为了少敲一些命令,我写了一个Makefile文件用于编译管理,注意源代码文件名为bujinji.c
 
Makefile:

TARGET= bujinji
 
CC= tcc
CFLAGS= -B
TCDIR= D:\tc3
INCLUDE= $(TCDIR)\INCLUDE
LIB= $(TCDIR)\LIB
 
$(TARGET).exe: $(TARGET).obj
  $(CC) $(CFLAGS) -I$(INCLUDE) -L$(LIB) $(TARGET).obj
$(TARGET).obj: $(TARGET).c
  $(CC) $(CFLAGS) -I$(INCLUDE) -L$(LIB) -c $(TARGET).c
 
clean:
  @del bujinji.obj
 

 
也算是把嵌入式汇编的开发流程给探索出来了,应当能算得上这一周没白忙活吧,算是这周的收获吧。

感触:
1. 汇编并不难,只要基本指令知道,语法很简单。汇编的优势在于能直接硬件操作和代码执行效率高,编写难点是汇编的流程的布局。
2. C语言更贴近人们的思维,适合布局流程和开发算法。但C的高度平台可移植性决定的它不可能提供直接的硬件操作功能。
3. 嵌入式汇编把这二者的优点完美的结合在了一起。
4. 有意思,一周时间总算探索出来一些眉目了
 
阅读(2553) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~