单片机上机实验报告

单片机实验报告

                         班级: 041231                      

                         学号:  O(∩_∩)O~                      

                         姓名:雷锋

                实验一:数码管实验

一.实验目的

1.了解数码管的显示原理;

2.掌握JXARM9-2440 中数码管显示编程方法。

二.实验原理

7段LED由7个发光二极管按“日”字形排列,所有发光二极管的阳极连在一起称共阳极接法,阴极连在一起称为共阴极接法。

LED显示器的接口一般有静态显示与动态显示接口两种方式。本实验中采用的是动态显示接口,其中数码管扫描控制地址为0x20007000,位0-位5每位分别对应一个数码管,将其中某位清0 来选择相应的数码管,地址0x20006000 为数码管的数据寄存器。数码管采用共阳方式,向该地址写一个数据就可以控制LED 的显示,其原理图如图所示。

三.实验内容及步骤

1、六个数码管同时正向显示0-F ,然后反向显示F-0。

1) 参照模板工程leddemo(modules\leddemo\leddemo.apj),添加相应的文件,并修改led 的工程设置;

2) 创建led.c 并加入到工程led 中;

3) 编写LED 显示函数void led_display(void),正向显示0-F 然后反向显示F-0,并循环执行以上动作,在每次显示之间延时一段时间;

4) 编译led,成功后,下载并运行,观察结果。

2、在六个数码管上依次显示“HELLO”,可分辨出轮流显示。步骤同上。

3、在六个数码管上依次显示“HELLO”,分辨不出轮流显示。步骤同上。

4、在每个数码管上递增显示0-9 。步骤同上。

四.实验程序

1./*******************************************************************/

/*文件名称: LEDSEG7.C                                             */

/*实验现象: 数码管依次显示出0、1,2、……9、a、b、C、d、E、F               */

/*******************************************************************/

#define U8 unsigned char

unsigned char seg7table[16] = {

    /* 0       1       2       3       4       5       6      7*/

    0xc0,   0xf9,   0xa4,   0xb0,   0x99,   0x92,   0x82,   0xf8,

    /* 8       9      A        B       C       D       E      F*/

    0x80,   0x90,   0x88,   0x83,   0xc6,   0xa1,   0x86,   0x8e,

};

void Delay(int time);

/*******************************************************************/

/* 函数说明: JXARM9-2410 7段构共阳数码管测试                      */

/* 功能描述: 依次在7段数码管上显示0123456789ABCDEF               */

/* 返回代码: 无                                                   */

/* 参数说明: 无                                                   */

/*******************************************************************/

void Test_Seg7(void)

{   

    int i;    

 *((U8*)0x20007000)=0x00;       /*六个数码管都亮*/

  for( ; ;)

{

for(i=0;i<0x10;i++)       /*数码管从0到F依次显示出来*/

{

  *((U8*)0x20006000)=seg7table[i];

  Delay(1000);

}

for(0xf;i>=0x0;i--)      /*数码管从F到0依次显示出来*/

{

  *((U8*)0x20006000)=seg7table[i];

  Delay(1000);

}

}

// TODO

}

/*****************************************************************/

/* Function name : 循环延时子程序                                */

/* Description : 循环 'time' 次                                  */

/* Return type :void                                            */

/* Argument      : 循环延时计数器                                */

/*****************************************************************/

void Delay(int time)

{

    int i;

    int delayLoopCount=1000;

    for(;time>0;time--);

        for(i=0;i<delayLoopCount;i++);

}

实验结果:6个数码管上一次显示0,1,2…F,然后从F到0循环。

2./*******************************************************************/

/*文件名称: LEDSEG7.C                                             */

/*实验现象: 数码管依次显示出0、1,2、……9、a、b、C、d、E、F            */

/*******************************************************************/

#define U8 unsigned char

unsigned char seg7table[4]= {/*O L E H*/ 0xC0,0xC7,0x86,0x89};

void Delay(int time);

/*******************************************************************/

/* 函数说明: JXARM9-2410 7段构共阳数码管测试                      */

/* 功能描述: 依次在7段数码管上显示0123456789ABCDEF               */

/* 返回代码: 无                                                   */

/* 参数说明: 无                                                   */

/******************************************************************/

void Test_Seg7(void)

{

  for( ; ;)

  {

   *((U8*)0x20007000)=0x3E;     //**111110

   *((U8*)0x20006000)=seg7table[0];  //第一个数码管显示O

       Delay(1000);

    *((U8*)0x20007000)=0x3D;    //**111101

    *((U8*)0x20006000)=seg7table[1];  //第二个数码管显示L

        Delay(1000);

     *((U8*)0x20007000)=0x3B;    //**111011

     *((U8*)0x20006000)=seg7table[1];  //第三个数码管显示L

         Delay(1000);

      *((U8*)0x20007000)=0x37;    //**110111

      *((U8*)0x20006000)=seg7table[2];  //第四个数码管显示E

          Delay(1000);

       *((U8*)0x20007000)=0x2F;    //**101111

       *((U8*)0x20006000)=seg7table[3];  //第五个数码管显示H

           Delay(1000);

   }

}

// TODO

/*******************************************************************/

/* Function name : 循环延时子程序                                  */

/* Description : 循环 'time' 次                                    */

/* Return type :void                                               */

/* Argument      : 循环延时计数器                                  */

/*******************************************************************/

void Delay(int time)

 {

    int i;

    int delayLoopCount=1000;

    for(;time>0;time--);

        for(i=0;i<delayLoopCount;i++);

}

实验结果:从左到右一次显示HELLO,之间有明显延迟。

3./*******************************************************************/

/*文件名称: LEDSEG7.C                                             */

/*实验现象: 数码管依次显示出0、1,2、……9、a、b、C、d、E、F              */

/*******************************************************************/

#define U8 unsigned char

unsigned char seg7table[4]= {/*O L E H*/ 0xC0,0xC7,0x86,0x89};

void Delay(int time);

/*******************************************************************/

/* 函数说明: JXARM9-2410 7段构共阳数码管测试                      */

/* 功能描述: 依次在7段数码管上显示0123456789ABCDEF               */

/* 返回代码: 无                                                   */

/* 参数说明: 无                                                   */

/*****************************************************************/

void Test_Seg7(void)

{

  for( ; ;)

  {

   *((U8*)0x20007000)=0x3E;     //**111110

   *((U8*)0x20006000)=seg7table[0];  //第一个数码管显示O

       Delay(5);

    *((U8*)0x20007000)=0x3D;    //**111101

    *((U8*)0x20006000)=seg7table[1];  //第二个数码管显示L

        Delay(5);

     *((U8*)0x20007000)=0x3B;    //**111011

     *((U8*)0x20006000)=seg7table[1];  //第三个数码管显示L

         Delay(5);

      *((U8*)0x20007000)=0x37;    //**110111

      *((U8*)0x20006000)=seg7table[2];  //第四个数码管显示E

          Delay(5);

       *((U8*)0x20007000)=0x2F;    //**101111

       *((U8*)0x20006000)=seg7table[3];  //第五个数码管显示H

           Delay(5);

   }

}

    // TODO

/*******************************************************************/

/* Function name : 循环延时子程序                                 */

/* Description : 循环 'time' 次                                   */

/* Return type :void                                             */

/* Argument      : 循环延时计数器                                 */

/******************************************************************/

void Delay(int time)

{

    int i;

    int delayLoopCount=5;

    for(;time>0;time--);

        for(i=0;i<delayLoopCount;i++);

}

实验结果:数码管上显示HELLO,几乎无延迟,同时显示。

4./*****************************************************************/

/*文件名称: LEDSEG7.C                                           */

/*实验现象: 数码管依次显示出0、1,2、……9、a、b、C、d、E、F   */

/*****************************************************************/

#define U8 unsigned char

unsigned char seg7table[10]= {/*0,1,2,3,4,5,6,7,8,9*/ 0xc0,   0xf9,   0xa4,   0xb0,   0x99,   0x92,   0x82,   0xf8,0x80,   0x90};

void Delay(int time);

/******************************************************************/

/* 函数说明: JXARM9-2410 7段构共阳数码管测试                     */

/* 功能描述: 依次在7段数码管上显示0123456789ABCDEF              */

/* 返回代码: 无                                                  */

/* 参数说明: 无                                                  */

/*****************************************************************/

void Test_Seg7(void)

{ int i;

  for( ; ;)

  {

   *((U8*)0x20007000)=0x3E; 

   for(i=0;i<0x0A;i++)

  {

                                                       

   *((U8*)0x20006000)=seg7table[i]; 

       Delay(5000);

   }

    *((U8*)0x20007000)=0x3D;   

    for(i=0;i<0x0A;i++)

  {

                                                       

   *((U8*)0x20006000)=seg7table[i]; 

       Delay(5000);

   }

     *((U8*)0x20007000)=0x3B;   

      for(i=0;i<0x0A;i++)

  {

                                                       

   *((U8*)0x20006000)=seg7table[i]; 

       Delay(5000);

   }

      *((U8*)0x20007000)=0x37;   

       for(i=0;i<0x0A;i++)

   {

                                                       

   *((U8*)0x20006000)=seg7table[i]; 

       Delay(5000);

   }

       *((U8*)0x20007000)=0x2F;   

        for(i=0;i<0x0A;i++)

  {

                                                        

   *((U8*)0x20006000)=seg7table[i]; 

       Delay(5000);

   }

   }

}

// TODO

/*******************************************************************/

/* Function name : 循环延时子程序                                  */

/* Description : 循环 'time' 次                                    */

/* Return type :void                                              */

/* Argument      : 循环延时计数器                                  */

/*******************************************************************/

void Delay(int time) {

    int i;

    int delayLoopCount=10000;

    for(;time>0;time--);

        for(i=0;i<delayLoopCount;i++);

}

五.结果及分析

1.六个数码管同时显示,从0——F,接着从F——0反向显示。

分析:通过地址20007000选择哪个数码管亮,通过地址20006000决定数码管输出的内容。再通过循环可完成轮流显示。

2.可分辨出:从数码管的右边至左边依次显示hello

分辨不出:数码管上显示hello。

分析:由于改变了Delay的数值,导致频率变化,所以可以产生两种效果。

3.每个数码管递增显示0——9。

分析:原理同一,靠循环实现。

六.实验总结

1.由于数码管为共阳极,小数点为最高位,A为最低位,所以显示内容一定要计算正确。

2.循环条件要选择正确。

                  实验二:键盘输入实验

一.实验目的

1、学习键盘驱动原理;

2、掌握通过CPU的I/O扩展键盘的方法。

二.实验原理

键盘实现方案

采用专门的芯片实现键盘扫描

采用软件实现键盘扫描

软键盘实现方案

当开关打开时,通过处理器的I/O 口的一个上拉电阻提供逻辑1;当开关闭合时,处理器的I/O 口的输入将被拉低到逻辑0。

矩阵键盘电路

一个瞬时接触开关(按钮)放置在每一行与每一列的交叉点。每一行由一个输出端口的一位驱动,每一列由一个电阻器上拉且供给输入端口一位。

键盘扫描过程就是让微处理器按有规律的时间间隔查看键盘矩阵,以确定是否有键被按下

一旦处理器判定有一个键按下,键盘扫描软件将过滤掉抖动并且判定哪个键被按下

每个键被分配一个称为扫描码的唯一标识符。应用程序利用该扫描码,根据按下的键来判定应该采取什么行动,换句话说,扫描码将告诉应用程序按下哪个键

键盘扫描算法

初始化:所有的行(输出端口)被强行设置为低电平在没有任何键按下时,所有的列(输入端口)将读到高电平。

任何键的闭合将造成其中的一列变为低电平。

一旦检测到有键被按下,就需要找出是哪一个键。过程很简单,微处理器只需在其中一行上输出一个低电平。如果它在输入端口上发现一个0值,微处理器就知道在所选择行上产生了键的闭合

三、实验内容及步骤

(一)学习与分析例程中的各个程序以及主要函数,以进一步理解键盘的工作原理。

(二)获取按键值,在串口显示。

(三)使按键按照如图的顺序显示出来。

(四)将键盘按键值在数码管上显示。或自行开发。

四.实验程序:
1./* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 键盘实验主程序

//                    实现功能:

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---键盘测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

      

    /* 开始回环测试 */

       while(1)

       {

              unsigned char ch;

              ch=Key_GetKeyPoll();

             

              // TODO

              // 获取键值

             

              if(ch != 0)

              {

      

             

                     PRINTF("\r'%c'键按下", ch);

              }

       }

}

实验结果:在小键盘上按键,串口上显示按键对应字符,如按0,串口上显示0。

2.在库函数中改变如下的key按键值,使对应于键盘上的位置

char key_get_char(int row, int col)

{

       char key = 0;

      

       switch( row )

       {

       case 0:

              if((col & 0x01) == 0) key = 'D';

              else if((col & 0x02) == 0) key = 'E';

              else if((col & 0x04) == 0) key = 'F';

              else if((col & 0x08) == 0) key = '0';

              break;

       case 1:

              if((col & 0x01) == 0) key = 'C';

              else if((col & 0x02) == 0) key = '7';

              else if((col & 0x04) == 0) key = '4';

              else if((col & 0x08) == 0) key = '1';

              break;

       case 2:

              if((col & 0x01) == 0) key = 'B';

              else if((col & 0x02) == 0) key = '8';

              else if((col & 0x04) == 0) key = '5';

              else if((col & 0x08) == 0) key = '2';

              break;

       case 3:

              if((col & 0x01) == 0) key = 'A';

              else if((col & 0x02) == 0) key = '9';

              else if((col & 0x04) == 0) key = '6';

              else if((col & 0x08) == 0) key = '3';

              break;

     }

}

实验结果:按下键盘的按键串口会按题图中所示对应显示

3./* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

#include <stdio.h>

#include <math.h>

#define IIRNUMBER 2

#define U8 unsigned char

unsigned char table[16] = {

    /* 0       1       2       3       4       5       6      7*/

    0xc0,   0xf9,   0xa4,   0xb0,   0x99,   0x92,   0x82,   0xf8,

    /* 8       9      A        B       C       D       E      F*/

    0x80,   0x90,   0x88,   0x83,   0xc6,   0xa1,   0x86,   0x8e,

};

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2440 键盘实验主程序

//                    实现功能:

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

 ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---键盘测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

      

/*    *((unsigned long int *)0x48000000) = 0x22111120;

       *((unsigned long int *)0x4800000c) =  0x7ffc;

       while(1){

              *((unsigned short int *)0x10000000) = 0x0;

              for(i=0;i<1000;i++)

                     ;

              *((unsigned short int *)0x10000000) = 0xffff;

              for(i=0;i<1000;i++);

       }

*/

    /* 开始回环测试 */

   

   

   int  j=0,k=0;  

   unsigned char table1[6] = {0x1F,0x2F,0x37,0x3B,0x3D,0x3E};

       while(1)

       {

              unsigned char ch;

              ch = Key_GetKeyPoll();

              if(ch != 0)

              {

                     PRINTF("\r'%c'键按下", ch);

              }

             

if(k<6)  *((U8*) 0x20007000)=table1[k];

if(k==6)  k=0;

             

                     switch(ch)

                     {

                    

case '0':

                     j=0;

            *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

                    

case '1':

                     j=1;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++; 

                  break;

                     case '2':

                     j=2;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                     break;

case '3':

                     j=3;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                     break;

                     case '4':

                     j=4;

*((U8*) 0x20006000) = table[j];

//Delay (20);

                  k++; 

                     break;

                  case '5':

                     j=5;

                     *((U8*) 0x20006000) = table[j];

//Delay (20);

                  k++;

                     break;

case '6':

                     j=6;

                     *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

                 

                 

case '7':

                     j=7;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

case '8':

                     j=8;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

case '9':

                     j=9;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

  case 'A':

                     j=10;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

case 'B':

                     j=11;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                   break;

case 'C':

                     j=12;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

                 

case 'D':

                     j=13;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

case 'E':

                     j=14;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

case 'F':

                     j=15;

                  *((U8*) 0x20006000) = table[j];

                  //Delay (20);

                  k++;

                  break;

                  default :break;

                     }                       

/****************************************************************************/

/* Function name : 循环延时子程序                                           */

/* Description : 循环 'time' 次                                             */

/* Return type :void                                                       */

/* Argument      : 循环延时计数器                                           */

/****************************************************************************/

void Delay(int time) {

    int i;

       int delayLoopCount=1000;

    for(;time>0;time--);

              for(i=0;i<delayLoopCount;i++);

}           

       }

}

实验结果:在键盘上按下按键,会显示在数码管上。

                            实验三:中断实验

一、实验目的

         1、了解中断的作用;

         2、掌握嵌入式系统中断的处理流程;

         3、掌握ARM中断编程。

二、实验原理

当CPU进行主程序操作时,外设的数据已存入输入端口的数据寄存器;或端口的数据输出寄存器已空,由外设通过接口电路向CPU发出中断请求信号,CPU在满足一定的条件下,暂停执行当前正在执行的主程序,转入执行相应能够进行输入/输出操作的子程序,待输入/输出操作执行完毕之后CPU再返回并继续执行原来被中断的主程序。这样CPU就避免了把大量时间耗费在等待、查询状态信号的操作上,使其工作效率得以大大地提高。

三、实验内容及步骤

(一)学习例程,对其关键程序与设置进行分析。

(二)编写中断处理程序,处理外部中断2,3,控制LED灯闪烁或数码管显示。

1、当外部中断2发生时,使8个LED在亮灭间切换;

2、当外部中断3发生时,使8个LED等依次亮一下。

*3、当中断发生时,控制数码管显示。

四.试验程序

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* functions */

void eint2_isr(void) __attribute__ ((interrupt("IRQ")));;

void eint3_isr(void) __attribute__ ((interrupt("IRQ")));;

void delay();

/* variables */

int dither_count2 = 0;

int dither_count3 = 0;

static int nLed = 0;

/*****************************************************************************

// Function name    : Main

// Description      : JXARM9-2410 中断实验主程序

//                    完成功能:

//                        外部中断按键引发中断

// Return type         : void

// Argument         : void

*****************************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

      

       /* 中断初始化 */

    Isr_Init();

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

    /* 打印提示信息 */

       PRINTF("\n---外部中断测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n外部中断测试开始\n");

       /* 请求中断 */

       Irq_Request(IRQ_EINT2, eint2_isr);               //中断选择

    //Irq_Request(IRQ_EINT3, eint3_isr);

    /* 使能中断 */

    Irq_Enable(IRQ_EINT2);

    //Irq_Enable(IRQ_EINT3);

   

    dither_count2 = 0;

    dither_count3 = 0;

    while(1)

    {

           delay();

           dither_count2++;

           dither_count3++;

    }

}

/*****************************************************************************

// Function name    : eint2_isr

// Description      : EINT2中断处理程序

// Return type         : int

// Argument         : void

*****************************************************************************/

void eint2_isr(void)

{

       Irq_Clear(IRQ_EINT2);       

    if(dither_count2 > 10)

    {

            dither_count2 = 0;

      

       (*(U8*)0x20007000)=0x0;                         //中断发生时,数码管显示

       (*(U8*)0x20006000)=0x80;

      

       (*(U8*)0x20005000)=nLed;                       //LED亮灭切换

       nLed=~nLed;

       }

}

/*****************************************************************************

// Function name    : eint3_isr

// Description      : EINT3中断处理程序

// Return type         : int

// Argument         : void

*****************************************************************************/

void eint3_isr(void)

{

       Irq_Clear(IRQ_EINT3);       

    if(dither_count3 > 10)

    {

            dither_count3 = 0;

           

       (*(U8*)0x20007000)=0x0;                                       //中断发生时,数码管显示

       (*(U8*)0x20006000)=0x90;

      

       (*(U8*)0x20005000)=0x01;delay();                          //LED依次亮一下

       (*(U8*)0x20005000)=0x02;delay();

       (*(U8*)0x20005000)=0x04;delay();

       (*(U8*)0x20005000)=0x08;delay();

       (*(U8*)0x20005000)=0x10;delay();

       (*(U8*)0x20005000)=0x20;delay();

       (*(U8*)0x20005000)=0x40;delay();

       (*(U8*)0x20005000)=0x80;delay();

       }

}

void delay()

{

       int index = 0;

      

       for ( index = 0 ; index < 20000; index++);

}

五.结果及分析

1.中断2发生时,LED亮灭切换。

2.中断3发生时,LED从右依次亮灭。

3.中断发生,数码管显示数字。

分析:加入中断使能语句,可使中断2和中断3发生,LED的地址为20005000,其余和之前原理相同,在中断语句部分里面加入。

六.实验总结

1.同时只能有一个中断发生,注意中断间的切换。

                             实验四:A/D实验

一.实验原理

1.了解模数转换的基本原理。

2.掌握模数转换的编程方法。

二.实验原理

       要将模拟量转换成数字信号需经采样——>量化——>编码三个基本过程(数字化过程)。

(1)采样:按采样定理对模拟信号进行等时间间隔采样,将得到的一系列时域上的样值去代替u=f(t),即用u0、u1、…un代替u=f(t)。这些样值在时间上是离散的值,但在幅度上仍然是连续模拟量。

 

(2)量化:

在幅值上再用离散值来表示。方法是用一个量化因子Q去度量u0、u1、…,便得到整量化的数字量。

       u0=2.4Q 2Q

       u1=4.0Q 4Q

       u2=5.2Q 5Q

       u3=5.8Q 5Q

(3)编码:

将整量化后的数字量进行编码,以便读入和识别;编码仅是对数字量的一种处理方法。

例如:Q=0.5V/格,设用三位(二进编码)

    

通道0和通道1的模拟输入信号可通过实验箱的可调电阻AIN0、AIN1调节。

三.实验内容及步骤

(一)学习例程,对其关键程序与设置进行分析。

(二)

1、通过可变电阻改变模拟量输入,补充程序将模拟输入进行采集和转换,观查显示结果(在串口显示);

2、将转换后的电压值结果显示在LED上和串口上(如2.345)。

3、 自行开发。

步骤:

1) 参照模板工程ad(modules\ad\ad.apj),新建一个工程ad,添加相应的文件,并修改ad的工程设置;创建main.c 并加入到工程ad 中;

2) 根据内容编程;

3) 编译、链接、调试、运行。

四.实验程序

1./* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 A/D采样实验主程序

//                    实现功能:

//                        实现JXRAM9-2410的模数转换

//                        JXARM9-2410 UART0 <==> PC COM

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---AD采样程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n从现在开始您将在超级终端上看到采样值,旋动旋钮AIN2和AIN3改变模拟输入\n");

      

    /* 开始测试 */

    Test_Adc();

       while(1)

       {

       }

}

#define ADC_FREQ 2500000

int ReadAdc(int ch);              //Return type is int, Declare Prototype function

//==================================================================================

void Test_Adc(void)

{

    int i;

    int a0=0,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0; //Initialize variables

    float b0,b1;

    PRINTF("----------AD测试--------\n");

    PRINTF("旋动AIN0, AIN1旋钮改变模拟输入,任意键退出\n");

       

    while(1)

    {a0=Adc_Get_Data(0,ADC_FREQ);

     a1=Adc_Get_Data(1,ADC_FREQ);

     b0=(float)a0/1024*3.3;

     b1=(float)a1/1024*3.3;

              // TODO

           PRINTF("\rAIN0: %04d AIN1: %04d", a0,a1);

           PRINTF("\U0: %04f U1: %04f", b0,b1);

    }

    rADCCON=(0<<14)|(19<<6)|(7<<3)|(1<<2);  //stand by mode to reduce power consumption      

       PRINTF("\n");

    PRINTF("--------AD测试结束------\n\n");

}

2./* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 A/D采样实验主程序

//                    实现功能:

//                        实现JXRAM9-2410的模数转换

//                        JXARM9-2410 UART0 <==> PC COM

// Return type         : void

// Argument         : void

*********************************************************************/

float ADchange(int data);

void TestAdc(void);

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---AD采样程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n从现在开始您将在超级终端上看到采样值,旋动旋钮AIN2和AIN3改变模拟输入\n");

    /* 开始测试 */

    TestAdc();

       while(1)

       {

       }

}

#define ADC_FREQ 2500000

int ReadAdc(int ch);              //Return type is int, Declare Prototype function

//==================================================================================

void TestAdc(void)

{

       int j = 0;

    int i = 0;

       float A0,A1;

       int LedShow;

       int show[6] = {0};

       unsigned char segtable[10] =

       {

    /* 0       1       2       3       4       5       6      7*/

    0xc0,   0xf9,   0xa4,   0xb0,   0x99,   0x92,   0x82,   0xf8,

    /* 8       9   */

    0x80,   0x90 };

       unsigned char segtable1[4] = {0x40,0x79,0x24,0x30};

    int a0=0,a1=0,a2=0,a3=0,a4=0,a5=0,a6=0,a7=0; //Initialize variables

       PRINTF("----------AD测试--------\n");

    PRINTF("旋动AIN0, AIN1旋钮改变模拟输入,任意键退出\n");

    

  

   

    while(1)

    {

              a0 = Adc_Get_Data(0, ADC_FREQ);

              a1 = Adc_Get_Data(1, ADC_FREQ);

              PRINTF("\rAIN0: %04d AIN1: %04d\n", a0, a1);

              A0 = ADchange(a0);

              A1 = ADchange(a1);

              PRINTF("\rvoltage-->AIN0: %05f AIN1: %05f\n", A0, A1);

              LedShow = (int)(A0*100000);

              show[0] = LedShow%10;

              show[1] = LedShow/10%10;

              show[2] = LedShow/100%10;

              show[3] = LedShow/1000%10;

              show[4] = LedShow/10000%10;

              show[5] = LedShow/100000%10;

             

              //Led 动态显示

             

              for( j = 0;j < 100;j++)

              {

                     *((unsigned char *)0x20007000) = ~(1 << i) & 0x3f;

                     if(i<5)

                            *((unsigned char *)0x20006000) = segtable[show[i]];

                     if(i==5)

                            *((unsigned char *)0x20006000) = segtable1[show[5]];

                     i++;

                     i %= 6;

                     Delay(1);

              }

    }

    rADCCON=(0<<14)|(19<<6)|(7<<3)|(1<<2);  //stand by mode to reduce power consumption      

       PRINTF("\n");

    PRINTF("--------AD测试结束------\n\n");

}

float ADchange(int data)

{

       float result;

       float per;

       per = 3.3/1024;

       result = per*data;

      

       return result; 

}

五.结果及分析

1.扭动旋钮改变电阻,串口上输出模拟量及转换后的输出电压值。

2.转换后的电压值在数码管上显示。

                            实验五:系统时钟实验

一、实验目的

了解实时时钟在嵌入式系统中的作用;

掌握实时时钟的使用。

二、实验原理

在一个嵌入式系统中,实时时钟单元可以提供可靠的时钟,包括时分秒和年月日;即使在系统处于关机状态下它也能够正常工作(通常采用后备电池供电)。

三、实验内容及步骤

(一)学习与分析实验例程,学习时钟寄存器的设置;

(二)

        1、补充程序,设置与修改当前的日期和时间;实现闹钟告警功能(设05S时报警),使能秒时钟告警 ;

        2、将时分秒在数码管上显示出来。

四.实验程序

1./* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* 表示日期、时间的数据结构 */

typedef struct ST_DATE

{

       short      year;       // 年

       char mon;        // 月

       char day;        // 日

       char week_day;   // 星期

       char hour;       // 时

       char min;        // 分

       char sec;        // 秒

} st_date;

void display();

void delay(int time);

extern unsigned char seg7table[16];

unsigned char loc[6]={

  /* 从左到右的数码管位选 */

  0x1f,0x2f,0x37,0x3b,0x3d,0x3e};

/* 全局变量 */

int led_index = 0;

int ext0_count = 0;

int table[6]={0};

/* functions */

void rtc_tick_isr(void) __attribute__ ((interrupt("IRQ")));;

void rtc_int_isr(void) __attribute__ ((interrupt("IRQ")));;

/*****************************************************************************

// Function name    : rtc_set_date

// Description      : 修改实时时钟当前时间、日期

// Return type         : void

// Argument         : p_date, 待设置的日期

*****************************************************************************/

void rtc_set_date(st_date* p_date)

{

    rRTCCON  = 0x01;     

    rBCDYEAR = p_date->year;

    rBCDMON  = p_date->mon;

    rBCDDAY  = p_date->day;

    rBCDDATE = p_date->week_day;

    rBCDHOUR = p_date->hour;

    rBCDMIN  = p_date->min;

    rBCDSEC  = p_date->sec;

    rRTCCON  = 0x00;     

}

/*****************************************************************************

// Function name    : rtc_get_date

// Description      : 获取实时时钟当前时间、日期

// Return type         : void

// Argument         : p_date, 返回日期的指针

*****************************************************************************/

void rtc_get_date(st_date* p_date)

{

    rRTCCON  = 0x01;     

   

    p_date->year   =    rBCDYEAR ;

    p_date->mon         =    rBCDMON  ;

    p_date->day           =    rBCDDAY  ;

    p_date->week_day=      rBCDDATE ;

    p_date->hour  =    rBCDHOUR ;

    p_date->min          =    rBCDMIN  ;

    p_date->sec           =    rBCDSEC  ;

   

    rRTCCON  = 0x00;     

}

/*****************************************************************************

// Function name    : rtc_tick_init

// Description      : 初始化S3C2410的TICK定时器

// Return type         : void

// Argument         : tick, 设置的TICK频率(时钟滴答的周期为 (1+tick)/128秒)

*****************************************************************************/

void rtc_tick_init( char tick )

{

    Irq_Request(IRQ_TICK, rtc_tick_isr);

   

    rRTCCON   = 0x0;            //No reset[3], Merge BCD counters[2], BCD clock select XTAL[1], RTC Control disable[0]

    rTICNT  = (tick&0x7f)|0x80;             /*TICK 中断使能,周期为(1+tick)/128秒*/  

    Irq_Enable(IRQ_TICK);  

}

/*****************************************************************************

// Function name    : rtc_alarm_set

// Description      : 设置S3C2410的告警时间以及方式

// Return type         : void

// Argument         : p_date, 告警的时间

//                    mode, 告警模式

*****************************************************************************/

void rtc_alarm_set(st_date* p_date, unsigned char mode)

{

    Irq_Request(IRQ_RTC, rtc_int_isr);

   

    rRTCCON  = 0x01;     

   

    rALMYEAR = p_date->year;

    rALMMON  = p_date->mon;

    rALMDATE = p_date->day;

    rALMHOUR = p_date->hour;

    rALMMIN  = p_date->min;

    rALMSEC  = p_date->sec;

   

    rRTCALM  = mode;

   

    rRTCCON  = 0x00;     

    Irq_Enable(IRQ_RTC);  

}

/*****************************************************************************

// Function name    : Main

// Description      : JXARM9-2410 实时时钟实验主程序

//                    完成功能:

//                        时钟滴答:每秒钟刷新数码管显示

//                        设置当前日期、时间

//                        动态刷新当前日期、时间,通过串口打印出来

//                        时间告警功能:每分钟的第5秒告警,并进行跑马灯显示

// Return type         : void

// Argument         : void

*****************************************************************************/

void Main(void)

{

       int old_index ;

      

       st_date m_date;

      

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

      

       /* 中断初始化 */

    Isr_Init();

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

    /* 打印提示信息 */

       PRINTF("\n---实时时钟测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n实时时钟测试开始\n");

       /* 采用BCD编码,如20##年需要设置的值为0x2004 */

       // TODO

      

      m_date.year = 0x15;

  m_date.mon = 0x05;

  m_date.day = 0x07;

  m_date.week_day = 0x03;

  m_date.hour = 0x02;

  m_date.min = 0x59;

  m_date.sec = 0x52;

    /* 修改当前日期和时间 */

    rtc_set_date(&m_date);

   

    m_date.sec             =    0x05 ;    //设置报警时间

   

       // TODO

    /* 设置告警的时间及方式,0x41表示使能RTC告警,以及使能秒时钟告警 */

        rtc_alarm_set(&m_date,0x41);

       rtc_tick_init(127);

      

       old_index = led_index;

     PRINTF("\r\n\r\n");

    

    while(1)

    {

           if(old_index != led_index)           /* 每隔一秒更新一次数据                        */

           {

                rtc_get_date(&m_date);

                old_index = led_index;

                      exchange(&m_date);

              display();

                PRINTF(                      /* 时钟数据为BCD码格式,以16进制显示 */

                            "\b\b\b\b\b\b\b\b%02x:%02x:%02x", m_date.hour, m_date.min, m_date.sec);

         }

    };

}

/*****************************************************************************

// Function name    : rtc_tick_isr

// Description      : TICK中断处理程序,程序中设置每秒钟引发一次中断

// Return type         : int

// Argument         : void

*****************************************************************************/

void rtc_tick_isr(void)

{

       Irq_Clear(IRQ_TICK);         /* 清除TICK中断 */

//     *((unsigned char*) 0x02000006) = 0x00;    

//    *(unsigned char*)0x02000004 = seg7table[led_index%10]; 

    

     led_index++;

}

/*****************************************************************************

// Function name    : rtc_int_isr

// Description      : rtc中断处理程序,程序中设置每分钟的第5秒引发该中断

// Return type         : int

// Argument         : void

*****************************************************************************/

void rtc_int_isr(void)

{

       Irq_Clear(IRQ_RTC);          /*清除RTC中断                                       */

   

//    if(ext0_count&1)

//                 *(unsigned char*)0x2000000 = 0x0f; 

//          else

//                 *(unsigned char*)0x2000000 = 0xff; 

           

     ext0_count++;

    

     PRINTF("\r\nAlarm\r\n                  ");

    

}

/**********************************************************************

 //name:         exchange

 //description:  将BCD码转化为数组形式

 //return type:  void

 //argument:     p_data

***********************************************************************/

int exchange(st_date* p_date) {

  table[0]=(p_date->hour & 0xf0)>>4;

  table[1]=p_date->hour & 0x0f;

  table[2]=(p_date->min & 0xf0)>>4;

  table[3]=p_date->min & 0x0f;

  table[4]=(p_date->sec & 0xf0)>>4;

  table[5]=p_date->sec & 0x0f;

}   /*end for exchange*/

/**********************************************************************

 //name:         display

 //description:  数码管显示

 //return type:  void

 //argument:     void

***********************************************************************/

void display()

{

  int i,count=90;                       // 调节count使显示正好在1s内

  while(count--) {

    for(i=0;i<6;i++) {

      *((U8*)0x20007000)=loc[i];

      *((U8*)0x20006000)=seg7table[table[i]];        /*调用数组str1*/

      delay(1);

    }

  }

  *((U8*)0x20007000)=0x3f;              // 关数码管

}   /*end for display*/

/*******************************************/

/* Function name: 循环延时子程序

/* Description: 循环‘time’次

/* Return type: void

/* Input type: int time

/* Argument: 循环延时计数器

*/

/*******************************************/

void delay(int time) {

  int i;

  int delayLoopCount=1000;

  for(;time>0;time--)

    for(i=0;i<delayLoopCount;i++);

}   /*end for delay*/

五.结果及分析

1.运行程序,串口和数码管会显示时间,但是不同步,当每分钟的第三秒,串口显示报警。

六.实验总结

1.由于延迟或者其他原因,串口时间与数码管时间不同步,而且报警时间与预期的也不同步。

                             实验六:看门狗实验

一.实验目的

1.了解WATCHDOG的作用。

2.掌握WATCHDOG定时器的使用方法。

二.实验原理

       看门狗定时器(WDT,Watch Dog Timer)是单片机的一个组成部分,它实际上是一个计数器,一般给看门狗一个大数,程序开始运行后看门狗开始倒计数。如果程序运行正常,过一段时间CPU应发出指令让看门狗复位,重新开始倒计数。如果看门狗减到0就认为程序没有正常工作,强制整个系统复位。

       看门狗定时器是单片机的一个组成部分,在单片机程序的调试和运行中都有着重要的意义。它的主要功能是在发生软件故障时,通过使器件复位(如果软件未将器件清零)将单片机复位。也可以用于将器件从休眠或空闲模式唤醒,看门狗定时器对微控制器提供了独立的保护系统,当系统出现故障时,在可选的超时周期之后,看门狗将以RESET信号作出响应,像x25045就可选超时周期为1.4秒、600毫秒、200毫秒三种。当你的程序死机时,x25045就会使单片机复位。

三.实验内容及步骤

(一)学习与分析例程;

(二)

1.在时钟实验的基础上增加看门狗代码,使看门狗的周期为2S左右,打开看门狗复位功能,不喂狗,观察是否复位;

2.使看门狗的周期为2S左右,打开看门狗复位功能,每秒喂狗一次,观察是否复位;

3.编程,使看门狗的周期为2S左右,打开看门狗复位功能,每3S喂狗一次,观察是否复位;

4.自行发挥

步骤:

1) 参照模板工程watchdog(modules\rtc\watchdog.apj),新建一个工程watchdog,添加相应的文件,并修改watch 的工程设置;

2) 创建main.c 并加入到工程watch 中;

3) 根据内容编程;

4) 编译main,下载程序并运行,通过超级终端看是否复位;

四、实验程序

/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

extern unsigned char seg7table[];

/* 表示日期、时间的数据结构 */

typedef struct ST_DATE

{

       short      year;       // 年

       char mon;        // 月

       char day;        // 日

       char week_day;   // 星期

       char hour;       // 时

       char min;        // 分

       char sec;        // 秒

} st_date;

/* 全局变量 */

int led_index = 0;

int ext0_count = 0;

int a[9]={8448*3,0,0,8448*3,0,0,8448*3,0,0};

int i=0;

/* functions */

void rtc_tick_isr(void) __attribute__ ((interrupt("IRQ")));;

void rtc_int_isr(void) __attribute__ ((interrupt("IRQ")));;

#define WDT_ENABLE               (0x01<<5)

#define WDT_INT_ENABLE              (0x01<<2)

#define WDT_RST_ENABLE             (0x01<<0)     

#define WDT_CLK_SEL                    (0X3    <<3)              /* 1/128 */

#define WDT_PRE_SCALER              ((PCLK/1000000-1)   <<8)        /* 49    */

/********************************************************************

// Function name    : watchdog_init

// Description      : 看门狗初始化

// Return type         : void

// Argument         :

*********************************************************************/

void watchdog_init()

{

       rWTCNT = 8448 * 2;           /* 设置看门狗初始值 */

       rWTCON = WDT_ENABLE | WDT_RST_ENABLE | WDT_CLK_SEL | WDT_PRE_SCALER;    /* 打开看门狗 */         /* 打开看门狗 */

}

/*****************************************************************************

// Function name    : rtc_set_date

// Description      : 修改实时时钟当前时间、日期

// Return type         : void

// Argument         : p_date, 待设置的日期

*****************************************************************************/

void rtc_set_date(st_date* p_date)

{

    rRTCCON  = 0x01;     

    rBCDYEAR = p_date->year;

    rBCDMON  = p_date->mon;

    rBCDDAY  = p_date->day;

    rBCDDATE = p_date->week_day;

    rBCDHOUR = p_date->hour;

    rBCDMIN  = p_date->min;

    rBCDSEC  = p_date->sec;

    rRTCCON  = 0x00;     

}

/*****************************************************************************

// Function name    : rtc_get_date

// Description      : 获取实时时钟当前时间、日期

// Return type         : void

// Argument         : p_date, 返回日期的指针

*****************************************************************************/

void rtc_get_date(st_date* p_date)

{

    rRTCCON  = 0x01;     

   

    p_date->year   =    rBCDYEAR ;

    p_date->mon         =    rBCDMON  ;

    p_date->day           =    rBCDDAY  ;

    p_date->week_day=      rBCDDATE ;

    p_date->hour  =    rBCDHOUR ;

    p_date->min          =    rBCDMIN  ;

    p_date->sec           =    rBCDSEC  ;

   

    rRTCCON  = 0x00;     

}

/*****************************************************************************

// Function name    : rtc_tick_init

// Description      : 初始化S3C2410的TICK定时器

// Return type         : void

// Argument         : tick, 设置的TICK频率(时钟滴答的周期为 (1+tick)/128秒)

*****************************************************************************/

void rtc_tick_init( char tick )

{

    Irq_Request(IRQ_TICK, rtc_tick_isr);

   

    rRTCCON   = 0x0;            //No reset[3], Merge BCD counters[2], BCD clock select XTAL[1], RTC Control disable[0]

    rTICNT  = (tick&0x7f)|0x80;             /*TICK 中断使能,周期为(1+tick)/128秒*/  

    Irq_Enable(IRQ_TICK);  

}

/*****************************************************************************

// Function name    : rtc_alarm_set

// Description      : 设置S3C2410的告警时间以及方式

// Return type         : void

// Argument         : p_date, 告警的时间

//                    mode, 告警模式

*****************************************************************************/

void rtc_alarm_set(st_date* p_date, unsigned char mode)

{

    Irq_Request(IRQ_RTC, rtc_int_isr);

   

    rRTCCON  = 0x01;     

   

    rALMYEAR = p_date->year;

    rALMMON  = p_date->mon;

    rALMDATE = p_date->day;

    rALMHOUR = p_date->hour;

    rALMMIN  = p_date->min;

    rALMSEC  = p_date->sec;

   

    rRTCALM  = mode;

   

    rRTCCON  = 0x00;     

    Irq_Enable(IRQ_RTC);  

}

/*****************************************************************************

// Function name    : Main

// Description      : JXARM9-2410 看门狗实验主程序

//                    完成功能:

//                        在实时时钟实验的基础上添加看门狗功能,并在时钟滴答

//                        中断中实现喂狗处理.

//      

// Return type         : void

// Argument         : void

*****************************************************************************/

void Main(void)

{

       int old_index ;

      

       st_date m_date;

      

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

      

       /* 中断初始化 */

    Isr_Init();

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

    /* 打印提示信息 */

       PRINTF("\n---看门狗测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n看门狗测试开始\n");

       /* 采用BCD编码,如20##年需要设置的值为0x2004 */

    m_date.year           =    0x2000+0x04 ;

    m_date.mon           =    0x03 ;

    m_date.day            =    0x02 ;

    m_date.week_day   =    0x02 ;

    m_date.hour          =    0x15 ;

    m_date.min           =    0x40 ;

    m_date.sec             =    0x00 ;

   

    /* 修改当前日期和时间 */

      m_date.year = 0x15;

  m_date.mon = 0x07;

  m_date.day = 0x01;

  m_date.week_day = 0x03;

  m_date.hour = 0x00;

  m_date.min = 0x59;

  m_date.sec = 0x53;

    rtc_set_date(&m_date);

   

    m_date.sec             =    0x05 ;

   

    /* 设置告警的时间及方式,0x41表示使能RTC告警,以及使能秒时钟告警 */

    rtc_alarm_set(&m_date, 0x41);

      

       rtc_tick_init(127);

      

       watchdog_init();// TODO

       /* 打开看门狗复位功能 */

      

       old_index = led_index;

     PRINTF("请在2秒内喂狗,否则系统将在约2秒后复位\n\n");

    

    while(1)

    {

           if(old_index != led_index)           /* 每隔一秒更新一次数据                        */

           {

                rtc_get_date(&m_date);

                old_index = led_index;

                    

                PRINTF(                      /* 时钟数据为BCD码格式,以16进制显示 */

                            "\b\b\b\b\b\b\b\b%02x:%02x:%02x", m_date.hour, m_date.min, m_date.sec);

         }

    };

}

/*****************************************************************************

// Function name    : rtc_tick_isr

// Description      : TICK中断处理程序,程序中设置每秒钟引发一次中断

//                    为避免看门狗复位在此处喂狗

// Return type         : int

// Argument         : void

*****************************************************************************/

void rtc_tick_isr(void)

{

       Irq_Clear(IRQ_TICK);         /* 清除TICK中断 */

       *((U8*) 0x10000006) = 0x00;

      *(unsigned char*)0x10000004 = seg7table[led_index%10];  

    

     led_index++;

 if(led_index %1==0)

      rWTCNT = 8448 * 2;

 

       // TODO

     /* 喂狗 */

}

/*****************************************************************************

// Function name    : rtc_int_isr

// Description      : rtc中断处理程序,程序中设置每分钟的第5秒引发该中断

// Return type         : int

// Argument         : void

*****************************************************************************/

void rtc_int_isr(void)

{

       Irq_Clear(IRQ_RTC);          /*清除RTC中断                                       */

   

//    if(ext0_count&1)

//                 *(unsigned char*)0x2000000 = 0x0f; 

//          else

//                 *(unsigned char*)0x2000000 = 0xff; 

           

     ext0_count++;

    

     PRINTF("\r\nAlarm\r\n                  ");

}

五.结果及分析

1.打开看门狗复位功能,不喂狗,看门狗复位。

2.使看门狗周期为2s左右,打开看门狗复位功能,每秒喂狗一次,看门狗不复位。

3.每3s喂狗一次,看门狗复位。

分析:喂狗相当于给看门狗一个使能信号,阻止看门狗复位。但当不喂狗或者喂狗的周期大于看门狗的周期时,看门狗也会复位。

六.实验总结

1.正确区分看门狗复位与机器故障引起的复位。

2.正确使用喂狗条件与周期。

                        

                    

                        实验七:PWM

一、实验目的

 1、了解PWM的基本原理;

 2、掌握PWM控制的编程方法。

二.实验原理

 PWM是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。

许多微控制器内部都包含PWM控制器。一般都可以选择接通时间和周期。占空比是接通时间与周期之比;调制频率为周期的倒数。

设置提供调制方波的片上定时器/计数器的周期;在PWM控制寄存器中设置接通时间;启动定时器。

三、实验内容及步骤

(一)学习与分析例程;

(二)

1、编写程序对PWM控制器输出8000Hz 2/3占空比的数字信号控制峰鸣器;

2、编写程序改变PWM控制器输出频率,如频率从4000HZ到14000HZ, 使用

          2/3的占空比;

3、编写程序改变PWM控制器输出占空比,如频率1000HZ, 使用1/100 - 95/100

           的占空比。

4、编写程序实现一句音乐。

四.试验程序

1/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* 函数声明 */

void test_pwm();

/********************************************************************

// Function name: Main

// Description : JXARM9-2410 PWM实验主程序

//  实现功能:实现JXARM9-2410 PWM方式控制蜂鸣器

// Return type: void

// Argument   : void

*********************************************************************/

void Main(void)

{

       unsigned char data[6] = {0, 1, 2, 3, 4, 5};

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---蜂鸣器测试程序---\n");

      

       /* 端口设置 */

rGPBUP  = rGPBUP  & ~(0x1f)     | 0x1f;         //GPB4 ~ 0

 rGPBCON = rGPBCON & ~(0x3ff)    | 0x2aa;    //Function Setting TCLK0, TOUT3 ~ 0  

    rGPGUP  = rGPGUP  & ~(0x800)    | 0x800;        //GPG11

    rGPGCON = rGPGCON & ~(0xc00000) | 0xc00000;     //TCLK1

    rGPHUP  = rGPHUP  & ~(0x200)    | 0x200;        //GPH9

    rGPHCON = rGPHCON & ~(0x3<<18)  | (0x2<<18);    //CLKOUT0   

    rMISCCR = rMISCCR & ~(0xf0)     | 0x40;         //Select PCLK with CLKOUT0

/* 开始测试 */

       test_pwm();

       while(1);

}

/*****************************************************************************

// Function name    : test_pwm

// Description      : 测试PWM,通过蜂鸣器输出脉冲

// Return type         : int

// Argument         : void

*****************************************************************************/

void test_pwm()

{int N,index;

while(1)

       {

       N=(PCLK/256/4)/8000;

       rTCNTB0=N;

       rTCNTB0=(2*N)/3;

       rTCON=0xa;

       rTCON=0x9;

       for(index=0;index<100000;index++)

       rTCON=0x0;// TODO   // TODO

       /*输出脉冲:频率8000Hz, 2/3占空比  */

       }

}

 2 /* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* 函数声明 */

void test_pwm();

/********************************************************************

// Function name: Main

// Description : JXARM9-2410 PWM实验主程序

//  实现功能:实现JXARM9-2410 PWM方式控制蜂鸣器

// Return type: void

// Argument   : void

*********************************************************************/

void Main(void)

{

       unsigned char data[6] = {0, 1, 2, 3, 4, 5};

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---蜂鸣器测试程序---\n");

      

       /* 端口设置 */

rGPBUP  = rGPBUP  & ~(0x1f)     | 0x1f;         //GPB4 ~ 0

 rGPBCON = rGPBCON & ~(0x3ff)    | 0x2aa;    //Function Setting TCLK0, TOUT3 ~ 0  

    rGPGUP  = rGPGUP  & ~(0x800)    | 0x800;        //GPG11

    rGPGCON = rGPGCON & ~(0xc00000) | 0xc00000;     //TCLK1

    rGPHUP  = rGPHUP  & ~(0x200)    | 0x200;        //GPH9

    rGPHCON = rGPHCON & ~(0x3<<18)  | (0x2<<18);    //CLKOUT0   

    rMISCCR = rMISCCR & ~(0xf0)     | 0x40;         //Select PCLK with CLKOUT0

/* 开始测试 */

       test_pwm();

       while(1);

}

/*****************************************************************************

// Function name    : test_pwm

// Description      : 测试PWM,通过蜂鸣器输出脉冲

// Return type         : int

// Argument         : void

*****************************************************************************/

void test_pwm()

{int Fout,N,index;

       rTCFG0=0xFF;

       rTCFG1=0x1;

       for(Fout=4000;Fout<14000;Fout+=1000)

       N=(PCLK/256/4)/Fout;

       rTCNTB0=N;

       rTCNTB0=(2*N)/3;

       rTCON=0xa;

       rTCON=0x9;

       for(index=0;index<100000;index++)

       rTCON=0x0;// TODO

/* 输出脉冲:频率从4000HZ到14000HZ, 使用2/3的占空比*/                            

}

 3/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* 函数声明 */

void test_pwm();

/********************************************************************

// Function name: Main

// Description : JXARM9-2410 PWM实验主程序

//  实现功能:实现JXARM9-2410 PWM方式控制蜂鸣器

// Return type: void

// Argument   : void

*********************************************************************/

void Main(void)

{

       unsigned char data[6] = {0, 1, 2, 3, 4, 5};

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---蜂鸣器测试程序---\n");

      

       /* 端口设置 */

rGPBUP  = rGPBUP  & ~(0x1f)     | 0x1f;         //GPB4 ~ 0

 rGPBCON = rGPBCON & ~(0x3ff)    | 0x2aa;    //Function Setting TCLK0, TOUT3 ~ 0  

    rGPGUP  = rGPGUP  & ~(0x800)    | 0x800;        //GPG11

    rGPGCON = rGPGCON & ~(0xc00000) | 0xc00000;     //TCLK1

    rGPHUP  = rGPHUP  & ~(0x200)    | 0x200;        //GPH9

    rGPHCON = rGPHCON & ~(0x3<<18)  | (0x2<<18);    //CLKOUT0   

    rMISCCR = rMISCCR & ~(0xf0)     | 0x40;         //Select PCLK with CLKOUT0

/* 开始测试 */

       test_pwm();

       while(1);

}

/*****************************************************************************

// Function name    : test_pwm

// Description      : 测试PWM,通过蜂鸣器输出脉冲

// Return type         : int

// Argument         : void

*****************************************************************************/

void test_pwm()

{int rate,N,index;

       N=(PCLK/256/4)/1000;

       for(rate=1;rate<95;rate++)

       rTCNTB0=N;

       rTCNTB0=(rate*N)/100;

       rTCON=0xa;

       rTCON=0x9;

       for(index=0;index<100000;index++)

       rTCON=0x0;// TODO

/*输出脉冲:频率1000HZ, 使用1/100 - 95/100的占空比     */

}

4  /* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

/* 函数声明 */

void test_pwm();

/********************************************************************

// Function name: Main

// Description : JXARM9-2410 PWM实验主程序

//  实现功能:实现JXARM9-2410 PWM方式控制蜂鸣器

// Return type: void

// Argument   : void

*********************************************************************/

void Main(void)

{

       unsigned char data[6] = { 0, 1, 2, 3, 4, 5 };

       /* 配置系统时钟 */

       ChangeClockDivider(2, 1);

       U32 mpll_val = 0;

       mpll_val = (92 << 12) | (1 << 4) | (1);

       ChangeMPllValue((mpll_val >> 12) & 0xff, (mpll_val >> 4) & 0x3f, mpll_val & 3);

       /* 初始化端口 */

       Port_Init();

       /* 初始化串口 */

       Uart_Init(0, 115200);

       Uart_Select(0);

       /* 打印提示信息 */

       PRINTF("\n---蜂鸣器测试程序---\n");

       /* 端口设置 */

       rGPBUP = rGPBUP  & ~(0x1f) | 0x1f;         //GPB4 ~ 0

       rGPBCON = rGPBCON & ~(0x3ff) | 0x2aa;    //Function Setting TCLK0, TOUT3 ~ 0  

       rGPGUP = rGPGUP  & ~(0x800) | 0x800;        //GPG11

       rGPGCON = rGPGCON & ~(0xc00000) | 0xc00000;     //TCLK1

       rGPHUP = rGPHUP  & ~(0x200) | 0x200;        //GPH9

       rGPHCON = rGPHCON & ~(0x3 << 18) | (0x2 << 18);    //CLKOUT0   

       rMISCCR = rMISCCR & ~(0xf0) | 0x40;         //Select PCLK with CLKOUT0

       /* 开始测试 */

       //test_pwm();

       while (1)

       {

              test_pwm();

       }

}

/*****************************************************************************

// Function name    : test_pwm

// Description      : 测试PWM,通过蜂鸣器输出脉冲

// Return type         : int

// Argument         : void

*****************************************************************************/

void test_pwm()

{

       // TODO

       //定时器配制,使用定时器0

       rTCFG0 = 0xff;

       rTCFG1 = 0x1;

       int N;

       /*输出脉冲:频率8000Hz, 2/3占空比  */

       N = PCLK / 256 / 4 / 8000;

       rTCNTB0 = N;

       rTCMPB0 = 2 * N / 3;

       rTCON = 0x9;

       Delay(100);

int feq;

       /* 输出脉冲:频率从4000HZ到14000HZ, 使用2/3的占空比*/

       for (feq = 4000; feq <= 14000; feq += 1000)

       {

              N = PCLK / 256 / 4 / feq;

              rTCNTB0 = N;

              rTCMPB0 = 2 * N / 3;

              rTCON = 0xa;

              rTCON = 0x9;

              Delay(100);

              rTCON = 0x0;

       }

       /* 输出脉冲:频率1000HZ, 使用1/100 - 95/100的占空比    */

      

       N = PCLK / 256 / 4 / 4000;

       rTCNTB0 = N;

       int i;

       int N1;

       for (i = 1; i <= 19; i++)

       {

              N1 = i*N / 100;

              rTCMPB0 = N1;

              rTCON = 0xa;

              rTCON = 0x9;

              Delay(100);

              rTCON = 0x0;

       }

}

void playSong()

{

       rTCFG0 = 0xff;

       rTCFG1 = 0x1;

       int N;

       int feq;

       int song[15]={523,523,523,523,392,392,659,659,659,659,587,587,880,494,523};

    int inter[15]={50,50,50,50,50,50,50,50,50,50,50,50,50,50,50};/*小花猫*/

    int i;

       for (i=0; i<15; i++)

       {

              N = PCLK / 256 / 4 / song[i];

              rTCNTB0 = N;

              rTCMPB0 = 2 * N / 3;

              rTCON = 0xa;

              rTCON = 0x9;

              Delay(interval[i]);

              rTCON = 0x0;

       }

}

实验结果:运行后,蜂鸣器会响起根据不同音符对应不同频率自行组合的音乐。

                              实验八:步进电机实验

一.实验目的

1.了解步进电机的原理以及控制方法。

二.实验原理

       步进电机是将电脉冲信号转变为角位移或线位移的开环控制元件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,即给电机加一个脉冲信号,电机则转过一个步距角。这一线性关系的存在,加上步进电机只有周期性的误差而无累积误差等特点。使得在速度、位置等控制领域用步进电机来控制变得非常的简单。

单三拍方式

       电机的定子上有六个均布的磁极,其夹角是60度。各磁极上套有线圈,按图连成A、B、C三相绕组。设转子上均布40个小齿。所以每个齿的齿距为。三相绕组按A→B→C→A顺序循环通电时,转子会按顺时针方向,以每个通电脉冲转动3度规律步进式转动起来。若改变通电顺序,按A→C→B→A顺序循环通电,则转子就按逆时针方向以每个通电脉冲转动3度律转动。因为每一瞬间只有一相绕组通电,并且按三种通电状态循环通电,故称为单三拍运行方式。三相步进电动机还有两种通电方式,它们分别是双三拍运行,即按AB→BC→CA→AB顺序循环通电的方式,以及单、双六拍运行,即按A→AB→B→BC→C→CA→A顺序循环通电的方式。六拍运行时的步矩角将减小一半。反应式步进电动机的步距角可按下式计算:,式中Er——转子齿数;N——运行拍数,N=km,m为步进电动机的绕组相数,k=1或2。

       本实验的步进电机使用四相式步进电机,工作模式为两相四拍。

       脉冲分配信号:整步模式脉冲分配

三.实验内容及步骤

1.编写程序实现步进电机正转;

2.编写程序实现步进电机反转;

步骤:

1)参照模板工程stepper (modules\stepper\ stepper.apj),新建一个工程stepper,添加相应的文件,并修改stepper的工程设置;

2)创建stepper.c文件,将该文件加入到工程中;

3)编写程序;

4)编译、下载、运行、调试程序、输出结果;

四,实验程序

//ioport unsigned port100e;

/* functions */

void delay(int count);

// TODO

// 整步模式正转脉冲

void Main(void)

{ int row = 0;

       for( ; ; )

       {int i;

       for(i=0;i<2;i++)

       {*((unsigned char*)0x20002000) = 0x5;

              delay(1000);

              *((unsigned char*)0x20002000) = 0x9;

              delay(1000);

              *((unsigned char*)0x20002000) = 0xa;

              delay(1000);

              *((unsigned char*)0x20002000) = 0x6;

              delay(1000);

     }

    for(i=2;i>=0;i--)

       {     *((unsigned char*)0x20002000) = 0x6;

              delay(1000);

              *((unsigned char*)0x20002000) = 0xa;

              delay(1000);

              *((unsigned char*)0x20002000) = 0x9;

              delay(1000);

              *((unsigned char*)0x20002000) = 0x5;

       }

              // TODO

       }

}

/*****************************************************************************

// Function name    : delay

// Description      : 延时子程序

// Return type         : void

// Argument         : count,延时的数值

*****************************************************************************/

void delay( int count )

{

       int cnt;

      

       for( count = count; count>0; count--)

              for( cnt = 0; cnt < 100; cnt++);

}

实验结果:运行后,步进电机先正转,然后再反转。

                         实验九:串口通讯实验

一.实验目的

1.掌握ARM的串行口工作原理。

2.学习编程实现ARM的UART通讯。

3.掌握S3C2440寄存器配置方法。

二.实验原理

1.UART(Universal Asynchronous Receiver and Transmitter,通用异步收发器),采用异步串行通信方式。UART以字符为单位进行数据传输,每个字符的传输格式如图所示,包括线路空闲状态(高电平)、起始位(低电平)、5~8位数据位、校验位(可选)和停止位(位数可以是1、1.5或2位)。

2. S3C2440A的UART特性:

(1)基于DMA或基于中断操作的RxD0,TxD0,RxD1,TxD1,RxD2和TxD2

(2)UART通道0,1和2带IrDA 1.0和64字节FIFO

(3)UART通道0和1带nRTS0,nCTS0,nRTS1和nCTS1

(4)支持握手发送/接收

(5)S3C2440A的UART包括了可编程波特率,红外(IR)发送/接收,插入1个或2个停止位,5位、6位、7位或8位的数据宽度以及奇偶校验。

三.实验内容及步骤

(一)学习与分析相关例程,分析有关UART寄存器的设置;

(二)

1.补充程序,实现对串口的初始化和回环测试。接收来自串口(通过超级终端)的字符并将接收到的字符发送到超级终端;

2.在1的基础上将终端输入字符显示在实验箱的数码管上;

3.自行开发,如显示一串字符等。

步骤:

1) 参照模板工程uart(modules\uart\uart.apj),新建一个工程uart,添加相应的文件,

并修改uart 的工程设置;

2) 加入如下文件到uart 中:common\2440lib.c、;asm\2440init.s、asm\2440slib.s。

3) 参照上节内容编写串口操作主函数,并保存为main.c 文件,将该文件加入到工程中;

4) 参考模板工程uart 对uart 工程进行设置,然后编译uart;

5) 将计算机的串口接到教学实验系统的uart0 上;

6) 运行超级终端,选择正确的串口号,并将串口设置为:波特率(115200)、奇偶校验

(None)、数据位数(8)和停止位数(1),无流控,打开串口。

7) 下载程序并运行,如果程序运行正确,在超级终端中输入的数据将回显到超级终端上。

四、实验程序

1/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"\

void showChar(char ch);

void showString(char *str);

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 串口通信实验主程序

//                    实现功能:

//                        实现JXRAM9-2410与PC机的串口通讯

//                        JXARM9-2410 UART0 <==> PC COM

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

       // TODO  串口初始化

    /* 打印提示信息 */

    Uart_Init(0, 115200);

       Uart_Select(0);

       PRINTF("\n---UART测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n从现在开始您从超级中断发送的字符将被回显在超级终端上\n");

              char ch;

       char *st;

       char *st1;

       ch = Uart_Getch();

       Uart_SendByte(ch);

       st1 = st;

       *st++ = ch;

    /* 开始回环测试 */

       while (ch != '\r')

       {

              // TODO

              *st++ = ch;

              showChar(ch);

              ch = Uart_Getch();

              Uart_SendByte(ch);

              // 串口回环测试

       }

       Uart_SendString(st1);

       //显示字符串

}

void showChar(char ch)

{

       unsigned char segtable[16] =

       {

              /* 0       1       2       3       4       5       6      7*/

              0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,

              /* 8       9      A        B       C       D       E      F*/

              0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,

       };

      

       *((unsigned char *)0x20007000) = 0x3E;

       if ((ch >= '0')&(ch <= '9'))

       {

              *((unsigned char*)0x20006000) = segtable[ch - '0'];

              Delay(1);

       }

       else if ((ch >= 'A')&(ch <= 'F'))

       {

              *((unsigned char*)0x20006000) = segtable[ch - 'A' + 10];

              Delay(1);

       }

       else

       {

              *((unsigned char*)0x20006000) = 0x00;

       }

}

void showString(char *str)

{

       char *show = str;

       unsigned char segtable[16] =

       {

              /* 0       1       2       3       4       5       6      7*/

              0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,

              /* 8       9      A        B       C       D       E      F*/

              0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,

       };

       int i = 0;

       int j;

       while (*show != '\r')

       {

              for (j = 0; j < 1000;j++)

              {

                     *((unsigned char*)0x20007000) = ~(1 << i) & 0x3f;

                     if ((*show >= '0')&(*show <= '9'))

                     {

                            *((unsigned char*)0x20006000) = segtable[*show - '0'];

                            Delay(1);

                     }

                     else if ((*show >= 'A')&(*show <= 'F'))

                     {

                            *((unsigned char*)0x20006000) = segtable[*show - 'A' + 10];

                            Delay(1);

                     }

                     else

                     {

                            *((unsigned char*)0x20006000) = 0x00;

                     }

                     show++;

                     i++;

                     i %= 6;

              }

       }

}

实验结果:程序运行后,可以在键盘上任意输入字符,会在超级终端上显示输入的字符,而且会在数码管上显示对应输入的字符(0-F),如果是其他字符会显示数字8。

2/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"\

void showChar(char ch);

void showString(char *str);

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 串口通信实验主程序

//                    实现功能:

//                        实现JXRAM9-2410与PC机的串口通讯

//                        JXARM9-2410 UART0 <==> PC COM

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

       // TODO  串口初始化

    /* 打印提示信息 */

    Uart_Init(0, 115200);

       Uart_Select(0);

       PRINTF("\n---UART测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       PRINTF("\n从现在开始您从超级中断发送的字符将被回显在超级终端上\n");

              char ch;

       char *st;

       char *st1;

       ch = Uart_Getch();

       Uart_SendByte(ch);

       st1 = st;

       *st++ = ch;

    /* 开始回环测试 */

       Uart_GetString(st);

       Uart_SendString(st);

       Uart_SendString(st1);

       /*

       while (1)

       {

              showString(st1);

       }

       */

       //显示字符串

       /*

       char *st;

       Uart_GetString(st);

       Uart_SendString(st);

       */

}

void showChar(char ch)

{

       unsigned char segtable[16] =

       {

              /* 0       1       2       3       4       5       6      7*/

              0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,

              /* 8       9      A        B       C       D       E      F*/

              0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,

       };

      

       *((unsigned char *)0x20007000) = 0x3E;

       if ((ch >= '0')&(ch <= '9'))

       {

              *((unsigned char*)0x20006000) = segtable[ch - '0'];

              Delay(1);

       }

       else if ((ch >= 'A')&(ch <= 'F'))

       {

              *((unsigned char*)0x20006000) = segtable[ch - 'A' + 10];

              Delay(1);

       }

       else

       {

              *((unsigned char*)0x20006000) = 0x00;

       }

}

void showString(char *str)

{

       char *show = str;

       unsigned char segtable[16] =

       {

              /* 0       1       2       3       4       5       6      7*/

              0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8,

              /* 8       9      A        B       C       D       E      F*/

              0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,

       };

       int i = 0;

       int j;

       while (*show != '\r')

       {

              for (j = 0; j < 1000;j++)

              {

                     *((unsigned char*)0x20007000) = ~(1 << i) & 0x3f;

                     if ((*show >= '0')&(*show <= '9'))

                     {

                            *((unsigned char*)0x20006000) = segtable[*show - '0'];

                            Delay(1);

                     }

                     else if ((*show >= 'A')&(*show <= 'F'))

                     {

                            *((unsigned char*)0x20006000) = segtable[*show - 'A' + 10];

                            Delay(1);

                     }

                     else

                     {

                            *((unsigned char*)0x20006000) = 0x00;

                     }

                     show++;

                     i++;

                     i %= 6;

              }

       }

实验结果:任意输入一串字符,会显示在超级终端上,当按下回车键结束时,会在下一行显示上下方向的箭头,表示输入结束,即输出了一个字符串。

                                实验十:LCD显示实验

一、实验目的

1、了解LCD显示图形的方法;

2、了解LCD显示字符的方法(本次实验显示汉字)。

二.实验原理

LCD显示器是通过给不同的液晶单元供电,控制其光线的通过与否,从而达到显示的目的。因此,LCD的驱动控制归于对每个液晶单元通断电的控制,每个液晶单元都对应着一个电极,对其通电,便可使用光线通过(也有刚好相反的,即不通电时光线通过,通电时光线不通过)。

光源的提供方式有两种:透射式和反射式。笔记本电脑的LCD显示屏即为透射式,屏后面有一个光源,因此外界环境可以不需要光源。而一般微控制器上使用的LCD为反射式,需要外界提供光源,靠反射光来工作。

LCD的驱动控制——扫描器控制方式:

一般带有驱动模块的LCD显示屏使用总线驱动方式,这种LCD可以方便地与各种低档单片机进行接口,如8051系列单片机。由于LCD已经带有驱动硬件电路,因此模块给出的是总线接口,便于与单片机的总线进行接口。驱动模块具有八位数据总线,外加一些电源接口和控制信号。而且还自带显示缓存,只需要将要显示的内容送到显示缓存中就可以实现内容的显示。由于只有八条数据线,因此常常通过引脚信号来实现地址与数据线复用,以达到把相应数据送到相应显示缓存的目的。

三.实验内容

1、学习例程,在LCD上显示图形;

2、在LCD上显示汉字。如:显示“西安电子科技大学”等;

四.试验程序

/* 包含文件 */

#include "def.h"

#include "2410lib.h"

#include "option.h"

#include "2410addr.h"

#include "interrupt.h"

#include "lcdlib.h"

//#define STN_LCD

#define TFT_8_0

void (*PutPixel)(U32,U32,U32);

void Lcd_Disp_Char(void);

void Lcd_Disp_Grap(void);

/********************************************************************

// Function name    : Main

// Description      : JXARM9-2410 LCD显示实验主程序

//                    实现功能:

// Return type         : void

// Argument         : void

*********************************************************************/

void Main(void)

{

       /* 配置系统时钟 */

    ChangeClockDivider(2,1);

    U32 mpll_val = 0 ;

    mpll_val = (92<<12)|(1<<4)|(1);

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

   

    /* 初始化端口 */

    Port_Init();

   

    /* 初始化串口 */

    Uart_Init(0,115200);

    Uart_Select(0);

   

    /* 打印提示信息 */

       PRINTF("\n---LCD测试程序---\n");

       PRINTF("\n请将UART0与PC串口进行连接,然后启动超级终端程序(115200, 8, N, 1)\n");

       /* LCD初始化 */

    Lcd_Port_Init();

#ifdef STN_LCD

    Lcd_Init(MODE_CSTN_8BIT);

    Glib_Init(MODE_CSTN_8BIT);

    Lcd_CstnOnOff(1);

   

    Glib_ClearScr(0xff, MODE_CSTN_8BIT);

#else

       #ifdef TFT_8_0

              rGPCCON &= ~(3<<8);

              rGPCCON |= (2<<8);

           Lcd_Init(MODE_TFT_16BIT_640480);

           Glib_Init(MODE_TFT_16BIT_640480);

      

           Glib_ClearScr(0xffff, MODE_TFT_16BIT_640480);

           Lcd_PowerEnable(0, 1);

           Lcd_EnvidOnOff(1);   

       #else

           Lcd_Init(MODE_TFT_16BIT_240320);

           Glib_Init(MODE_TFT_16BIT_240320);

          

           Glib_ClearScr(0xffff, MODE_TFT_16BIT_240320);

           Lcd_PowerEnable(0, 1);

           Lcd_EnvidOnOff(1);

    #endif

#endif

    while(1)

    {

//#define LCD_DISP_CHAR

/*#ifdef  LCD_DISP_CHAR      

       Lcd_Disp_Char();

#else

       Lcd_Disp_Grap();

#endif  */

   // Lcd_Disp_Char();

   Glib_Line(40,240,70,300,0x0);

   Glib_Line(70,280,100,300,0x0);

   Glib_Line(140,240,170,300,0x0);

   Glib_Line(170,300,200,240,0x0);

   

   

 //   Lcd_Disp_Grap();

    }

}   

void Lcd_Disp_Char(void)

{

       /* 显示字符串 */

      Glib_disp_hzk16(30,100,"西安电子科技大学自动化", 0x0);

       while(1);

}

void Lcd_Disp_Grap(void)

{

       int i,j;

      

    for(j=0;j<480;j++)

        for(i=0;i<640;i++)     //RRRGGGBB

           (*PutPixel)(i,j,0xf800);

          

       Delay (100);           

  

    for(j=0;j<480;j++)

        for(i=0;i<640;i++)     //RRRGGGBB

           (*PutPixel)(i,j,0x07e0);

  

       Delay (100);           

    for(j=0;j<480;j++)

        for(i=0;i<640;i++)     //RRRGGGBB

           (*PutPixel)(i,j,0x001f);

  

       Delay (100);           

    for(j=0;j<480;j++)

        for(i=0;i<640;i++)     //RRRGGGBB

           (*PutPixel)(i,j,0xffff);

  

       Delay (100);           

       /*int i,j;

       PRINTF("\ndis 1\n");

       for(i=0;i<640;i++)

           for(j=0;j<480;j++)

                  _PutTft16Bit_640480(i,j,*(short *)(0xf100 + (j*640 + i) * 2));*/

}

实验结果:根据坐标设计显示了闭合图形。

调用 Lcd_Disp_Grap();函数,屏幕上显示“西安电子科技大学”

相关推荐