1 CPU与硬件的交互方式
轮询
CPU执行程序时不断地询问硬件是否需要其服务,若需要则给予其服务,若不需要一段时间后再次询问,周而复始
中断
CPU执行程序时若硬件需要其服务,对应的硬件给CPU发送中断信号,CPU接收到中断信号后将当前的程序暂停下来,转而去执行中断服务程序,执行完成后再返回到被打断的点继续执行
DMA
硬件产生数据后,硬件控制器可将产生的数据直接写入到存储器中,整个过程无需CPU的参与
2 轮询方式实现按键实验
2.1 查看原理图
2.2 轮询方式寄存器分析
GPX1CON控制寄存器
2.3 轮询代码
#include "exynos_4412.h"
int main()
{
/*将GPX1_1设置成输入功能*/
GPX1.CON = GPX1.CON & (~(0xF << 4));
while(1)
{
/*判断GPX1_1引脚的状态,即判断按键是否按下*/
if(!(GPX1.DAT & (1 << 1)))
{
printf("Key2 Pressed\n");
/*等待松手*/
while(!(GPX1.DAT & (1 << 1)));
}
else
{
}
}
return 0;
}
练习
使用轮询的方式检测Key3按键的状态,实现按一次按键,LED2点亮,再次按下,LED2熄灭
查看原理图
查看芯片手册
led的略
#include "exynos_4412.h"
void Led_on(int num)
{
switch(num)
{
case 2:
GPX2.DAT = GPX2.DAT | (1 << 7);
case 3:
GPX1.DAT = GPX1.DAT | (1 << 0);
case 4:
GPF3.DAT = GPF3.DAT | (1 << 4);
case 5:
GPF3.DAT = GPF3.DAT | (1 << 5);
default:
break;
}
}
void Led_off(int num)
{
switch(num)
{
case 2:
GPX2.DAT = GPX2.DAT & ~(1 << 7);
case 3:
GPX1.DAT = GPX1.DAT & ~(1 << 0);
case 4:
GPF3.DAT = GPF3.DAT & ~(1 << 4);
case 5:
GPF3.DAT = GPF3.DAT & ~(1 << 5);
default:
break;
}
}
void Led_init(void)
{
GPX2.CON = GPX2.CON & (~(0xF << 28)) | (0x1 << 28); //LED2 GPX2_7 output
//GPX1.CON = GPX1.CON & (~0xF) | 0x1; //LED3 GPX1_0 output
//GPF3.CON = GPF3.CON & (~(0xF << 16)) | (0x1 << 16); //LED4 GPF3_4 output
//GPF3.CON = GPF3.CON & (~(0xF << 20)) | (0x1 << 20); //LED5 GPF3_5 output
Led_off(2);
}
void Key_init(void)
{
//GPIO X1_2 input
GPX1.CON = GPX1.CON & (~(0xf << 8));
}
int main()
{
int toggle = 0;
Key_init();
Led_init();
printf("start\n");
for(;;)
{
if(!(GPX1.DAT & ( 1 << 2)))
{
//等待松手
while(!(GPX1.DAT & (1 << 2)));
printf("key press\n");
if(toggle == 0)
{
Led_on(2);
toggle = 1;
}
else
{
Led_off(2);
toggle = 0;
}
}
}
return 0;
}