Chinaunix首页 | 论坛 | 博客
  • 博客访问: 244863
  • 博文数量: 181
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 422
  • 用 户 组: 普通用户
  • 注册时间: 2016-06-09 15:34
个人简介

你好 世界

文章分类

全部博文(181)

文章存档

2016年(181)

我的朋友

分类: 嵌入式

2016-06-06 18:18:42

=========================================================================================
按键中断实验

一、看原理图,找到key2对应的引脚是GPX1_1,我们需要配置这个引脚为中断功能
   XEINT9/KP_COL1/ALV_DBG5/GPX1_1

二、分析芯片手册

外设层次上
GPX1CON
GPX1CON[1]  [7:4]: 0xF = WAKEUP_INT1[1]

GPX1PUD
GPX1PUD[1] [3:2]: 0 disabled

EXT_INT41CON
EXT_INT41_CON[1]  [6:4]: 0x2 = Triggers Falling edge  //下降沿触发中断

EXT_INT41_MASK
EXT_INT41_MASK[1]  [1]: 0x0 = Enables Interrupt      //使能中断,可以让中断发生

EXT_INT41_PEND
EXT_INT41_PEND[1]  [1]:0x1 = Interrupt Occurs         //写1清中断,在中断处理函数中设置,初始化不用设置

SPI号    中断号(唯一的)
25             57           –  EINT[9]
********************************************************************************
GIC层次上
ICCEOIR_CPU0          //当中断处理程序结束,将中断号写回这个寄存器,代表中断处理完成
EOIINTID  [9:0]  W The ACKINTID value from the corresponding ICCIAR access.

ICDISER1              //使能当前中断
Set-enable bits  [31:0]:  25   1-enable

ICDDCR       //全局使能GIC,让所有中断都可以通过GIC到达CPU接口
Enable  [0]: 1 = GIC monitors the peripheral interrupt signals and forwards pending interrupts to the CPU interfaces.

ICCPMR_CPU0   //设置优先级的门槛,当前发生的中断的优先级高于这个门槛才能通过
Priority  [7:0]: 0xff      //0xff表示优先级最低,所有的中断都可以通过

ICDICPR1
Clear-pending bits  [31:0]: 25 写1 清中断

****************************************************************************
CPU层次
全局使能中断,所有中断都可以通过CPU接口到达处理器
ICCICR_CPU0   // Global enable for signaling of interrupts by the CPU Interface to the connected processors.
Enable  [0]:1 = Enables signaling of interrupts

ICCIAR_CPU0           //当前发生中断的中断号
ACKINTID  [9:0]  R  The interrupt ID   

ICDIPTR14    //将57号中断交给CPU0来处理
CPU targets, byte offset 1  [15:8]; 0x1 

点击(此处)折叠或打开

  1. #include "exynos_4412.h"
  2. #include "led.h"
  3. #include "buzz.h"
  4. #include "uart.h"
  5. #include "adc.h"


  6. unsigned int adflag = 0;
  7. /*****延时代码块*****/
  8. void delay_ms(unsigned int Time)
  9. {
  10.     unsigned int i, j;

  11.     for (i = 0; i < Time; i++)
  12.     {
  13.         for (j = 0; j < 3000; j++);
  14.     }
  15. }

  16. /****外设层设置*****/
  17. void peripheral()
  18. {
  19.     /* 1. 将GPX1_1/2和GPX3_2 引脚设置为中断功能,同时禁止上下拉电阻 */
  20.     GPX1.CON = GPX1.CON & (~(0xFF << 4)) | (0xFF << 4);
  21.     GPX1.PUD = GPX1.PUD & (~(0xF << 2));

  22.     GPX3.CON = GPX3.CON & (~(0xF << 8)) | (0xF << 8);
  23.     GPX3.PUD = GPX3.PUD & (~(0x3 << 4));

  24.     /* 2. 配置中断触发模式, 下降沿触发 */
  25.     EXT_INT41_CON = EXT_INT41_CON & (~(0x77 << 4)) | (0x22 << 4);
  26.     EXT_INT43_CON = EXT_INT43_CON & (~(0x7 << 8)) | (0x2 << 8);

  27.     /* 3. 使能中断 */
  28.     EXT_INT41_MASK = EXT_INT41_MASK & (~(0x3 << 1));
  29.     EXT_INT43_MASK = EXT_INT43_MASK & (~(0x1 << 2));

  30.     return ;
  31. }

  32. /****GIC层次设置****/
  33. void GIC()
  34. {
  35.     /* 1. 全局使能GIC,让所有中断都可以通过GIC */
  36.     ICDDCR = ICDDCR | (0x1 << 0);

  37.     /* 2. 使能当前中断,57,58,64号中断 */
  38.     ICDISER.ICDISER1 = ICDISER.ICDISER1 & (~(0x3 << 25)) | (0x3 << 25);
  39.     ICDISER.ICDISER2 = ICDISER.ICDISER2 & (~(0x1 << 0)) | (0x1 << 0);

  40.     /* 3. 设置中断优先级的门槛,高于这个门槛都可以通过,值越大门槛越低 */
  41.     CPU0.ICCPMR = CPU0.ICCPMR & (~(0xFF << 0 )) | (0xFF << 0);

  42.     return;
  43. }

  44. /****CPU层次设置****/
  45. void CPU()
  46. {
  47.     /* 1. 全局使能中断,所有中断都可以通过CPU接口到达处理器 */
  48.     CPU0.ICCICR = CPU0.ICCICR & (~(0x1 << 0)) | (0x1 << 0);

  49.     /* 2. 将中断交个CPU0来处理 */
  50.     ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xFFFF << 8)) | (0x101 << 8);
  51.     ICDIPTR.ICDIPTR16 = ICDIPTR.ICDIPTR16 & (~(0xFF << 0)) | (0x01 << 0);

  52.     return ;
  53. }



  54. void do_irq()
  55. {
  56.     unsigned int irq_num;

  57.     /***获取中断号****/
  58.     irq_num = CPU0.ICCIAR & (0x3ff<<0);

  59.     /***清中断***/
  60.     EXT_INT41_PEND = EXT_INT41_PEND & (~(0x3 << 1)) | (0x3 << 1);

  61.     switch (irq_num)
  62.     {
  63.         case 57:
  64.             ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 & (~(0x1 << 25)) | (0x1 << 25);
  65.             /***将中断号写回这个寄存器,代表中断处理完成***/
  66.             CPU0.ICCEOIR = CPU0.ICCEOIR & (~(0x3ff<<0)) | (irq_num<<0);
  67.             printf("**************************SPI Port No:%d********ID:%d************************\n",irq_num,irq_num-32);
  68.             adflag = 0;
  69.             buzzoff();
  70.             LEDon();
  71.             break;
  72.         case 58:
  73.             ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 & (~(0x2 << 25)) | (0x2 << 25);
  74.             /***将中断号写回这个寄存器,代表中断处理完成***/
  75.             CPU0.ICCEOIR = CPU0.ICCEOIR & (~(0x3ff<<0)) | (irq_num<<0);
  76.             printf("**************************SPI Port No:%d********ID:%d************************\n",irq_num,irq_num-32);
  77.             adflag = 0;
  78.             buzzon();
  79.             break;
  80.         case 64:
  81.             ICDICPR.ICDICPR2 = ICDICPR.ICDICPR2 & (~(0x1 << 0)) | (0x1 << 0);
  82.             /***将中断号写回这个寄存器,代表中断处理完成***/
  83.             CPU0.ICCEOIR = CPU0.ICCEOIR & (~(0x3ff<<0)) | (irq_num<<0);
  84.             printf("**************************SPI Port No:%d********ID:%d************************\n",irq_num,irq_num-32);
  85.             buzzoff();
  86.             adflag = 1;
  87.             adc_Converter_Value();
  88.             break;
  89.         default:
  90.             break;
  91.     }

  92.     return ;
  93. }



  94. int main()
  95. {
  96.     /***初始化LED***/
  97.     LED_init();

  98.     /***初始化ADC***/
  99.     adc_init();

  100.     /***初始化buzz***/
  101.     buzz_init();

  102.     /***初始化串口***/
  103.     uart_init();
  104.     puts("******************* interrupt information *******************\n");

  105.     /****外设层设置*****/
  106.     peripheral();

  107.     /****GIC层次设置****/
  108.     GIC();

  109.     /****CPU层次设置****/
  110.     CPU();

  111.     while(1);
  112.     return 0;
  113. }

  114. /********LED*********/
  115. /****LEDIO配置****/
  116. void LED_init()
  117. {
  118.     /*******LED1***********/
  119.     GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x01 << 28);
  120.     /*******LED2***********/
  121.     GPX1.CON = GPX1.CON & (~(0xF << 0)) | (0x1 << 0);
  122.     /*******LED3***********/
  123.     /*******LED4***********/
  124.     GPF3.CON = GPF3.CON & (~(0xFF << 16)) | (0x11 << 16);
  125. }



  126. /****IO控制****/
  127. void LEDon()
  128. {
  129.     /***开启蜂鸣器****/
  130. //    buzzon();
  131.     /*******LED1***********/
  132.     GPX2.DAT = GPX2.DAT & (~(0x01 << 7)) | (0x01 << 7);
  133.     delay_ms(500);
  134.     GPX2.DAT = GPX2.DAT & (~(0x01 << 7)) | (0x00 << 7);
  135.     /***关闭蜂鸣器****/
  136. //    buzzoff();
  137.     delay_ms(500);


  138.     /***开启蜂鸣器****/
  139. //    buzzon();
  140.     /*******LED2***********/
  141.     GPX1.DAT = GPX1.DAT & (~(0x01 << 0)) | (0x01 << 0);
  142.     delay_ms(500);
  143.     GPX1.DAT = GPX1.DAT & (~(0x01 << 0)) | (0x00 << 0);
  144.     /***关闭蜂鸣器****/
  145. //    buzzoff();
  146.     delay_ms(500);


  147.     /***开启蜂鸣器****/
  148. //    buzzon();
  149.     /*******LED3***********/
  150.     GPF3.DAT = GPF3.DAT & (~(0x01 << 4)) | (0x01 << 4);
  151.     delay_ms(500);
  152.     GPF3.DAT = GPF3.DAT & (~(0x01 << 4)) | (0x00 << 4);
  153.     /***关闭蜂鸣器****/
  154. //    buzzoff();
  155.     delay_ms(500);

  156.     /***开启蜂鸣器****/
  157. //    buzzon();
  158.     /*******LED4***********/
  159.     GPF3.DAT = GPF3.DAT & (~(0x01 << 5)) | (0x01 << 5);
  160.     delay_ms(500);
  161.     GPF3.DAT = GPF3.DAT & (~(0x01 << 5)) | (0x00 << 5);
  162.     /***关闭蜂鸣器****/
  163. //    buzzoff();
  164.     delay_ms(500);


  165. }


  166. /************BUZZ*************/
  167. /*****蜂鸣器设置******/
  168. void buzz_init()
  169. {
  170.     /*将DPD0_0管脚设置成PWM功能*/
  171.     GPD0.CON = GPD0.CON & (~(0xF << 0)) | (0x2 << 0);
  172.     /*一级预分频100000000/(99+1) = 1000000*/
  173.     PWM.TCFG0 = PWM.TCFG0 & (~(0xFF)) | 99;
  174.     /*二级预分频1000000/1 = 1000000*/
  175.     PWM.TCFG1 = PWM.TCFG1 & (~(0xF));
  176.     /*打开自动重装载功能*/
  177.     PWM.TCON = PWM.TCON | (0x1 << 3);
  178.     /*设置频率为1MHZ/1000=1000HZ 周期为1/1000HZ=1ms*/
  179.     PWM.TCNTB0 = 500;
  180.     /*设置占空比 500/1000=50%*/
  181.     PWM.TCMPB0 = 150;

  182.     /**
  183.      * 在第一次执行完后,必须手动装载往TCNTB0寄存器中装载一次数据
  184.      */

  185.     /*手动将TCNTB0中的值加载到TCNTB0*/
  186.     PWM.TCON = PWM.TCON | (1 << 1);
  187. //    /***开启蜂鸣器****/
  188. //    buzzon();
  189.     /*关闭手动装载*/
  190.     PWM.TCON = PWM.TCON & ~((1 << 1));
  191. }
  192. /***关闭蜂鸣器****/
  193. void buzzoff()
  194. {
  195.     /*关闭计数器0*/
  196.     PWM.TCON = PWM.TCON & (~(0x1 << 0)) | (0x0 << 0);
  197. }
  198. /****开启蜂鸣器****/
  199. void buzzon()
  200. {
  201.     /*打开计数器0*/
  202.     PWM.TCON = PWM.TCON & (~(0x1 << 0)) | (0x1 << 0);
  203. }


  204. /***********ADC************/
  205. void adc_init()
  206. {

  207.         /***通道选择:3****/
  208.         ADCMUX = ADCMUX & (~(0xF << 0)) | (0x3 << 0);

  209.         /**
  210.          * 寄存器配置方式1
  211.          * ADCCON = (0x1 << 16) | (0x1 << 14) | (0xff << 6);
  212.          */
  213.         /***12位转换精度***/
  214.         ADCCON = ADCCON & (~(0x1 << 16)) | (0x1 << 16);

  215.         /***使能预分频***/
  216.         ADCCON = ADCCON & (~(0x1 << 14)) | (0x1 << 14);

  217.         /*** AD是时钟频率100M/(19+1) = 5M ***/
  218.         ADCCON = ADCCON & (~(0xFF << 6)) | (0x13 << 6);

  219.         /***正常模式 关闭待机****/
  220.         ADCCON = ADCCON & (~(0x1 << 2));


  221.         /**
  222.          * 寄存器配置方式2
  223.          */
  224.     //    ADCCON = (0x1<<16) | (0x1<<14) | (0xff<<6) | 0x1<<1;
  225.     //    必须先读一次寄存器的值,才能激活AD
  226.     //    temp_adc = ADCDAT & 0xFFF;

  227.         return ;
  228. }

  229. void adc_Converter_Value ()
  230. {
  231.     unsigned int temp_adc = 0;
  232.     unsigned int temp_mv = 0;


  233.     printf("\n************ ADC Converter Value ************\n");

  234.     while (1)
  235.     {
  236.         if (adflag == 1)
  237.         {
  238.             /***打开AD开始转换***/
  239.             ADCCON = ADCCON & (~(0x1 << 0)) | (0x1 << 0);
  240.             delay_ms(10);

  241.             /***等待转换完成***/
  242.             while (!(ADCCON & (1 << 15)))
  243.                 ;

  244.             /***读取转换结果***/
  245.             temp_adc = ADCDAT & 0xFFF;

  246.             /***将读出来的数据进行格式转换 ***/
  247.             /*(精度是12位,所以是4096,单位mV,提高准确性)*/
  248.             temp_mv = 1800 * temp_adc / 4096;

  249.             printf("adc value: %d mv\n", temp_mv);
  250.             delay_ms(1000);
  251.         }
  252.     }
  253. }





  254. /********UART*************/
  255. void mydelay_ms(int time) {
  256.     int i, j;
  257.     while (time--) {
  258.         for (i = 0; i < 5; i++)
  259.             for (j = 0; j < 514; j++)
  260.                 ;
  261.     }
  262. }

  263. void uart_init(void) {

  264.     /* 设置GPA1_0和GPA1_1引脚为uart的输入和输出功能 */
  265.     GPA1.GPA1CON = (GPA1.GPA1CON & ~0xFF) | (0x22); //GPA1_0:RX;GPA1_1:TX

  266.     /* 设置传输模式:8N1 */
  267.     UART2.ULCON2 = 0x3; //Normal mode, No parity,One stop bit,8 data bits
  268.     UART2.UCON2 = 0x5; //Interrupt request or polling mode


  269.     /*
  270.      * 设置波特率
  271.      * Baud-rate 115200: src_clock:100Mhz
  272.      * DIV_VAL = (100*10^6 / (115200*16) -1) = (54.3 - 1) = 53.3
  273.      * UBRDIV2 = (Integer part of 53.3) = 53 = 0x35
  274.      * UFRACVAL2 = 0.3*16 = 0x5
  275.      * */
  276.     UART2.UBRDIV2 = 53;
  277.     UART2.UFRACVAL2 = 5;
  278. }

  279. void putc(const char data) {
  280.     while (!(UART2.UTRSTAT2 & (0x1<<1))) /* 等待发送缓冲区为空再将数据放入发送缓冲区中 */
  281.         ;
  282.     UART2.UTXH2 = data;
  283.     if (data == '\n')
  284.         putc('\r');
  285. }

  286. void puts(const char *pstr) {
  287.     while (*pstr != '\0')
  288.         putc(*pstr++);
  289. }

  290. unsigned char getchar() {
  291.     unsigned char c;
  292.     while (!(UART2.UTRSTAT2 & (0X1<<0))) /* 等待接收缓冲区不为空(即有数据)然后在读数据 */
  293.         ;
  294.     c = UART2.URXH2;
  295.     return c;
  296. }

  297. int main(void) {

  298.     uart_init();
  299.     mydelay_ms(3000);

  300.     puts("UART0 Test\n");
  301.     printf("Please input one strings\n");
  302.     while (1) {
  303.         putc(getchar());
  304.     }
  305.     return 0;
  306. }


阅读(2779) | 评论(0) | 转发(1) |
0

上一篇:Cortex_A9----RTC

下一篇:Cortex_A9----I2C

给主人留下些什么吧!~~