一、背景
看门狗的作用在于监控 CPU 的运行,保证在诸如噪音和系统错误等这样的故障干扰情况下能尽快恢复正常工作。看门狗与 PWM 定时器都能实现定时的功能,两者的区别在于看门狗能发出复位信号而 PWM 定时器不能,后面将会有具体的章节讲解看门狗的定时和复位功能,这里我们只是简单的将其关闭。
二、相关寄存器
查阅数据手册,关闭看门狗的复位功能只需要将WTCON的bit[0]置0即可
三、程序
1、start.S
/*
* 代码:关看门狗并且让LED灯闪烁
* 日期:2020.7.10
* 作者:glass love
*
*/
.globl _start
_start:
/**************关看门狗***********************/
//通过查阅数据手册知道控制看门狗开关的寄存器是:
//Watchdog Timer Control Register (WTCON, R/W, Address = )
//WTCON寄存器的bit[0]位是启用或禁用复位信号的看门狗定时器输出位
//1为启用,0为禁止
//因此只需要往WTCON中写入0x0即可
ldr r0, =0x0
ldr r1, =0xE2700000
str r0, [r1]
/***************使LED闪烁***********************/
//首先通过查阅原理图,得到控制4颗LED灯的引脚
//GPJ2_(0~3)对应LED(1~4)
//通过查阅数据手册与用户手册得到
//与控制LED有关的寄存器为GPJ2CON、GPJ2DAT
//GPJ2CON的地址为0xE020_0280、0xE020_0280的地址为0xE020_0284
//需要将GPJ2CON的bit(0~15)设置为0x1111
//如果要LED亮需要将GPJ2DAT的bit(0~3)设置为0x0
//如果要LED灭需要将GPJ2DAT的bit(0~3)设置为0xf
//设置GPJ2CON的bit(0~15),配置GPJ2_0/1/2/3引脚为输出模式
ldr r0, =0x00001111
ldr r1, =0xE0200280
str r0, [r1]
//此处赋给r2一个随机数0x1000,目的是为后面的循环是设定一个时间
mov r2, #0x10000
led_blink:
//LED亮
ldr r0, =0x00000000
//mov r0, #0
ldr r1, =0xE0200284
str r0, [r1]
//延时
ldr r0, =0x100000
bl delay
//LED灭
ldr r0, =0x0000000f
//mov r0, #0xf
ldr r1, =0xE0200284
str r0, [r1]
//延时
ldr r0, =0x100000
bl delay
//下面为循环函数
sub r2, r2, #1
cmp r2, #0
bne led_blink
//此时mov r2, #0x1000和后面的循环函数
//两者中间为循环体一般仿佛声明了
//在汇编函数结尾需要一个死循环
halt:
b halt
//此处的延时函数把它注释掉,因为要通过调用c函数来
//验证栈是否被初始化
#if 0
delay:
mov r0, #0x1000000
delay_loop:
cmp r0, #0
sub r0, r0, #1
bne delay_loop
//调用完函数需要返回,所以mov pc, lr起到返回作用
mov pc, lr
#endif
2、delay.c
由于汇编中调用 C 函数时,参数的传递、现场的保存和恢复、临时变量的保存等都需要使用到栈,在 delay()函数中变量 count 就是临时变量。如果,程序运行成功说明栈已经设置好了;如果程序运行不成功,则栈未被设置。
void delay(int r0)
{
volatile int count=r0;
while(count--);
}
3、Makefile
4、mkv210_image.c
5、write2sd
后面三部分代码和脚本较"(1)汇编点亮LED"中均为发生改变,请参照"(1)汇编点亮LED".