Board logo

标题: ARM开发调试笔记心得(转)(3) [打印本页]

作者: yuyang911220    时间: 2015-2-27 13:30     标题: ARM开发调试笔记心得(转)(3)

四.总结    本实验非常的顺利,没有出现问题。证明ARM芯片的内部外围与8位单片机内部外围的控制或使用方法在原理上基本是相同的,都是通过设置相关的特殊功能寄存器来实现控制。也就是说只要会单片机也就会ARM!
键盘输入——I/O输入实验
一.实验目的
能够正确读取PIO的管脚状态,实现当有按键按下时,LED点亮,否则灭。
二.实验程序和参数设置
1>连接器选项设置和启动代码都与上个实验相同
2> C语言的代码
        #include "AT91SAM7S64.h" //特殊功能寄存器头文件。类似与51单片机中reg51.h
        #include "Board.h" //定义目标板的头文件
        int main(void)
        {
             unsigned int Key_Val; //定义变量,unsigned int为32位,C51是16位
             *AT91C_PIOA_PER = LED_MASK | SW_MASK;//使能LED、KEY脚I/O口功能 *AT91C_PIOA_ODR = SW_MASK;//使能4个KEY对应管脚的输入功能
            *AT91C_PIOA_OER = LED_MASK;//使能4个LED管脚的输出功能
            while (1)
            {
                Key_Val = *AT91C_PIOA_PDSR;//读管脚的电平状态
                if (Key_Val & SW1)
                {
                       *AT91C_PIOA_SODR = LED1;//将状态反映给LED
                 }
                else
                {
                        *AT91C_PIOA_COER = LED1;//按钮按下时,LED1亮
                }
            }
        }
三.出现的问题与解决方法
1> 无论作输入用的I/O口电平如何变化,管脚状态寄存器(AT91C_PIOA_PDSR)的内容始终为0,即I/O口的输入功能没起作用。
原因是AT91SAM7Sxx内部集成了功率管理控制器,用它来控制所有外设的时钟以达到优化功耗的目的。所以只有使能了PIO的外围时钟,PIO外设才会工作,才能读入输入管脚的状态。那么为什么PIO作为输出时不需要使能外围时钟呢?我个人认为这与内部外设在数字电路上的实现有关,输出功能只需要组合逻辑电路(不用时钟)就能实现,而输入功能则需要用到时序逻辑电路(需要时钟)才能实现。
因此,必须在main()函数的开头增加如下两条时钟使能的语句:
*AT91C_PMC_SCER = AT91C_CKGR_MOSCEN;//使能系统时钟寄存器的处理器时钟
*AT91C_PMC_PCER = 1 << AT91C_ID_PIOA; //使能PIOA外围时钟
四.总结
当要使AT91SAM7S64特定的外设工作时,必须使能相应外设的时钟控制寄存器。相反,如果不用相应的外设,禁能相应的时钟可以降低功耗。
模拟量输入——A/D转换实验
一.目的
通过A/D转换,能够正确读取外部模拟输入通道的电压值。
二.实验程序和参数设置
1>连接器选项设置和启动代码都与上个实验相同
2>C语言的代码
        #include "AT91SAM7S64.h"
        #include "Board.h"
        volatile unsigned int EXT_AD_Val[4]; //定义A/D转换结果值
        int main(void)
        {
            unsigned char i;
            *AT91C_ADC_CR = AT91C_CKGR_MOSCEN; //ADC的软件复位,即清除ADC的所有寄存器
            *AT91C_PMC_SCER = AT91C_CKGR_MOSCEN;//使能系统时钟寄存器的处理器时钟
            *AT91C_PMC_PCER = 1 << AT91C_ID_ADC; //使能ADC时钟
            *AT91C_PIOA_PDR = EXT_AD0 | EXT_AD1; //禁止管脚的I/O口功能,使作为模拟输入功能
            *AT91C_ADC_MR = 0x0f1f3f00; //软件起动,10位分辨率,128分频
            *AT91C_ADC_CHER = 0x33; //使能通道0,1,4,5
            *AT91C_ADC_CHDR = 0xcc; //禁能通道2,3,6,7
            *AT91C_ADC_IDR = 0xfffff; //禁止所有ADC中断
            while (1)
            {
                  *AT91C_ADC_CR = 0x2; //起动转换
                  while(1)
                  {
                        if ((*AT91C_ADC_SR) & 0x33) //等待转换结束
                        {
                               EXT_AD_Val[0] = (*AT91C_ADC_CDR0) & 0x3ff;//读取10Bit的结果值
                               EXT_AD_Val[1] = (*AT91C_ADC_CDR1) & 0x3ff;
                               EXT_AD_Val[2] = (*AT91C_ADC_CDR4) & 0x3ff;
                               EXT_AD_Val[3] = (*AT91C_ADC_CDR5) & 0x3ff;
                               for (i = 0; i < 4; i++) EXT_AD_Val = (EXT_AD_Val * 3300) / 1023;
                              break;
                         }
                  }
            }
        }
三.总结
执行ADC的软件复位,将清除ADC的所有相关寄存器,因此必须在设置ADC相关寄存器之前执行。




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