一、看门狗
1、为什么要有看门狗:由于单片机的工作会受到外界的干扰,可能造成程序进入死循环或者程序跑飞,程序的正常运行被打断,单片机控制的系统无法继续工作,会造成整个系统的陷入停滞状态。为了防止进入这个情况便产生了一种专门用于实时监测单片机程序运行状态的模块或者芯片,俗称“看门狗”。
2、什么是看门狗:看门狗(WDT)是一个定时器,开启看门狗定时器之后(比如定时100ms),在单片机程序中每隔一段时间(小于100ms)就要"喂狗"一次,即将看门狗定时器清零。这样做的用处是,一旦单片机程序跑飞,没有在定时的时间之内去喂狗,那么定时达到200ms时,看门狗自动将单片机复位。
3、S3C2440开发板中如何去失能看门狗
在该开发板中,每个寄存器占4个字节(32位)。由下图可以看出,最低位[0]为0时失能。
#define WTCON (*((unsigned int*)(0x53000000)))
void init_wdt(void)
{
WTCON &= ~(1 << 0); //按位与:指定位清零
}
二、按位运算时的与、或和异或作用
按位&:指定位清0,例如:将i的第5位清0:i &= ~(1<<5)
按位|:指定位置1,例如:将i的第5位置1:i |= (1<<5)
按位^:指定位翻转,例如:将i的第5位翻转:i ^= (1<<5)
三、上拉电阻和下拉电阻
1、是什么? 上拉、下拉电阻统一称为拉电阻,作用是将状态不确定的信号线通过一个电阻将其箝位至高电平(上拉)或低电平(下拉)。状态不确定的信号是指既不是高电平,也不是低电平。
举个例子:
上图是一个经典的按键电路,每一个按键都接了一个上拉电阻,为什么?因为初始上电时,IO口电平是随机的,IO口可能是高电平,也可能是低电平,这样就会产生干扰导致检测误差,所以我们接上一个上拉电阻,初始态即可稳定成高电平。
2、如何辨别拉电阻:
上拉电阻与电源串联,下拉电阻与地串联。
三、LED点灯实验
S3C2440A包含了130个GPIO并且它们规定为如下图所示的八个端口:
1、原理图
四个led对应的引脚分别为:GPB5、GPB6、GPB7、GPB8。
2、寄存器
相应的寄存器有下面三个,分别为GPBCON、GPBDAT、GPBUP。
(1)端口配置寄存器(GPBCON): 决定了每个引脚使用哪项功能,点灯配置为01输出。
(2)端口数据寄存器(GPBDAT): 如果设置为输出,则可以写数据到相应位;如果设置为输入,从里面读取,点灯将GPB[5]写入0,二极管导通。
(3)端口上拉寄存器(GPBUP): 相应位为0时使能上拉电阻,1时禁止。
四、按键实验
1、原理图
可以看到一共有6个key,每个按键对应管脚如右下角所示,为GPG组引脚。
2、寄存器
控制KEY为GPG组引脚,相应的寄存器有下面三个,分别为GPGCON,GPGDAT,GPGUP。
(1)端口配置寄存器(GPGCON): 决定了每个引脚使用哪项功能,按键配置为00输入,由下到上分别是key1到key6。
(2)端口数据寄存器(GPGDAT): 如果设置为输出,则可以写数据到相应位;如果设置为输入,从里面读取,按键初始化将GPG置为1表示为未按下。
(3)端口上拉寄存器(GPGUP): 相应位为0时使能上拉电阻,1时禁止。K1和K6两个按键外接有上拉电阻,所以将这两个失能,可以降低功耗。
附录
1、点灯代码
//led.h
#ifndef __LED_H__
#define __LED_H__
extern void init_led(void);
extern void ledOn(unsigned int n);
extern void ledAllOn(void);
extern void ledOff(unsigned int n);
extern void ledAllOff(void);
extern void ledAllNor(void);
#endif
//led.c
#include <s3c2440.h>
#include "led.h"
void init_led(void)
{
GPBCON &= ~(0xff << 10); //清零
GPBCON |= (0x55 << 10); //01=输出
ledAllOff();
}
void ledOn(unsigned int n)
{
if (n < 1 || n > 4)
{
return;
}
GPBDAT &= ~(1 << (n+4));
}
void ledAllOn(void)
{
GPBDAT &= ~(0x0f << 5);
}
void ledOff(unsigned int n)
{
if (n < 1 || n > 4)
{
return;
}
GPBDAT |= (1 << (n+4));
}
void ledAllOff(void)
{
GPBDAT |= (0x0f << 5);
}
void ledAllNor(void)
{
GPBDAT ^= (0x0f << 5);
}
2、按键代码
//key.h
#ifndef __KEY_H__
#define __KEY_H__
extern void init_key(void);
extern int key_pressed(void);
#endif
//key.c
#include <s3c2440.h>
#include "key.h"
void init_key(void)
{
GPGCON &= ~((3<<0)|(3<<6)|(3<<10)|(3<<12)|(3<<14)|(3<<22)); // 设置6个键为输入
GPGDAT |= (1<<0)|(1<<3)|(1<<5)|(1<<6)|(1<<7)|(1<<11); //将按键初始化为高电平
GPGUP |= (1<<0) | (1<<11); //失能有外部上拉电阻的
GPGUP &= (1<<3)|(1<<5)|(1<<6)|(1<<7); //使能无外部上拉电阻的
}
int key_pressed(void)
{
if((GPGDAT & (1 << 0)) == 0)
{
return 1;
}
else if(GPGDAT & (1 << 3) == 0)
{
return 2;
}
else if(GPGDAT & (1 << 5) == 0)
{
return 3;
}
else if(GPGDAT & (1 << 6) == 0)
{
return 4;
}
else if(GPGDAT & (1 << 7) == 0)
{
return 5;
}else if(GPGDAT & (1 << 11) == 0)
{
return 6;
}
return 0;
}